You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by gi...@apache.org on 2023/01/25 04:22:25 UTC

[groovy-dev-site] branch asf-site updated: 2023/01/25 04:22:21: Generated dev website from groovy-website@cb35d8c

This is an automated email from the ASF dual-hosted git repository.

git-site-role pushed a commit to branch asf-site
in repository https://gitbox.apache.org/repos/asf/groovy-dev-site.git


The following commit(s) were added to refs/heads/asf-site by this push:
     new 4c64149  2023/01/25 04:22:21: Generated dev website from groovy-website@cb35d8c
4c64149 is described below

commit 4c6414998d6b9a5f0bf18cfce9d84ff20478478c
Author: jenkins <bu...@apache.org>
AuthorDate: Wed Jan 25 04:22:21 2023 +0000

    2023/01/25 04:22:21: Generated dev website from groovy-website@cb35d8c
---
 blog/fun-with-rating-stars.html               | 265 +++++++++
 img/confs/acah2021.png                        | Bin 0 -> 11557 bytes
 img/confs/acna2022.png                        | Bin 0 -> 23078 bytes
 img/confs/devdotnext.png                      | Bin 0 -> 62514 bytes
 img/confs/gr8conf-jdkio.svg                   | 795 ++++++++++++++++++++++++++
 img/courses/groovy-course-beginner.png        | Bin 0 -> 32394 bytes
 img/courses/groovy-course-fundamentals.png    | Bin 0 -> 56959 bytes
 img/courses/groovy-course-mastering.png       | Bin 0 -> 87866 bytes
 img/courses/groovy-course-metaprogramming.png | Bin 0 -> 29118 bytes
 img/courses/groovy-course-practical.png       | Bin 0 -> 77125 bytes
 img/ecosystem/infrastructor.png               | Bin 0 -> 9879 bytes
 wiki/GEP-14.html                              | 379 ++++++++++++
 12 files changed, 1439 insertions(+)

diff --git a/blog/fun-with-rating-stars.html b/blog/fun-with-rating-stars.html
new file mode 100644
index 0000000..9bc9499
--- /dev/null
+++ b/blog/fun-with-rating-stars.html
@@ -0,0 +1,265 @@
+<!DOCTYPE html>
+<!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
+<!--[if IE 7]>         <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
+<!--[if IE 8]>         <html class="no-js lt-ie9"> <![endif]-->
+<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]--><head>
+    <meta charset='utf-8'/><meta http-equiv='X-UA-Compatible' content='IE=edge'/><meta name='viewport' content='width=device-width, initial-scale=1'/><title>The Apache Groovy programming language - Developer docs - Fun with rating stars</title><link href='../img/favicon.ico' type='image/x-ico' rel='icon'/><link rel='stylesheet' type='text/css' href='../css/bootstrap.css'/><link rel='stylesheet' type='text/css' href='../css/font-awesome.min.css'/><link rel='stylesheet' type='text/css' hre [...]
+</head><body>
+    <div id='fork-me'>
+        <a href='https://github.com/apache/groovy'>
+            <img style='position: fixed; top: 20px; right: -58px; border: 0; z-index: 100; transform: rotate(45deg);' src='/img/horizontal-github-ribbon.png'/>
+        </a>
+    </div><div id='st-container' class='st-container st-effect-9'>
+        <nav class='st-menu st-effect-9' id='menu-12'>
+            <h2 class='icon icon-lab'>Socialize</h2><ul>
+                <li>
+                    <a href='http://groovy-lang.org/mailing-lists.html' class='icon'><span class='fa fa-envelope'></span> Discuss on the mailing-list</a>
+                </li><li>
+                    <a href='https://twitter.com/ApacheGroovy' class='icon'><span class='fa fa-twitter'></span> Groovy on Twitter</a>
+                </li><li>
+                    <a href='http://groovy-lang.org/events.html' class='icon'><span class='fa fa-calendar'></span> Events and conferences</a>
+                </li><li>
+                    <a href='https://github.com/apache/groovy' class='icon'><span class='fa fa-github'></span> Source code on GitHub</a>
+                </li><li>
+                    <a href='http://groovy-lang.org/reporting-issues.html' class='icon'><span class='fa fa-bug'></span> Report issues in Jira</a>
+                </li><li>
+                    <a href='http://stackoverflow.com/questions/tagged/groovy' class='icon'><span class='fa fa-stack-overflow'></span> Stack Overflow questions</a>
+                </li><li>
+                    <a href='http://groovycommunity.com/' class='icon'><span class='fa fa-slack'></span> Slack Community</a>
+                </li>
+            </ul>
+        </nav><div class='st-pusher'>
+            <div class='st-content'>
+                <div class='st-content-inner'>
+                    <!--[if lt IE 7]>
+                    <p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
+                <![endif]--><div><div class='navbar navbar-default navbar-static-top' role='navigation'>
+                            <div class='container'>
+                                <div class='navbar-header'>
+                                    <button type='button' class='navbar-toggle' data-toggle='collapse' data-target='.navbar-collapse'>
+                                        <span class='sr-only'></span><span class='icon-bar'></span><span class='icon-bar'></span><span class='icon-bar'></span>
+                                    </button><a class='navbar-brand' href='../index.html'>
+                                        <i class='fa fa-star'></i> Apache Groovy
+                                    </a>
+                                </div><div class='navbar-collapse collapse'>
+                                    <ul class='nav navbar-nav navbar-right'>
+                                        <li class=''><a href='http://groovy-lang.org/learn.html'>Learn</a></li><li class=''><a href='http://groovy-lang.org/documentation.html'>Documentation</a></li><li class=''><a href='/download.html'>Download</a></li><li class=''><a href='http://groovy-lang.org/support.html'>Support</a></li><li class=''><a href='/'>Contribute</a></li><li class=''><a href='http://groovy-lang.org/ecosystem.html'>Ecosystem</a></li><li class=''><a href='https://groovy.apac [...]
+                                            <a data-effect='st-effect-9' class='st-trigger' href='#'>Socialize</a>
+                                        </li><li class=''>
+                                            <a href='../search.html'>
+                                                <i class='fa fa-search'></i>
+                                            </a>
+                                        </li>
+                                    </ul>
+                                </div>
+                            </div>
+                        </div><div id='content' class='page-1'><div class='row'><div class='row-fluid'><div class='col-lg-3'><ul class='nav-sidebar'><li class='active'><a href='#doc'>Fun with rating stars</a></li><li><a href='#_star_ratings' class='anchor-link'>Star Ratings</a></li><li><a href='#_increasing_robustness' class='anchor-link'>Increasing Robustness</a></li><li><a href='#_references' class='anchor-link'>References</a></li><li><a href='#_update_history' class='anchor-link'>Upda [...]
+<h2 id="_star_ratings">Star Ratings</h2>
+<div class="sectionbody">
+<div class="paragraph">
+<p>A recent tweet showed some C# code for producing a String of stars that might
+be used when displaying ratings on a website:</p>
+</div>
+<div class="paragraph">
+<p><span class="image"><img src="img/star_ratings_csharp.png" alt="image"></span></p>
+</div>
+<div class="paragraph">
+<p>Let&#8217;s have a look at several ways to do the same thing in Groovy.</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="prettyprint highlight"><code>def rating0(percentage) {
+    int stars = Math.ceil(percentage * 10)
+    ("⬤" * stars).padRight(10, "○")
+}</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="prettyprint highlight"><code>def rating1(percentage) {
+    int stars = Math.ceil(percentage * 10)
+    "⬤" * stars + "○" * (10-stars)
+}</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="prettyprint highlight"><code>def rating2(percentage) {
+    int skip = 10 - Math.ceil(percentage * 10)
+    "⬤⬤⬤⬤⬤⬤⬤⬤⬤⬤○○○○○○○○○○"[skip..&lt;10+skip]
+}</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="prettyprint highlight"><code>def rating3(percentage) {
+    switch(percentage) {
+        case 0 -&gt; "○○○○○○○○○○"
+        case { it &lt;= 0.1 } -&gt; "⬤○○○○○○○○○"
+        case { it &lt;= 0.2 } -&gt; "⬤⬤○○○○○○○○"
+        case { it &lt;= 0.3 } -&gt; "⬤⬤⬤○○○○○○○"
+        case { it &lt;= 0.4 } -&gt; "⬤⬤⬤⬤○○○○○○"
+        case { it &lt;= 0.5 } -&gt; "⬤⬤⬤⬤⬤○○○○○"
+        case { it &lt;= 0.6 } -&gt; "⬤⬤⬤⬤⬤⬤○○○○"
+        case { it &lt;= 0.7 } -&gt; "⬤⬤⬤⬤⬤⬤⬤○○○"
+        case { it &lt;= 0.8 } -&gt; "⬤⬤⬤⬤⬤⬤⬤⬤○○"
+        case { it &lt;= 0.9 } -&gt; "⬤⬤⬤⬤⬤⬤⬤⬤⬤○"
+        default -&gt; "⬤⬤⬤⬤⬤⬤⬤⬤⬤⬤"
+    }
+}</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>If you want you can test the various edge cases:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="prettyprint highlight"><code>for (i in 0..3)
+    for (j in [0, 0.09, 0.1, 0.11, 0.9, 1])
+        println "rating$i"(j)</code></pre>
+</div>
+</div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_increasing_robustness">Increasing Robustness</h2>
+<div class="sectionbody">
+<div class="paragraph">
+<p>The code examples here assume that the input is in the range <code>0 &lt;= percentage &lt;= 1</code>. There are several tweaks we could do to guard against inputs outside those ranges.</p>
+</div>
+<div class="paragraph">
+<p>We could simply add an assert, e.g.:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="prettyprint highlight"><code>def rating4(percentage) {
+    assert percentage &gt;= 0 &amp;&amp; percentage &lt;= 1
+    int stars = Math.ceil(percentage * 10)
+    ("⬤" * stars).padRight(10, "○")
+}</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>Or, if we wanted to not fail, tweak some of our conditions, e.g.
+for <code>rating3</code>, instead of <code>case 0</code>, we could use <code>case { it &#8656; 0 }</code>.</p>
+</div>
+<div class="paragraph">
+<p>We could push the checks into our types by making a special class, <code>Percent</code> say, which only permitted the allowed values:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="prettyprint highlight"><code>final class Percent {
+    final Double value
+    Percent(Double value) {
+        assert value &gt;= 0 &amp;&amp; value &lt;= 1
+        this.value = value
+    }
+}</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>And we could optionally also use some metaprogramming to provide a custom <code>isCase</code> method:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="prettyprint highlight"><code>Double.metaClass.isCase = { Percent p -&gt; delegate &gt;= p.value }</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>Which means we could tweak the rating method to be:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="prettyprint highlight"><code>def rating5(Percent p) {
+    switch(p) {
+        case 0.0d -&gt; "○○○○○○○○○○"
+        case 0.1d -&gt; "⬤○○○○○○○○○"
+        case 0.2d -&gt; "⬤⬤○○○○○○○○"
+        case 0.3d -&gt; "⬤⬤⬤○○○○○○○"
+        case 0.4d -&gt; "⬤⬤⬤⬤○○○○○○"
+        case 0.5d -&gt; "⬤⬤⬤⬤⬤○○○○○"
+        case 0.6d -&gt; "⬤⬤⬤⬤⬤⬤○○○○"
+        case 0.7d -&gt; "⬤⬤⬤⬤⬤⬤⬤○○○"
+        case 0.8d -&gt; "⬤⬤⬤⬤⬤⬤⬤⬤○○"
+        case 0.9d -&gt; "⬤⬤⬤⬤⬤⬤⬤⬤⬤○"
+        default   -&gt; "⬤⬤⬤⬤⬤⬤⬤⬤⬤⬤"
+    }
+}</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>We can be fancier here using <code>@EqualsAndHashCode</code> on the <code>Percent</code> class and/or using <code>@Delegate</code> on the <code>value</code> property, depending on how rich in
+functionality we wanted the <code>Percent</code> instances to be.</p>
+</div>
+<div class="paragraph">
+<p>Alternatively, we could use a design-by-contract approach:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="prettyprint highlight"><code>@Requires({ percentage &gt;= 0 &amp;&amp; percentage &lt;= 1 })
+def rating6(percentage) {
+    int stars = Math.ceil(percentage * 10)
+    ("⬤" * stars).padRight(10, "○")
+}</code></pre>
+</div>
+</div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_references">References</h2>
+<div class="sectionbody">
+<div class="paragraph">
+<p><a href="https://twitter.com/JeroenFrijters/status/1615204074588180481">Original tweet</a></p>
+</div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_update_history">Update history</h2>
+<div class="sectionbody">
+<div class="dlist">
+<dl>
+<dt class="hdlist1">1.0 (2023-01-25)</dt>
+<dd>
+<p>Initial version</p>
+</dd>
+</dl>
+</div>
+</div>
+</div></div></div></div></div><footer id='footer'>
+                            <div class='row'>
+                                <div class='colset-3-footer'>
+                                    <div class='col-1'>
+                                        <h1>Groovy</h1><ul>
+                                            <li><a href='http://groovy-lang.org/learn.html'>Learn</a></li><li><a href='http://groovy-lang.org/documentation.html'>Documentation</a></li><li><a href='/download.html'>Download</a></li><li><a href='http://groovy-lang.org/support.html'>Support</a></li><li><a href='/'>Contribute</a></li><li><a href='http://groovy-lang.org/ecosystem.html'>Ecosystem</a></li><li><a href='https://groovy.apache.org/events.html'></a></li>
+                                        </ul>
+                                    </div><div class='col-2'>
+                                        <h1>About</h1><ul>
+                                            <li><a href='https://github.com/apache/groovy'>Source code</a></li><li><a href='http://groovy-lang.org/security.html'>Security</a></li><li><a href='http://groovy-lang.org/learn.html#books'>Books</a></li><li><a href='http://groovy-lang.org/thanks.html'>Thanks</a></li><li><a href='http://www.apache.org/foundation/sponsorship.html'>Sponsorship</a></li><li><a href='http://groovy-lang.org/faq.html'>FAQ</a></li><li><a href='http://groovy-lang.org/sea [...]
+                                        </ul>
+                                    </div><div class='col-3'>
+                                        <h1>Socialize</h1><ul>
+                                            <li><a href='http://groovy-lang.org/mailing-lists.html'>Discuss on the mailing-list</a></li><li><a href='https://twitter.com/ApacheGroovy'>Groovy on Twitter</a></li><li><a href='http://groovy-lang.org/events.html'>Events and conferences</a></li><li><a href='https://github.com/apache/groovy'>Source code on GitHub</a></li><li><a href='http://groovy-lang.org/reporting-issues.html'>Report issues in Jira</a></li><li><a href='http://stackoverflow.com [...]
+                                        </ul>
+                                    </div><div class='col-right'>
+                                        <p>
+                                            The Groovy programming language is supported by the <a href='http://www.apache.org'>Apache Software Foundation</a> and the Groovy community.
+                                        </p><div text-align='right'>
+                                            <img src='../img/asf_logo.png' title='The Apache Software Foundation' alt='The Apache Software Foundation' style='width:60%'/>
+                                        </div><p>Apache&reg; and the Apache feather logo are either registered trademarks or trademarks of The Apache Software Foundation.</p>
+                                    </div>
+                                </div><div class='clearfix'>&copy; 2003-2023 the Apache Groovy project &mdash; Groovy is Open Source: <a href='http://www.apache.org/licenses/LICENSE-2.0.html' alt='Apache 2 License'>license</a>, <a href='https://privacy.apache.org/policies/privacy-policy-public.html'>privacy policy</a>.</div>
+                            </div>
+                        </footer></div>
+                </div>
+            </div>
+        </div>
+    </div><script src='../js/vendor/jquery-1.10.2.min.js' defer></script><script src='../js/vendor/classie.js' defer></script><script src='../js/vendor/bootstrap.js' defer></script><script src='../js/vendor/sidebarEffects.js' defer></script><script src='../js/vendor/modernizr-2.6.2.min.js' defer></script><script src='../js/plugins.js' defer></script><script src='https://cdnjs.cloudflare.com/ajax/libs/prettify/r298/prettify.min.js'></script><script>document.addEventListener('DOMContentLoa [...]
+          (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+          (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+          m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+          })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
+
+          ga('create', 'UA-257558-10', 'auto');
+          ga('send', 'pageview');
+    </script>
+</body></html>
\ No newline at end of file
diff --git a/img/confs/acah2021.png b/img/confs/acah2021.png
new file mode 100644
index 0000000..f605342
Binary files /dev/null and b/img/confs/acah2021.png differ
diff --git a/img/confs/acna2022.png b/img/confs/acna2022.png
new file mode 100644
index 0000000..aa40130
Binary files /dev/null and b/img/confs/acna2022.png differ
diff --git a/img/confs/devdotnext.png b/img/confs/devdotnext.png
new file mode 100644
index 0000000..f7156eb
Binary files /dev/null and b/img/confs/devdotnext.png differ
diff --git a/img/confs/gr8conf-jdkio.svg b/img/confs/gr8conf-jdkio.svg
new file mode 100644
index 0000000..c8aaa0e
--- /dev/null
+++ b/img/confs/gr8conf-jdkio.svg
@@ -0,0 +1,795 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="279"
+   height="180"
+   viewBox="0 0 73.818748 47.625001"
+   version="1.1"
+   id="svg8"
+   sodipodi:docname="gr8conf-jdkio.svg"
+   inkscape:version="0.92.4 (5da689c313, 2019-01-14)">
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="640"
+     inkscape:window-height="480"
+     id="namedview170"
+     showgrid="false"
+     inkscape:pagecheckerboard="true"
+     borderlayer="true"
+     inkscape:zoom="2.8284271"
+     inkscape:cx="68.012653"
+     inkscape:cy="90.136006"
+     inkscape:current-layer="svg8" />
+  <defs
+     id="defs2">
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath18">
+      <path
+         d="m 450.395,454.342 -9.299,-19.067 19.067,-9.3 9.299,19.068 z"
+         id="path16" />
+    </clipPath>
+    <mask
+       maskUnits="userSpaceOnUse"
+       x="0"
+       y="0"
+       width="1"
+       height="1"
+       id="mask24">
+      <image
+         width="1"
+         height="1"
+         style="image-rendering:optimizeSpeed"
+         preserveAspectRatio="none"
+         xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAH4AAAB+CAAAAADHSPpUAAAAAXNCSVQI5gpbmQAAA4dJREFUaIHt279PFEEUB/C5IwdEKYxRQwJEGguwgEBCaQMFicZEYgf/gMX9A/ZQeR0J/gFQw6kxJnaWBshRiASbM2AiKsYQNNwReBYYdd+82fn1XnaTu9fB7H4/M7uzd3t3O0r5VWGmuvNilmqZfb5TnSl4xvnVxOIRAADM6U1zAABwtDghZU8fwt9axY2r/9oOp/ntwhYkqi/Z3Jds3WI+CeuAainZvoTb1xnxZRwOUE9uUde3WGbCO8/0bAcezjrt2UXrFuWGfRs6ulEO2/H/WiPG5TZ6AFiL1TfoXEceNizxlgO7NxbTd6XG9mL4Wn+crlR/LZyvjMTqSo1UQvecNJxQj3MPADAZppdSIn14KJmNlIP/M6zXXkFmfj6l0 [...]
+         id="image26" />
+    </mask>
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath36">
+      <path
+         d="M 0,595.28 H 841.89 V 0 H 0 Z"
+         id="path34" />
+    </clipPath>
+    <clipPath
+       id="clipPath53"
+       clipPathUnits="userSpaceOnUse">
+      <path
+         id="path51"
+         d="M 10.701,328 C 5.318,328 0.819,324.021 0,318.859 v 0 V 43.141 C 0.819,37.979 5.318,34 10.701,34 v 0 h 336.04 c 5.959,0 10.835,4.876 10.835,10.834 v 0 272.331 c 0,5.959 -4.876,10.835 -10.835,10.835 v 0 z" />
+    </clipPath>
+    <clipPath
+       id="clipPath65"
+       clipPathUnits="userSpaceOnUse">
+      <path
+         id="path63"
+         d="m 10.701,328 c -4.038,0 -7.578,-2.239 -9.441,-5.536 v 0 C 0.456,320.976 0,319.273 0,317.463 v 0 -272.927 c 0,-1.812 0.458,-3.518 1.264,-5.008 v 0 C 3.128,36.235 6.666,34 10.701,34 v 0 H 344.463 C 350.283,34 355,38.717 355,44.536 v 0 272.927 c 0,5.82 -4.717,10.537 -10.537,10.537 v 0 z" />
+    </clipPath>
+    <linearGradient
+       id="linearGradient75"
+       spreadMethod="pad"
+       gradientTransform="matrix(355,0,0,-355,0,181)"
+       gradientUnits="userSpaceOnUse"
+       y2="0"
+       x2="1"
+       y1="0"
+       x1="0">
+      <stop
+         id="stop71"
+         offset="0"
+         style="stop-opacity:1;stop-color:#f15e22" />
+      <stop
+         id="stop73"
+         offset="1"
+         style="stop-opacity:1;stop-color:#f99e39" />
+    </linearGradient>
+    <clipPath
+       id="clipPath85"
+       clipPathUnits="userSpaceOnUse">
+      <path
+         id="path83"
+         d="M 10.701,328 C 5.318,328 0.819,324.021 0,318.859 v 0 V 43.141 C 0.819,37.979 5.318,34 10.701,34 v 0 h 336.04 c 5.959,0 10.835,4.876 10.835,10.834 v 0 272.331 c 0,5.959 -4.876,10.835 -10.835,10.835 v 0 z" />
+    </clipPath>
+    <clipPath
+       id="clipPath93"
+       clipPathUnits="userSpaceOnUse">
+      <path
+         id="path91"
+         d="M -13,191 H 299 V 23 H -13 Z" />
+    </clipPath>
+    <clipPath
+       id="clipPath97"
+       clipPathUnits="userSpaceOnUse">
+      <path
+         id="path95"
+         d="M -13,191 H 299 V 23 H -13 Z" />
+    </clipPath>
+    <mask
+       id="mask99"
+       height="1"
+       width="1"
+       y="0"
+       x="0"
+       maskUnits="userSpaceOnUse">
+      <g
+         id="g109">
+        <g
+           id="g107"
+           clip-path="url(#clipPath97)">
+          <g
+             id="g105">
+            <g
+               id="g103"
+               transform="matrix(312,0,0,168,-13,23)">
+              <image
+                 id="image101"
+                 xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAATgAAACoCAYAAAB0bvKdAAAABHNCSVQICAgIfAhkiAAAFQNJREFUeJztne2WmzASRGXPPvg+eGZmf2SV9HSqPyQEEqLuOT4IgQ3YcF0tnMyrlPJdCCFkQ96zd4AQQs6CgiOEbAsFRwjZFgqOELItFBwhZFsoOELItlBwhJBtoeAIIdtCwRFCtoWCI4RsCwVHCNkWCo4Qsi0UHCFkWyg4Qsi2UHCEkG2h4Agh20LBEUK2hYIjhGwLBUcI2RYKjhCyLRQcIWRbKDhCyLZQcISQbaHgCCHbQsERQrblP7N3YGVer9fsXYB8f3/P3gVCbsGrlPLoq6VVYjOkd0RolCF5Mo9KcJGcMvJaNdVVtNCi/aUAyc5sneCsi7u1P1p2JZGQMsIatQ4hq7Od4JCIdF/POisIzpLOqP5oW [...]
+                 transform="matrix(1,0,0,-1,0,1)"
+                 preserveAspectRatio="none"
+                 style="image-rendering:optimizeSpeed"
+                 height="1"
+                 width="1" />
+            </g>
+          </g>
+        </g>
+      </g>
+    </mask>
+    <mask
+       id="mask111"
+       height="1"
+       width="1"
+       y="0"
+       x="0"
+       maskUnits="userSpaceOnUse">
+      <image
+         id="image113"
+         xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAATgAAACoCAAAAABRBa1BAAAAAXNCSVQI5gpbmQAADQ5JREFUeJztne22q6wOhRP3uf8rPiXvD0gyA4jYWusag3Rtq7ZVfDrzAVU30bJly5YtW7Zs2bJly5YtW7Zs2bJly5YtW7Zs2bJly5YtW7bsOca3bkcu2tsD7GNwvDPfmAwX/5x9Ao6r52lw0l/9p+xdcNxMJzYl1XNn5s/YW+BYJ2HmcFOyM22B/gE7Dw44Mc7NKs4m+q+i+EfwnQQXiDFMZtBJ/AdPDcTn0zsFruLljzypNuZLAMNpSZmPGEGVz4Z3ApwxK7iMG+hutE2psSm98PxX6E2Dc5WVP0UHuhuiQ2iFG8y0GFv3fZRNglNsSoyBHZIboOuCs0dD0igG/T3H5sCp1hRan9wQXRvgArDODPrv8+BNgVNqlbXkGmq2e [...]
+         preserveAspectRatio="none"
+         style="image-rendering:optimizeSpeed"
+         height="1"
+         width="1" />
+    </mask>
+    <clipPath
+       id="clipPath135"
+       clipPathUnits="userSpaceOnUse">
+      <path
+         id="path133"
+         d="M -7.45653,298.73 H 281.543 v -108 H -7.45653 Z" />
+    </clipPath>
+    <clipPath
+       id="clipPath139"
+       clipPathUnits="userSpaceOnUse">
+      <path
+         id="path137"
+         d="M -7.45653,298.73 H 281.543 v -108 H -7.45653 Z" />
+    </clipPath>
+    <mask
+       id="mask141"
+       height="1"
+       width="1"
+       y="0"
+       x="0"
+       maskUnits="userSpaceOnUse">
+      <g
+         id="g151">
+        <g
+           id="g149"
+           clip-path="url(#clipPath139)">
+          <g
+             id="g147">
+            <g
+               id="g145"
+               transform="matrix(289,0,0,108,-7.4565225,190.73007)">
+              <image
+                 id="image143"
+                 xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASEAAABsCAYAAAAlrAQdAAAABHNCSVQICAgIfAhkiAAAFZpJREFUeJztnel227gShCE58973xe3cX53p6fRSvYCkJNY5PMRKLCI+FWA7eay1fq+T9Hg83DSZr+XJe1TPahfJs/T79/wUWs/U0mVaNl5Nj/KQ/Fu3HusECCFQ8OCSTXt1CCEQyYAHhQ1SB3lONv/WZ+lQCGUcyuPxCOPI3Uqz+nCksg4DBVMVSF6bFZeE5KNlbr2vDoMQsl3S7lpYy7PStOd6fZgSurCq264oXAFWNoz0M5OXKXPrfbQdQtlzHRmO4lrYS0P61VEXPjLPWvQoeDKAQuugfbTiUvf27bO1DUIofDTIWGloeS1s9UHr64SqC6vidpC8qTLdsJfWzbv1mtoCoWixo7DJXNZzkbvWV1RHbbsyE [...]
+                 transform="matrix(1,0,0,-1,0,1)"
+                 preserveAspectRatio="none"
+                 style="image-rendering:optimizeSpeed"
+                 height="1"
+                 width="1" />
+            </g>
+          </g>
+        </g>
+      </g>
+    </mask>
+    <mask
+       id="mask153"
+       height="1"
+       width="1"
+       y="0"
+       x="0"
+       maskUnits="userSpaceOnUse">
+      <image
+         id="image155"
+         xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASEAAABsCAAAAAAAx1vBAAAAAXNCSVQI5gpbmQAADqdJREFUeJzNnOuC6yoIhSHpef83DueHAgtEYzvpzHba3L19XaAmZpjWgfuCdcWw187aqgWpkhFfSvrGpUUvk/mLwLdnOyPOi3cJGRHA42wkRPyXMK0IgVJYv/bXGd0gDsqQAMM3+8kgJYfz15QWFTRrYmJiVkpt28RUJyFpCwhJpyHxyCAz+kcoTQmh42Fi+wKkKaHMx2svxQJ2kr5CYn9FaULI+TBxx8O+jYTKFGK1gnhsNW4Mgkpi+hNINSE2PsoGQjvqDmnmqLN9AZH530jqrylVhMz7KJ4Dlq6kgtDgOIJLtj9JO0Lx2CAppE2/TKkgxNp6GR77tP1bQqkBc2lERmExooteatJt+n4YCZl7dj5HWzZIx+iKPAxdwFFAg [...]
+         preserveAspectRatio="none"
+         style="image-rendering:optimizeSpeed"
+         height="1"
+         width="1" />
+    </mask>
+    <clipPath
+       id="clipPath197"
+       clipPathUnits="userSpaceOnUse">
+      <path
+         id="path195"
+         d="m 54.242,172.769 v -65.983 h 26.714 v 34.138 h 15.501 c 5.005,-7.711 6.21,-18.896 6.21,-26.053 v 0 c 0,-27.195 -19.129,-36.279 -34.634,-36.279 v 0 c -23.614,0 -35.34,14.284 -35.34,36.279 v 0 c 0,9.067 2.252,21.043 10.524,30.879 v 0 L 23.57,167.939 C 7.539,150.178 4.094,133.591 4.094,114.871 v 0 c 0,-50.729 32.399,-73.893 63.939,-73.893 v 0 c 31.535,0 63.416,20.252 63.416,73.71 v 0 c 0,26.049 -8.271,49.587 -23.609,58.081 v 0 z" />
+    </clipPath>
+    <linearGradient
+       id="linearGradient209"
+       spreadMethod="pad"
+       gradientTransform="matrix(52.458736,0,0,-52.458736,-27.616693,106.87352)"
+       gradientUnits="userSpaceOnUse"
+       y2="0"
+       x2="1"
+       y1="0"
+       x1="0">
+      <stop
+         id="stop203"
+         offset="0"
+         style="stop-opacity:1;stop-color:#ffffff" />
+      <stop
+         id="stop205"
+         offset="0.00202589"
+         style="stop-opacity:1;stop-color:#ffffff" />
+      <stop
+         id="stop207"
+         offset="1"
+         style="stop-opacity:1;stop-color:#221f1f" />
+    </linearGradient>
+    <clipPath
+       id="clipPath219"
+       clipPathUnits="userSpaceOnUse">
+      <path
+         id="path217"
+         d="m 126.103,319.498 -40.671,-35.12 c -8.964,22.769 -21.541,28.551 -36.358,28.551 v 0 c -21.712,0 -41.535,-17.944 -41.535,-52.48 v 0 -65.991 H 128.175 V 232.67 H 89.052 v 13.308 l 39.123,31.452 v 42.068 z M 34.766,260.449 c 0,10.039 7.409,14.865 14.996,14.865 v 0 c 7.241,0 13.958,-4.433 13.958,-14.487 v 0 -28.157 H 34.766 Z" />
+    </clipPath>
+    <linearGradient
+       id="linearGradient231"
+       spreadMethod="pad"
+       gradientTransform="matrix(52.454781,0,0,-52.454781,-27.575252,256.97772)"
+       gradientUnits="userSpaceOnUse"
+       y2="0"
+       x2="1"
+       y1="0"
+       x1="0">
+      <stop
+         id="stop225"
+         offset="0"
+         style="stop-opacity:1;stop-color:#ffffff" />
+      <stop
+         id="stop227"
+         offset="0.00202589"
+         style="stop-opacity:1;stop-color:#ffffff" />
+      <stop
+         id="stop229"
+         offset="1"
+         style="stop-opacity:1;stop-color:#221f1f" />
+    </linearGradient>
+    <clipPath
+       id="clipPath53-3"
+       clipPathUnits="userSpaceOnUse">
+      <path
+         id="path51-5"
+         d="M 10.701,328 C 5.318,328 0.819,324.021 0,318.859 v 0 V 43.141 C 0.819,37.979 5.318,34 10.701,34 v 0 h 336.04 c 5.959,0 10.835,4.876 10.835,10.834 v 0 272.331 c 0,5.959 -4.876,10.835 -10.835,10.835 v 0 z" />
+    </clipPath>
+    <clipPath
+       id="clipPath65-6"
+       clipPathUnits="userSpaceOnUse">
+      <path
+         id="path63-2"
+         d="m 10.701,328 c -4.038,0 -7.578,-2.239 -9.441,-5.536 v 0 C 0.456,320.976 0,319.273 0,317.463 v 0 -272.927 c 0,-1.812 0.458,-3.518 1.264,-5.008 v 0 C 3.128,36.235 6.666,34 10.701,34 v 0 H 344.463 C 350.283,34 355,38.717 355,44.536 v 0 272.927 c 0,5.82 -4.717,10.537 -10.537,10.537 v 0 z" />
+    </clipPath>
+    <linearGradient
+       id="linearGradient75-9"
+       spreadMethod="pad"
+       gradientTransform="matrix(355,0,0,-355,0,181)"
+       gradientUnits="userSpaceOnUse"
+       y2="0"
+       x2="1"
+       y1="0"
+       x1="0">
+      <stop
+         id="stop71-1"
+         offset="0"
+         style="stop-opacity:1;stop-color:#f15e22" />
+      <stop
+         id="stop73-2"
+         offset="1"
+         style="stop-opacity:1;stop-color:#f99e39" />
+    </linearGradient>
+    <clipPath
+       id="clipPath85-7"
+       clipPathUnits="userSpaceOnUse">
+      <path
+         id="path83-0"
+         d="M 10.701,328 C 5.318,328 0.819,324.021 0,318.859 v 0 V 43.141 C 0.819,37.979 5.318,34 10.701,34 v 0 h 336.04 c 5.959,0 10.835,4.876 10.835,10.834 v 0 272.331 c 0,5.959 -4.876,10.835 -10.835,10.835 v 0 z" />
+    </clipPath>
+    <clipPath
+       id="clipPath93-9"
+       clipPathUnits="userSpaceOnUse">
+      <path
+         id="path91-3"
+         d="M -13,191 H 299 V 23 H -13 Z" />
+    </clipPath>
+    <mask
+       id="mask99-6"
+       height="1"
+       width="1"
+       y="0"
+       x="0"
+       maskUnits="userSpaceOnUse">
+      <g
+         id="g109-0">
+        <g
+           id="g107-6"
+           clip-path="url(#clipPath97-8)">
+          <g
+             id="g105-2">
+            <g
+               id="g103-6"
+               transform="matrix(312,0,0,168,-13,23)">
+              <image
+                 id="image101-1"
+                 xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAATgAAACoCAYAAAB0bvKdAAAABHNCSVQICAgIfAhkiAAAFQNJREFUeJztne2WmzASRGXPPvg+eGZmf2SV9HSqPyQEEqLuOT4IgQ3YcF0tnMyrlPJdCCFkQ96zd4AQQs6CgiOEbAsFRwjZFgqOELItFBwhZFsoOELItlBwhJBtoeAIIdtCwRFCtoWCI4RsCwVHCNkWCo4Qsi0UHCFkWyg4Qsi2UHCEkG2h4Agh20LBEUK2hYIjhGwLBUcI2RYKjhCyLRQcIWRbKDhCyLZQcISQbaHgCCHbQsERQrblP7N3YGVer9fsXYB8f3/P3gVCbsGrlPLoq6VVYjOkd0RolCF5Mo9KcJGcMvJaNdVVtNCi/aUAyc5sneCsi7u1P1p2JZGQMsIatQ4hq7Od4JCIdF/POisIzpLOqP5oW [...]
+                 transform="matrix(1,0,0,-1,0,1)"
+                 preserveAspectRatio="none"
+                 style="image-rendering:optimizeSpeed"
+                 height="1"
+                 width="1" />
+            </g>
+          </g>
+        </g>
+      </g>
+    </mask>
+    <clipPath
+       id="clipPath97-8"
+       clipPathUnits="userSpaceOnUse">
+      <path
+         id="path95-7"
+         d="M -13,191 H 299 V 23 H -13 Z" />
+    </clipPath>
+    <mask
+       id="mask111-9"
+       height="1"
+       width="1"
+       y="0"
+       x="0"
+       maskUnits="userSpaceOnUse">
+      <image
+         id="image113-2"
+         xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAATgAAACoCAAAAABRBa1BAAAAAXNCSVQI5gpbmQAADQ5JREFUeJztne22q6wOhRP3uf8rPiXvD0gyA4jYWusag3Rtq7ZVfDrzAVU30bJly5YtW7Zs2bJly5YtW7Zs2bJly5YtW7Zs2bJly5YtW7bsOca3bkcu2tsD7GNwvDPfmAwX/5x9Ao6r52lw0l/9p+xdcNxMJzYl1XNn5s/YW+BYJ2HmcFOyM22B/gE7Dw44Mc7NKs4m+q+i+EfwnQQXiDFMZtBJ/AdPDcTn0zsFruLljzypNuZLAMNpSZmPGEGVz4Z3ApwxK7iMG+hutE2psSm98PxX6E2Dc5WVP0UHuhuiQ2iFG8y0GFv3fZRNglNsSoyBHZIboOuCs0dD0igG/T3H5sCp1hRan9wQXRvgArDODPrv8+BNgVNqlbXkGmq2e [...]
+         preserveAspectRatio="none"
+         style="image-rendering:optimizeSpeed"
+         height="1"
+         width="1" />
+    </mask>
+    <clipPath
+       id="clipPath135-0"
+       clipPathUnits="userSpaceOnUse">
+      <path
+         id="path133-2"
+         d="M -7.45653,298.73 H 281.543 v -108 H -7.45653 Z" />
+    </clipPath>
+    <mask
+       id="mask141-3"
+       height="1"
+       width="1"
+       y="0"
+       x="0"
+       maskUnits="userSpaceOnUse">
+      <g
+         id="g151-7">
+        <g
+           id="g149-5"
+           clip-path="url(#clipPath139-8)">
+          <g
+             id="g147-9">
+            <g
+               id="g145-2"
+               transform="matrix(289,0,0,108,-7.4565225,190.73007)">
+              <image
+                 id="image143-2"
+                 xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASEAAABsCAYAAAAlrAQdAAAABHNCSVQICAgIfAhkiAAAFZpJREFUeJztnel227gShCE58973xe3cX53p6fRSvYCkJNY5PMRKLCI+FWA7eay1fq+T9Hg83DSZr+XJe1TPahfJs/T79/wUWs/U0mVaNl5Nj/KQ/Fu3HusECCFQ8OCSTXt1CCEQyYAHhQ1SB3lONv/WZ+lQCGUcyuPxCOPI3Uqz+nCksg4DBVMVSF6bFZeE5KNlbr2vDoMQsl3S7lpYy7PStOd6fZgSurCq264oXAFWNoz0M5OXKXPrfbQdQtlzHRmO4lrYS0P61VEXPjLPWvQoeDKAQuugfbTiUvf27bO1DUIofDTIWGloeS1s9UHr64SqC6vidpC8qTLdsJfWzbv1mtoCoWixo7DJXNZzkbvWV1RHbbsyE [...]
+                 transform="matrix(1,0,0,-1,0,1)"
+                 preserveAspectRatio="none"
+                 style="image-rendering:optimizeSpeed"
+                 height="1"
+                 width="1" />
+            </g>
+          </g>
+        </g>
+      </g>
+    </mask>
+    <clipPath
+       id="clipPath139-8"
+       clipPathUnits="userSpaceOnUse">
+      <path
+         id="path137-9"
+         d="M -7.45653,298.73 H 281.543 v -108 H -7.45653 Z" />
+    </clipPath>
+    <mask
+       id="mask153-7"
+       height="1"
+       width="1"
+       y="0"
+       x="0"
+       maskUnits="userSpaceOnUse">
+      <image
+         id="image155-3"
+         xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASEAAABsCAAAAAAAx1vBAAAAAXNCSVQI5gpbmQAADqdJREFUeJzNnOuC6yoIhSHpef83DueHAgtEYzvpzHba3L19XaAmZpjWgfuCdcWw187aqgWpkhFfSvrGpUUvk/mLwLdnOyPOi3cJGRHA42wkRPyXMK0IgVJYv/bXGd0gDsqQAMM3+8kgJYfz15QWFTRrYmJiVkpt28RUJyFpCwhJpyHxyCAz+kcoTQmh42Fi+wKkKaHMx2svxQJ2kr5CYn9FaULI+TBxx8O+jYTKFGK1gnhsNW4Mgkpi+hNINSE2PsoGQjvqDmnmqLN9AZH530jqrylVhMz7KJ4Dlq6kgtDgOIJLtj9JO0Lx2CAppE2/TKkgxNp6GR77tP1bQqkBc2lERmExooteatJt+n4YCZl7dj5HWzZIx+iKPAxdwFFAg [...]
+         preserveAspectRatio="none"
+         style="image-rendering:optimizeSpeed"
+         height="1"
+         width="1" />
+    </mask>
+    <clipPath
+       id="clipPath197-6"
+       clipPathUnits="userSpaceOnUse">
+      <path
+         id="path195-1"
+         d="m 54.242,172.769 v -65.983 h 26.714 v 34.138 h 15.501 c 5.005,-7.711 6.21,-18.896 6.21,-26.053 v 0 c 0,-27.195 -19.129,-36.279 -34.634,-36.279 v 0 c -23.614,0 -35.34,14.284 -35.34,36.279 v 0 c 0,9.067 2.252,21.043 10.524,30.879 v 0 L 23.57,167.939 C 7.539,150.178 4.094,133.591 4.094,114.871 v 0 c 0,-50.729 32.399,-73.893 63.939,-73.893 v 0 c 31.535,0 63.416,20.252 63.416,73.71 v 0 c 0,26.049 -8.271,49.587 -23.609,58.081 v 0 z" />
+    </clipPath>
+    <linearGradient
+       id="linearGradient209-2"
+       spreadMethod="pad"
+       gradientTransform="matrix(52.458736,0,0,-52.458736,-27.616693,106.87352)"
+       gradientUnits="userSpaceOnUse"
+       y2="0"
+       x2="1"
+       y1="0"
+       x1="0">
+      <stop
+         id="stop203-9"
+         offset="0"
+         style="stop-opacity:1;stop-color:#ffffff" />
+      <stop
+         id="stop205-3"
+         offset="0.00202589"
+         style="stop-opacity:1;stop-color:#ffffff" />
+      <stop
+         id="stop207-1"
+         offset="1"
+         style="stop-opacity:1;stop-color:#221f1f" />
+    </linearGradient>
+    <clipPath
+       id="clipPath219-9"
+       clipPathUnits="userSpaceOnUse">
+      <path
+         id="path217-4"
+         d="m 126.103,319.498 -40.671,-35.12 c -8.964,22.769 -21.541,28.551 -36.358,28.551 v 0 c -21.712,0 -41.535,-17.944 -41.535,-52.48 v 0 -65.991 H 128.175 V 232.67 H 89.052 v 13.308 l 39.123,31.452 v 42.068 z M 34.766,260.449 c 0,10.039 7.409,14.865 14.996,14.865 v 0 c 7.241,0 13.958,-4.433 13.958,-14.487 v 0 -28.157 H 34.766 Z" />
+    </clipPath>
+    <linearGradient
+       id="linearGradient231-7"
+       spreadMethod="pad"
+       gradientTransform="matrix(52.454781,0,0,-52.454781,-27.575252,256.97772)"
+       gradientUnits="userSpaceOnUse"
+       y2="0"
+       x2="1"
+       y1="0"
+       x1="0">
+      <stop
+         id="stop225-8"
+         offset="0"
+         style="stop-opacity:1;stop-color:#ffffff" />
+      <stop
+         id="stop227-4"
+         offset="0.00202589"
+         style="stop-opacity:1;stop-color:#ffffff" />
+      <stop
+         id="stop229-5"
+         offset="1"
+         style="stop-opacity:1;stop-color:#221f1f" />
+    </linearGradient>
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath18-0">
+      <path
+         d="m 450.395,454.342 -9.299,-19.067 19.067,-9.3 9.299,19.068 z"
+         id="path16-3" />
+    </clipPath>
+    <mask
+       maskUnits="userSpaceOnUse"
+       x="0"
+       y="0"
+       width="1"
+       height="1"
+       id="mask24-6">
+      <image
+         width="1"
+         height="1"
+         style="image-rendering:optimizeSpeed"
+         preserveAspectRatio="none"
+         xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAH4AAAB+CAAAAADHSPpUAAAAAXNCSVQI5gpbmQAAA4dJREFUaIHt279PFEEUB/C5IwdEKYxRQwJEGguwgEBCaQMFicZEYgf/gMX9A/ZQeR0J/gFQw6kxJnaWBshRiASbM2AiKsYQNNwReBYYdd+82fn1XnaTu9fB7H4/M7uzd3t3O0r5VWGmuvNilmqZfb5TnSl4xvnVxOIRAADM6U1zAABwtDghZU8fwt9axY2r/9oOp/ntwhYkqi/Z3Jds3WI+CeuAainZvoTb1xnxZRwOUE9uUde3WGbCO8/0bAcezjrt2UXrFuWGfRs6ulEO2/H/WiPG5TZ6AFiL1TfoXEceNizxlgO7NxbTd6XG9mL4Wn+crlR/LZyvjMTqSo1UQvecNJxQj3MPADAZppdSIn14KJmNlIP/M6zXXkFmfj6l0 [...]
+         id="image26-1" />
+    </mask>
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath36-0">
+      <path
+         d="M 0,595.28 H 841.89 V 0 H 0 Z"
+         id="path34-6" />
+    </clipPath>
+  </defs>
+  <metadata
+     id="metadata5">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <rect
+     style="opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal"
+     id="rect1667"
+     width="74.929008"
+     height="48.643055"
+     x="-0.37417734"
+     y="-0.45678806" />
+  <g
+     id="layer1"
+     transform="translate(0,-249.37496)" />
+  <g
+     transform="matrix(0.44576922,0,0,0.44576922,-10.070663,-12.66831)"
+     id="g1617">
+    <g
+       transform="translate(-12.436742,-219.37007)"
+       id="layer1-5" />
+    <g
+       transform="matrix(0.37365477,0,0,-0.37365477,-49.857693,279.06728)"
+       id="g1187"
+       style="fill:#fffffe;fill-opacity:1">
+      <g
+         id="g12"
+         style="fill:#fffffe;fill-opacity:1">
+        <g
+           clip-path="url(#clipPath18-0)"
+           id="g14"
+           style="fill:#fffffe;fill-opacity:1">
+          <g
+             id="g20"
+             style="fill:#fffffe;fill-opacity:1">
+            <g
+               transform="matrix(19.067261,-9.2997284,9.2997284,19.067261,441.09578,435.27502)"
+               id="g22"
+               style="fill:#fffffe;fill-opacity:1">
+              <image
+                 id="image28"
+                 mask="url(#mask24-6)"
+                 xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAH4AAAB+CAYAAADiI6WIAAAABHNCSVQICAgIfAhkiAAAArpJREFUeJzt3U1uGkEQQGGIfBhLuUSOnktE8m0mq5ERNjJM1x+89y29Gboe1WBvfN62bTs9qX9/3r/9+e+/H0/5nErnZwx/K8SlqCiVz6r0NOHvCXBtNUjHM6uMDn9k8NeOhuh8doVf3S/glojBd5t8hrfuF3Bt8rCO2M8zbfvHhH+14NemvQFGXPWvHv3SlLO2h58yiEoTztwafsIAunSfvS1898En6JxBS3ijf+qaRXl4o3/VMZPS8Ea/rXo2ZeGN/rPKGbX/OqceJeHd9vtVzSo9vNEfVzEzr3qo1PBu+3HZs3PjodLCu+3rMmfoxkOlhHfb42TN0o2HCg/vtsfLmKkbD2V4qNDwXvN5omfrxkMZHiosv [...]
+                 transform="matrix(1,0,0,-1,0,1)"
+                 preserveAspectRatio="none"
+                 style="fill:#fffffe;fill-opacity:1;image-rendering:optimizeSpeed"
+                 height="1"
+                 width="1" />
+            </g>
+          </g>
+        </g>
+      </g>
+      <g
+         id="g30"
+         style="fill:#fffffe;fill-opacity:1">
+        <g
+           clip-path="url(#clipPath36-0)"
+           id="g32"
+           style="fill:#fffffe;fill-opacity:1">
+          <g
+             transform="translate(588.7041,440.3208)"
+             id="g38"
+             style="fill:#fffffe;fill-opacity:1">
+            <path
+               id="path40"
+               style="fill:#fffffe;fill-opacity:1;fill-rule:nonzero;stroke:none"
+               d="m 0,0 c 0,10.733 -3.674,18.588 -11.02,23.566 -7.345,4.977 -18.334,7.466 -32.964,7.466 -14.694,0 -25.697,-2.489 -33.012,-7.466 -3.809,-2.591 -6.603,-5.981 -8.428,-10.132 h 23.676 c 1.666,0.627 3.619,1.088 5.891,1.362 3.238,0.39 7.195,0.585 11.873,0.585 4.676,0 8.634,-0.195 11.873,-0.585 3.238,-0.39 5.859,-1.14 7.869,-2.248 2.009,-1.11 3.464,-2.669 4.363,-4.678 0.9,-2.009 1.35,-4.632 1.35,-7.87 0,-3.238 -0.45,-5.862 -1.35,-7.87 -0.899,-2.01 -2.354,-3.584 -4.363,-4.723 -2. [...]
+               inkscape:connector-curvature="0" />
+          </g>
+        </g>
+      </g>
+    </g>
+  </g>
+  <g
+     transform="matrix(0.09480937,0,0,-0.09480937,19.679648,32.576607)"
+     id="g45">
+    <g
+       id="g47">
+      <g
+         clip-path="url(#clipPath53-3)"
+         id="g49">
+        <g
+           transform="translate(354,44.5367)"
+           id="g55">
+          <path
+             id="path57"
+             style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             d="M 0,0 C 0,-5.819 -4.717,-10.537 -10.537,-10.537 H -344.463 C -350.283,-10.537 -355,-5.819 -355,0 v 272.927 c 0,5.819 4.717,10.536 10.537,10.536 H -10.537 C -4.717,283.463 0,278.746 0,272.927 Z" />
+        </g>
+      </g>
+    </g>
+    <g
+       id="g59">
+      <g
+         clip-path="url(#clipPath65-6)"
+         id="g61">
+        <g
+           id="g67">
+          <g
+             id="g69">
+            <path
+               id="path77"
+               style="fill:url(#linearGradient75-9);stroke:none"
+               d="m 10.701,328 c -4.038,0 -7.578,-2.239 -9.441,-5.536 v 0 C 0.456,320.976 0,319.273 0,317.463 v 0 -272.927 c 0,-1.812 0.458,-3.518 1.264,-5.008 v 0 C 3.128,36.235 6.666,34 10.701,34 v 0 H 344.463 C 350.283,34 355,38.717 355,44.536 v 0 272.927 c 0,5.82 -4.717,10.537 -10.537,10.537 v 0 z" />
+          </g>
+        </g>
+      </g>
+    </g>
+    <g
+       id="g79">
+      <g
+         clip-path="url(#clipPath85-7)"
+         id="g81">
+        <g
+           id="g87">
+          <g
+             id="g89" />
+          <g
+             id="g127">
+            <g
+               style="opacity:0.49000501"
+               id="g125"
+               clip-path="url(#clipPath93-9)">
+              <g
+                 id="g123">
+                <g
+                   id="g115" />
+                <g
+                   id="g121"
+                   mask="url(#mask99-6)">
+                  <g
+                     id="g119"
+                     transform="matrix(312,0,0,168,-13,23)">
+                    <image
+                       id="image117"
+                       mask="url(#mask111-9)"
+                       xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAATgAAACoCAYAAAB0bvKdAAAABHNCSVQICAgIfAhkiAAAAkBJREFUeJzt1EENACAQwDDAv+dDBSFZWgV7bc/MLICg8zsA4BWDA7IMDsgyOCDL4IAsgwOyDA7IMjggy+CALIMDsgwOyDI4IMvggCyDA7IMDsgyOCDL4IAsgwOyDA7IMjggy+CALIMDsgwOyDI4IMvggCyDA7IMDsgyOCDL4IAsgwOyDA7IMjggy+CALIMDsgwOyDI4IMvggCyDA7IMDsgyOCDL4IAsgwOyDA7IMjggy+CALIMDsgwOyDI4IMvggCyDA7IMDsgyOCDL4IAsgwOyDA7IMjggy+CALIMDsgwOyDI4IMvggCyDA7IMDsgyOCDL4IAsgwOyDA7IMjggy+CALIMDsgwOyDI4IMvggCyDA7I [...]
+                       transform="matrix(1,0,0,-1,0,1)"
+                       preserveAspectRatio="none"
+                       style="image-rendering:optimizeSpeed"
+                       height="1"
+                       width="1" />
+                  </g>
+                </g>
+              </g>
+            </g>
+          </g>
+        </g>
+        <g
+           id="g129">
+          <g
+             id="g131" />
+          <g
+             id="g169">
+            <g
+               style="opacity:0.49000501"
+               id="g167"
+               clip-path="url(#clipPath135-0)">
+              <g
+                 id="g165">
+                <g
+                   id="g157" />
+                <g
+                   id="g163"
+                   mask="url(#mask141-3)">
+                  <g
+                     id="g161"
+                     transform="matrix(289,0,0,108,-7.4565225,190.73007)">
+                    <image
+                       id="image159"
+                       mask="url(#mask153-7)"
+                       xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASEAAABsCAYAAAAlrAQdAAAABHNCSVQICAgIfAhkiAAAAW9JREFUeJzt1DEBwDAAw7B1/DmnMHxUQuDLZ9s+gMhfBwBvMyEgZUJAyoSAlAkBKRMCUiYEpEwISJkQkDIhIGVCQMqEgJQJASkTAlImBKRMCEiZEJAyISBlQkDKhICUCQEpEwJSJgSkTAhImRCQMiEgZUJAyoSAlAkBKRMCUiYEpEwISJkQkDIhIGVCQMqEgJQJASkTAlImBKRMCEiZEJAyISBlQkDKhICUCQEpEwJSJgSkTAhImRCQMiEgZUJAyoSAlAkBKRMCUiYEpEwISJkQkDIhIGVCQMqEgJQJASkTAlImBKRMCEiZEJAyISBlQkDKhICUCQEpEwJSJgSkTAhImRCQMiEgZUJAyoSAlAkBKRM [...]
+                       transform="matrix(1,0,0,-1,0,1)"
+                       preserveAspectRatio="none"
+                       style="image-rendering:optimizeSpeed"
+                       height="1"
+                       width="1" />
+                  </g>
+                </g>
+              </g>
+            </g>
+          </g>
+        </g>
+        <g
+           transform="translate(167.7321,121.5312)"
+           id="g171">
+          <path
+             id="path173"
+             style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             d="m 0,0 c 0.008,-10.15 2.212,-19.965 6.617,-29.455 4.404,-9.493 10.945,-16.834 19.631,-22.03 8.677,-5.204 18.016,-7.798 28.022,-7.79 15.545,0.012 28.381,5.49 38.498,16.44 10.122,10.949 15.171,24.859 15.159,41.733 C 107.92,16.03 102.699,30.199 92.271,41.395 81.835,52.595 68.785,58.185 53.116,58.169 37.814,58.161 25.13,52.615 15.072,41.534 5.013,30.457 -0.008,16.615 0,0.004 Z m 68.972,207.305 h 62.303 44.808 c 3.836,0 7.309,-1.54 9.824,-4.039 2.515,-2.49 4.07,-5.94 4.07,-9.74 [...]
+        </g>
+        <g
+           transform="translate(343.8594,115.6368)"
+           id="g175">
+          <path
+             id="path177"
+             style="fill:#d4550f;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             d="m 0,0 c 8.367,-9.143 12.135,-20.948 12.135,-34.154 0,-33.902 -20.264,-47.359 -42.775,-47.482 -21.326,-0.131 -43.723,14.853 -43.723,47.482 0,12.187 4.365,23.487 12.732,32.626 L -50.2,-13.965 c -4.83,-5.336 -6.835,-13.074 -6.835,-20.189 0,-20.184 14.49,-28.054 26.51,-27.93 12.024,0.127 25.691,7.11 25.691,27.93 0,7.115 -2.949,16.508 -7.894,21.84 z" />
+        </g>
+        <g
+           transform="translate(324.8847,169.7239)"
+           id="g179">
+          <path
+             id="path181"
+             style="fill:#d4550f;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             d="m 0,0 c -7.305,0 -15.314,-4.822 -15.314,-15.863 0,-10.922 8.009,-15.744 15.314,-15.744 7.309,0 15.207,4.695 15.207,15.744 C 15.207,-4.691 7.659,0 0,0 m 0,-50.148 c -17.558,0 -30.517,13.456 -30.517,34.285 0,20.948 12.959,34.4 30.517,34.4 17.558,0 30.286,-13.078 30.286,-34.4 C 30.286,-37.07 17.558,-50.148 0,-50.148" />
+        </g>
+        <g
+           transform="translate(353.8739,245.2724)"
+           id="g183">
+          <path
+             id="path185"
+             style="fill:#d4550f;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             d="m 0,0 h -30.756 c -8.956,0 -13.547,-4.19 -13.547,-12.951 -0.12,-8.506 6.712,-14.22 14.252,-14.22 H 0 v -18.032 h -58.213 v 16.508 l 7.424,0.637 c -6.716,5.586 -8.96,12.696 -8.833,20.311 0,14.093 6.128,26.157 28.751,26.157 L 0,18.41 Z" />
+        </g>
+        <g
+           transform="translate(353.8739,284.5029)"
+           id="g187">
+          <path
+             id="path189"
+             style="fill:#d4550f;fill-opacity:1;fill-rule:nonzero;stroke:none"
+             d="M 0,0 H -42.891 V -11.041 H -57.155 V 0 h -3.414 c -16.849,0 -23.45,13.205 -23.45,25.396 0,6.983 1.77,11.937 4.949,17.395 l 11.897,-6.218 c -1.643,-2.921 -2.348,-6.227 -2.348,-9.012 0,-5.467 2.821,-9.275 8.952,-9.275 h 3.414 v 17.395 h 14.264 V 18.286 H 0 Z" />
+        </g>
+      </g>
+    </g>
+    <g
+       id="g191">
+      <g
+         clip-path="url(#clipPath197-6)"
+         id="g193">
+        <g
+           id="g199">
+          <g
+             id="g201">
+            <path
+               id="path211"
+               style="fill:url(#linearGradient209-2);stroke:none"
+               d="m 54.242,172.769 v -65.983 h 26.714 v 34.138 h 15.501 c 5.005,-7.711 6.21,-18.896 6.21,-26.053 v 0 c 0,-27.195 -19.129,-36.279 -34.634,-36.279 v 0 c -23.614,0 -35.34,14.284 -35.34,36.279 v 0 c 0,9.067 2.252,21.043 10.524,30.879 v 0 L 23.57,167.939 C 7.539,150.178 4.094,133.591 4.094,114.871 v 0 c 0,-50.729 32.399,-73.893 63.939,-73.893 v 0 c 31.535,0 63.416,20.252 63.416,73.71 v 0 c 0,26.049 -8.271,49.587 -23.609,58.081 v 0 z" />
+          </g>
+        </g>
+      </g>
+    </g>
+    <g
+       id="g213">
+      <g
+         clip-path="url(#clipPath219-9)"
+         id="g215">
+        <g
+           id="g221">
+          <g
+             id="g223">
+            <path
+               id="path233"
+               style="fill:url(#linearGradient231-7);stroke:none"
+               d="m 126.103,319.498 -40.671,-35.12 c -8.964,22.769 -21.541,28.551 -36.358,28.551 v 0 c -21.712,0 -41.535,-17.944 -41.535,-52.48 v 0 -65.991 H 128.175 V 232.67 H 89.052 v 13.308 l 39.123,31.452 v 42.068 z M 34.766,260.449 c 0,10.039 7.409,14.865 14.996,14.865 v 0 c 7.241,0 13.958,-4.433 13.958,-14.487 v 0 -28.157 H 34.766 Z" />
+          </g>
+        </g>
+      </g>
+    </g>
+  </g>
+</svg>
diff --git a/img/courses/groovy-course-beginner.png b/img/courses/groovy-course-beginner.png
new file mode 100644
index 0000000..3ad27dd
Binary files /dev/null and b/img/courses/groovy-course-beginner.png differ
diff --git a/img/courses/groovy-course-fundamentals.png b/img/courses/groovy-course-fundamentals.png
new file mode 100644
index 0000000..9fa52c6
Binary files /dev/null and b/img/courses/groovy-course-fundamentals.png differ
diff --git a/img/courses/groovy-course-mastering.png b/img/courses/groovy-course-mastering.png
new file mode 100644
index 0000000..d27cbd6
Binary files /dev/null and b/img/courses/groovy-course-mastering.png differ
diff --git a/img/courses/groovy-course-metaprogramming.png b/img/courses/groovy-course-metaprogramming.png
new file mode 100644
index 0000000..a043422
Binary files /dev/null and b/img/courses/groovy-course-metaprogramming.png differ
diff --git a/img/courses/groovy-course-practical.png b/img/courses/groovy-course-practical.png
new file mode 100644
index 0000000..395c4ee
Binary files /dev/null and b/img/courses/groovy-course-practical.png differ
diff --git a/img/ecosystem/infrastructor.png b/img/ecosystem/infrastructor.png
new file mode 100644
index 0000000..6a8ec46
Binary files /dev/null and b/img/ecosystem/infrastructor.png differ
diff --git a/wiki/GEP-14.html b/wiki/GEP-14.html
new file mode 100644
index 0000000..7243735
--- /dev/null
+++ b/wiki/GEP-14.html
@@ -0,0 +1,379 @@
+<!DOCTYPE html>
+<!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
+<!--[if IE 7]>         <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
+<!--[if IE 8]>         <html class="no-js lt-ie9"> <![endif]-->
+<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]--><head>
+    <meta charset='utf-8'/><meta http-equiv='X-UA-Compatible' content='IE=edge'/><meta name='viewport' content='width=device-width, initial-scale=1'/><title>The Apache Groovy programming language - Developer docs - GEP-14</title><link href='../img/favicon.ico' type='image/x-ico' rel='icon'/><link rel='stylesheet' type='text/css' href='../css/bootstrap.css'/><link rel='stylesheet' type='text/css' href='../css/font-awesome.min.css'/><link rel='stylesheet' type='text/css' href='../css/style [...]
+</head><body>
+    <div id='fork-me'>
+        <a href='https://github.com/apache/groovy'>
+            <img style='position: fixed; top: 20px; right: -58px; border: 0; z-index: 100; transform: rotate(45deg);' src='/img/horizontal-github-ribbon.png'/>
+        </a>
+    </div><div id='st-container' class='st-container st-effect-9'>
+        <nav class='st-menu st-effect-9' id='menu-12'>
+            <h2 class='icon icon-lab'>Socialize</h2><ul>
+                <li>
+                    <a href='http://groovy-lang.org/mailing-lists.html' class='icon'><span class='fa fa-envelope'></span> Discuss on the mailing-list</a>
+                </li><li>
+                    <a href='https://twitter.com/ApacheGroovy' class='icon'><span class='fa fa-twitter'></span> Groovy on Twitter</a>
+                </li><li>
+                    <a href='http://groovy-lang.org/events.html' class='icon'><span class='fa fa-calendar'></span> Events and conferences</a>
+                </li><li>
+                    <a href='https://github.com/apache/groovy' class='icon'><span class='fa fa-github'></span> Source code on GitHub</a>
+                </li><li>
+                    <a href='http://groovy-lang.org/reporting-issues.html' class='icon'><span class='fa fa-bug'></span> Report issues in Jira</a>
+                </li><li>
+                    <a href='http://stackoverflow.com/questions/tagged/groovy' class='icon'><span class='fa fa-stack-overflow'></span> Stack Overflow questions</a>
+                </li><li>
+                    <a href='http://groovycommunity.com/' class='icon'><span class='fa fa-slack'></span> Slack Community</a>
+                </li>
+            </ul>
+        </nav><div class='st-pusher'>
+            <div class='st-content'>
+                <div class='st-content-inner'>
+                    <!--[if lt IE 7]>
+                    <p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
+                <![endif]--><div><div class='navbar navbar-default navbar-static-top' role='navigation'>
+                            <div class='container'>
+                                <div class='navbar-header'>
+                                    <button type='button' class='navbar-toggle' data-toggle='collapse' data-target='.navbar-collapse'>
+                                        <span class='sr-only'></span><span class='icon-bar'></span><span class='icon-bar'></span><span class='icon-bar'></span>
+                                    </button><a class='navbar-brand' href='../index.html'>
+                                        <i class='fa fa-star'></i> Apache Groovy
+                                    </a>
+                                </div><div class='navbar-collapse collapse'>
+                                    <ul class='nav navbar-nav navbar-right'>
+                                        <li class=''><a href='http://groovy-lang.org/learn.html'>Learn</a></li><li class=''><a href='http://groovy-lang.org/documentation.html'>Documentation</a></li><li class=''><a href='/download.html'>Download</a></li><li class=''><a href='http://groovy-lang.org/support.html'>Support</a></li><li class=''><a href='/'>Contribute</a></li><li class=''><a href='http://groovy-lang.org/ecosystem.html'>Ecosystem</a></li><li class=''><a href='https://groovy.apac [...]
+                                            <a data-effect='st-effect-9' class='st-trigger' href='#'>Socialize</a>
+                                        </li><li class=''>
+                                            <a href='../search.html'>
+                                                <i class='fa fa-search'></i>
+                                            </a>
+                                        </li>
+                                    </ul>
+                                </div>
+                            </div>
+                        </div><div id='content' class='page-1'><div class='row'><div class='row-fluid'><div class='col-lg-3'><ul class='nav-sidebar'><li class='active'><a href='#doc'>GEP-14</a></li><li><a href='#_abstract' class='anchor-link'>Abstract</a></li><li><a href='#_references_and_useful_links' class='anchor-link'>References and useful links</a></li><li><a href='#_update_history' class='anchor-link'>Update history</a></li></ul></div><div class='col-lg-8 col-lg-pull-0'><a name='do [...]
+<div class="sectionbody">
+<div class="sidebarblock">
+<div class="content">
+<div class="title">Metadata</div>
+<div class="hdlist">
+<table>
+<tr>
+<td class="hdlist1">
+<strong>Number</strong>
+</td>
+<td class="hdlist2">
+<p>GEP-14</p>
+</td>
+</tr>
+<tr>
+<td class="hdlist1">
+<strong>Title</strong>
+</td>
+<td class="hdlist2">
+<p>Record classes</p>
+</td>
+</tr>
+<tr>
+<td class="hdlist1">
+<strong>Version</strong>
+</td>
+<td class="hdlist2">
+<p>1</p>
+</td>
+</tr>
+<tr>
+<td class="hdlist1">
+<strong>Type</strong>
+</td>
+<td class="hdlist2">
+<p>Feature</p>
+</td>
+</tr>
+<tr>
+<td class="hdlist1">
+<strong>Status</strong>
+</td>
+<td class="hdlist2">
+<p>Draft</p>
+</td>
+</tr>
+<tr>
+<td class="hdlist1">
+<strong>Leader</strong>
+</td>
+<td class="hdlist2">
+<p>Paul King</p>
+</td>
+</tr>
+<tr>
+<td class="hdlist1">
+<strong>Created</strong>
+</td>
+<td class="hdlist2">
+<p>2021-10-26</p>
+</td>
+</tr>
+<tr>
+<td class="hdlist1">
+<strong>Last modification</strong>&#160;
+</td>
+<td class="hdlist2">
+<p>2021-10-26</p>
+</td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_abstract">Abstract</h2>
+<div class="sectionbody">
+<div class="paragraph">
+<p>Record classes, or <em>records</em> for short, are a special kind of class
+useful for modelling plain data aggregates.
+They provide a compact syntax with less ceremony than normal classes.
+Groovy already has AST transforms such as <code>@Immutable</code> and <code>@Canonical</code>
+which already dramatically reduce ceremony but records have been
+introduced in Java and record classes in Groovy are designed to align
+with Java record classes.</p>
+</div>
+<div class="sect2">
+<h3 id="_motivation">Motivation</h3>
+<div class="paragraph">
+<p>For motivation of the general concept for records,
+see the References and useful links section below.
+The overall summary is that very succinct classes can be written
+for the special case of plain data aggregates, e.g.:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="prettyprint highlight"><code data-lang="groovy">record Point3D(int x, int y, int z) { }</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>or:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="prettyprint highlight"><code data-lang="groovy">record Person(String firstName, String lastName) { }</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>Such classes have automatic <code>toString</code>, <code>hashCode</code> and <code>equals</code> methods
+and an automatic tuple constructor. All of these factor into account the
+properties (known as record components) of the class.</p>
+</div>
+</div>
+<div class="sect2">
+<h3 id="_requirements">Requirements</h3>
+<div class="paragraph">
+<p>The main requirement is to provide equivalent functionality to Java record classes when compiling on suitable JDK versions (16+).
+By <em>equivalent functionality</em>, the following aspects are relevant:</p>
+</div>
+<div class="ulist">
+<ul>
+<li>
+<p>Support reduced ceremony when writing records.</p>
+</li>
+<li>
+<p>Store appropriate information at the bytecode level so that Groovy records are recognised by Java.
+We refer to classes with such bytecode information as <em>native</em> records.</p>
+</li>
+<li>
+<p>Maintain Java syntax compatibility where possible including the compact constructor syntax.</p>
+</li>
+</ul>
+</div>
+<div class="sect3">
+<h4 id="_non_goals">Non-goals</h4>
+<div class="ulist">
+<ul>
+<li>
+<p>Provide native record support on versions of the JDK which supported records in preview mode</p>
+</li>
+</ul>
+</div>
+</div>
+</div>
+<div class="sect2">
+<h3 id="_design_considerations">Design considerations</h3>
+<div class="ulist">
+<ul>
+<li>
+<p>Numerous Groovy AST transforms already provide functionality that overlaps with some features of Java records, e.g. <code>@ToString</code>
+helps reduce ceremony by offering a declarative mechanism to achieve an <em>automatic</em> <code>toString</code> method.
+Where it makes sense, Groovy&#8217;s record implementation should leverage such existing functionality.</p>
+</li>
+<li>
+<p>Even though existing Groovy AST transforms can be pieced together to achieve mimic record functionality,
+it sees worth providing a pre-canned packaging of those pieces to mirror record functionality in a concise way.
+Records should not introduce any additional impedance for Java developers learning or using Groovy.</p>
+</li>
+<li>
+<p>Groovy&#8217;s existing AST transforms offer additional customization options and additional boilerplate reduction options.
+These should be available with Groovy records (when it makes sense).</p>
+</li>
+<li>
+<p>Given that Groovy&#8217;s existing AST transforms work for JDK versions prior to JDK16, Groovy&#8217;s record functionality can
+allow the creation of <em>record-like</em> classes. Unlike <em>native</em> records, these won&#8217;t have record information at the
+bytecode level but will otherwise follow the same conventions as native records. Such classes will store record
+information using annotations. They will be recognised by the Groovy compiler but not a Java compiler.</p>
+</li>
+<li>
+<p>Given that records are primarily designed to be data aggregates, Groovy records are <code>@CompileStatic</code> by default.</p>
+</li>
+</ul>
+</div>
+</div>
+<div class="sect2">
+<h3 id="_groovy_special_features">Groovy special features</h3>
+<div class="ulist">
+<ul>
+<li>
+<p>Support Groovy&#8217;s named-parameter syntax</p>
+</li>
+<li>
+<p>Support Groovy&#8217;s <code>getAt</code> method for positional access of components</p>
+</li>
+<li>
+<p>Support Groovy&#8217;s default parameter concept</p>
+</li>
+<li>
+<p>Support additional helper methods found in other languages, e.g. Kotlin data classes and Scala case classes. Candidates include <code>copyWith</code>, <code>size</code>, <code>toMap</code>, <code>toList</code>.</p>
+</li>
+<li>
+<p>Support destructuring of records</p>
+</li>
+</ul>
+</div>
+<div class="sect3">
+<h4 id="_initial_implementation">Initial implementation</h4>
+<div class="ulist">
+<ul>
+<li>
+<p>Provide a <code>@RecordType</code> annotation collector which collects
+existing AST transforms suitable for providing the desired functionality.</p>
+</li>
+<li>
+<p>Provide a <code>@RecordBase</code> AST transform which encapsulates any special
+treatment not found in existing transforms.</p>
+</li>
+<li>
+<p>Provide a <code>@RecordOptions</code> annotation which allows the constructed
+record implementation to be customised.</p>
+</li>
+<li>
+<p>Provide support for the <code>record</code> keyword in the grammar which can be used
+instead of the <code>@RecordType</code> annotation.</p>
+</li>
+</ul>
+</div>
+</div>
+</div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_references_and_useful_links">References and useful links</h2>
+<div class="sectionbody">
+<div class="ulist">
+<ul>
+<li>
+<p><a href="https://openjdk.java.net/jeps/395">JEP 395: Records</a></p>
+</li>
+<li>
+<p><a href="https://openjdk.java.net/jeps/384">JEP 384: Records (Second Preview)</a></p>
+</li>
+<li>
+<p><a href="https://openjdk.java.net/jeps/359">JEP 359: Records (Preview)</a></p>
+</li>
+<li>
+<p><a href="https://docs.oracle.com/en/java/javase/16/language/records.html">Record Classes</a> Java documentation</p>
+</li>
+<li>
+<p><a href="https://kotlinlang.org/docs/data-classes.html">Kotlin data classes</a></p>
+</li>
+<li>
+<p><a href="https://docs.scala-lang.org/tour/case-classes.html">Scala case classes</a></p>
+</li>
+</ul>
+</div>
+<div class="sect2">
+<h3 id="_reference_implementation">Reference implementation</h3>
+<div class="paragraph">
+<p><a href="https://github.com/apache/groovy/pull/1375" class="bare">https://github.com/apache/groovy/pull/1375</a>
+<a href="https://github.com/apache/groovy/pull/1633" class="bare">https://github.com/apache/groovy/pull/1633</a>
+<a href="https://github.com/apache/groovy/pull/1645" class="bare">https://github.com/apache/groovy/pull/1645</a></p>
+</div>
+</div>
+<div class="sect2">
+<h3 id="_jira_issues">JIRA issues</h3>
+<div class="ulist">
+<ul>
+<li>
+<p><a href="https://issues.apache.org/jira/browse/GROOVY-9754">GROOVY-9754: Provide a record-like equivalent</a></p>
+</li>
+<li>
+<p><a href="https://issues.apache.org/jira/browse/GROOVY-10240">GROOVY-10240: Support record grammar</a></p>
+</li>
+<li>
+<p><a href="https://issues.apache.org/jira/browse/GROOVY-10298">GROOVY-10298: Refine records to not use system properties</a></p>
+</li>
+<li>
+<p><a href="https://issues.apache.org/jira/browse/GROOVY-10338">GROOVY-10338: Enhance records with additional helper methods</a></p>
+</li>
+</ul>
+</div>
+</div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_update_history">Update history</h2>
+<div class="sectionbody">
+<div class="paragraph">
+<p>1 (2021-10-26) Initial draft
+2 (2021-11-06) Update to align with 4.0.0-beta-2</p>
+</div>
+</div>
+</div></div></div></div></div><footer id='footer'>
+                            <div class='row'>
+                                <div class='colset-3-footer'>
+                                    <div class='col-1'>
+                                        <h1>Groovy</h1><ul>
+                                            <li><a href='http://groovy-lang.org/learn.html'>Learn</a></li><li><a href='http://groovy-lang.org/documentation.html'>Documentation</a></li><li><a href='/download.html'>Download</a></li><li><a href='http://groovy-lang.org/support.html'>Support</a></li><li><a href='/'>Contribute</a></li><li><a href='http://groovy-lang.org/ecosystem.html'>Ecosystem</a></li><li><a href='https://groovy.apache.org/events.html'></a></li>
+                                        </ul>
+                                    </div><div class='col-2'>
+                                        <h1>About</h1><ul>
+                                            <li><a href='https://github.com/apache/groovy'>Source code</a></li><li><a href='http://groovy-lang.org/security.html'>Security</a></li><li><a href='http://groovy-lang.org/learn.html#books'>Books</a></li><li><a href='http://groovy-lang.org/thanks.html'>Thanks</a></li><li><a href='http://www.apache.org/foundation/sponsorship.html'>Sponsorship</a></li><li><a href='http://groovy-lang.org/faq.html'>FAQ</a></li><li><a href='http://groovy-lang.org/sea [...]
+                                        </ul>
+                                    </div><div class='col-3'>
+                                        <h1>Socialize</h1><ul>
+                                            <li><a href='http://groovy-lang.org/mailing-lists.html'>Discuss on the mailing-list</a></li><li><a href='https://twitter.com/ApacheGroovy'>Groovy on Twitter</a></li><li><a href='http://groovy-lang.org/events.html'>Events and conferences</a></li><li><a href='https://github.com/apache/groovy'>Source code on GitHub</a></li><li><a href='http://groovy-lang.org/reporting-issues.html'>Report issues in Jira</a></li><li><a href='http://stackoverflow.com [...]
+                                        </ul>
+                                    </div><div class='col-right'>
+                                        <p>
+                                            The Groovy programming language is supported by the <a href='http://www.apache.org'>Apache Software Foundation</a> and the Groovy community.
+                                        </p><div text-align='right'>
+                                            <img src='../img/asf_logo.png' title='The Apache Software Foundation' alt='The Apache Software Foundation' style='width:60%'/>
+                                        </div><p>Apache&reg; and the Apache feather logo are either registered trademarks or trademarks of The Apache Software Foundation.</p>
+                                    </div>
+                                </div><div class='clearfix'>&copy; 2003-2023 the Apache Groovy project &mdash; Groovy is Open Source: <a href='http://www.apache.org/licenses/LICENSE-2.0.html' alt='Apache 2 License'>license</a>, <a href='https://privacy.apache.org/policies/privacy-policy-public.html'>privacy policy</a>.</div>
+                            </div>
+                        </footer></div>
+                </div>
+            </div>
+        </div>
+    </div><script src='../js/vendor/jquery-1.10.2.min.js' defer></script><script src='../js/vendor/classie.js' defer></script><script src='../js/vendor/bootstrap.js' defer></script><script src='../js/vendor/sidebarEffects.js' defer></script><script src='../js/vendor/modernizr-2.6.2.min.js' defer></script><script src='../js/plugins.js' defer></script><script src='https://cdnjs.cloudflare.com/ajax/libs/prettify/r298/prettify.min.js'></script><script>document.addEventListener('DOMContentLoa [...]
+          (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+          (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+          m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+          })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
+
+          ga('create', 'UA-257558-10', 'auto');
+          ga('send', 'pageview');
+    </script>
+</body></html>
\ No newline at end of file