galaaz 0.4.8 → 0.4.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -380,32 +380,59 @@ $(document).ready(function () {
380
380
 
381
381
  <div id="introduction" class="section level1">
382
382
  <h1>Introduction</h1>
383
- <p>The idea of “literate programming” was first introduced by Donald Knuth in the 1980’s. The main intention of this approach was to develop software interspersing macro snippets, traditional source code, and a natural language such as English in a document that could be compiled into executable code and at the same time easily read by a human developer. According to Knuth “The practitioner of literate programming can be regarded as an essayist, whose main concern is with exposition and excellence of style.”</p>
383
+ <p>The idea of “literate programming” was first introduced by Donald Knuth in the 1980’s <span class="citation">(Knuth 1984)</span>. The main intention of this approach was to develop software interspersing macro snippets, traditional source code, and a natural language such as English in a document that could be compiled into executable code and at the same time easily read by a human developer. According to Knuth “The practitioner of literate programming can be regarded as an essayist, whose main concern is with exposition and excellence of style.”</p>
384
384
  <p>The idea of literate programming evolved into the idea of reproducible research, in which all the data, software code, documentation, graphics etc. needed to reproduce the research and its reports could be included in a single document or set of documents that when distributed to peers could be rerun generating the same output and reports.</p>
385
- <p>The R community has put a great deal of effort in reproducible research. In 2002, Sweave was introduced and it allowed mixing R code with Latex generating high quality PDF documents. Those documents could include the code, the result of executing the code, graphics and text. This contained the whole narrative to reproduce the research. But Sweave had many problems and in 2012, Knitr, developed by Yihui Xie from RStudio was released, solving many of the long lasting problems from Sweave and including in one single package many extensions and add-on packages that were necessary for Sweave.</p>
386
- <p>With Knitr, R markdown was also developed, an extension to the Markdown format. With R markdown and Knitr it is possible to generate reports in a multitude of formats such as HTML, markdown, Latex, PDF, dvi, etc. R markdown also allows the use of multiple programming languages in the same document. In R markdown text is interspersed with code chunks that can be executed and both the code and its results can become part of the final report. Although R markdown allows multiple programming languages in the same document, only R and Python (with the reticulate package) can persist variables between chunks. For other languages, such as Ruby, every chunk will start a new process and thus all data is lost between chunks, unless it is somehow stored in a data file that is read by the next chunk.</p>
387
- <p>Being able to persist data between chunks is critical for literate programming otherwise the flow of the narrative is lost by all the effort of having to save data and then reload it. Probably, because of this impossibility, it is very rare to see any R markdown document in the Ruby community. Also, the use of R markdown for the Ruby community would also require the Ruby developer to download R and have some minimal knowledge of Knitr.</p>
388
- <p>In the Python community, the same effort to have code and text in an integrated environment started around the first decade of 2000. In 2006 iPython 0.7.2 was released. In 2014, Fernando Pérez, spun off project Jupyter from iPython creating a web-based interactive computation environment. Jupyter can now be used with many languages, including Ruby with the iruby gem (<a href="https://github.com/SciRuby/iruby" class="uri">https://github.com/SciRuby/iruby</a>). I am not sure if multiple languages can be used in a Jupyter notebook and if variables can persist between chunks.</p>
385
+ <p>The R community has put a great deal of effort in reproducible research. In 2002, Sweave was introduced and it allowed mixing R code with Latex generating high quality PDF documents. A Sweave document could include code, the results of executing the code, graphics and text such that it contained the whole narrative to reproduce the research. In 2012, Knitr, developed by Yihui Xie from RStudio was released to replace Sweave and to consolidate in one single package the many extensions and add-on packages that were necessary for Sweave.</p>
386
+ <p>With Knitr, <strong>R markdown</strong> was also developed, an extension to the Markdown format. With <strong>R markdown</strong> and Knitr it is possible to generate reports in a multitude of formats such as HTML, markdown, Latex, PDF, dvi, etc. <strong>R markdown</strong> also allows the use of multiple programming languages such as R, Ruby, Python, etc. in the same document.</p>
387
+ <p>In <strong>R markdown</strong>, text is interspersed with code chunks that can be executed and both the code and its results can become part of the final report. Although <strong>R markdown</strong> allows multiple programming languages in the same document, only R and Python (with the reticulate package) can persist variables between chunks. For other languages, such as Ruby, every chunk will start a new process and thus all data is lost between chunks, unless it is somehow stored in a data file that is read by the next chunk.</p>
388
+ <p>Being able to persist data between chunks is critical for literate programming otherwise the flow of the narrative is lost by all the effort of having to save data and then reload it. Although this might, at first, seem like a small nuisance, not being able to persist data between chunks is a major issue. For example, let’s take a look at the following simple example in which we want to show how to create a list and the use it. Let’s first assume that data cannot be persisted between chunks. In the next chunk we create a list, then we would need to save it to file, but to save it, we need somehow to marshal the data into a binary format:</p>
389
+ <pre class="ruby"><code>lst = R.list(a: 1, b: 2, c: 3)
390
+ lst.saveRDS(&quot;lst.rds&quot;)</code></pre>
391
+ <p>then, on the next chunk, where variable ‘lst’ is used, we need to read back it’s value</p>
392
+ <pre class="ruby"><code>lst = R.readRDS(&quot;lst.rds&quot;)
393
+ puts lst</code></pre>
394
+ <pre><code>## $a
395
+ ## [1] 1
396
+ ##
397
+ ## $b
398
+ ## [1] 2
399
+ ##
400
+ ## $c
401
+ ## [1] 3</code></pre>
402
+ <p>Now, any single code has dozens of variables that we might want to use and reuse between chunks. Clearly, such an approach becomes quickly unmanageable. Probably, because of this problem, it is very rare to see any <strong>R markdown</strong> document in the Ruby community.</p>
403
+ <p>When variables can be used accross chunks, then no overhead is needed:</p>
404
+ <pre class="ruby"><code>@lst = R.list(a: 1, b: 2, c: 3)
405
+ # any other code can be added here</code></pre>
406
+ <pre class="ruby"><code>puts @lst</code></pre>
407
+ <pre><code>## $a
408
+ ## [1] 1
409
+ ##
410
+ ## $b
411
+ ## [1] 2
412
+ ##
413
+ ## $c
414
+ ## [1] 3</code></pre>
415
+ <p>In the Python community, the same effort to have code and text in an integrated environment started around the first decade of 2000. In 2006 iPython 0.7.2 was released. In 2014, Fernando Pérez, spun off project Jupyter from iPython creating a web-based interactive computation environment. Jupyter can now be used with many languages, including Ruby with the iruby gem (<a href="https://github.com/SciRuby/iruby" class="uri">https://github.com/SciRuby/iruby</a>). In order to have multiple languages in a Jupyter notebook the SoS kernel was developed (<a href="https://vatlab.github.io/sos-docs/" class="uri">https://vatlab.github.io/sos-docs/</a>).</p>
389
416
  </div>
390
417
  <div id="gknitting-a-document" class="section level1">
391
418
  <h1>gKnitting a Document</h1>
392
- <p>This document describes gKnit. gKnit uses Knitr and R markdown to knit a document in Ruby or R and output it in any of the available formats for R markdown.<br />
393
- gKnit runs atop of GraalVM, and Galaaz (an integration library between Ruby and R). In gKnit, Ruby variables are persisted between chunks, making it an ideal solution for literate programming in this language. Also, since it is based on Galaaz, Ruby chunks can have access to R variables and Polyglot Programming with Ruby and R is quite natural.</p>
394
- <p>Galaaz has been describe already in the following posts:</p>
419
+ <p>This document describes gKnit. gKnit is based on knitr and <strong>R markdown</strong> and can knit a document written both in Ruby and/or R and output it in any of the available formats of <strong>R markdown</strong>. gKnit allows ruby developers to do literate programming and reproducible research by allowing them to have in a single document, text and code.</p>
420
+ <p>gKnit runs atop of GraalVM, and Galaaz (an integration library between Ruby and R - see bellow). In gKnit, Ruby variables are persisted between chunks, making it an ideal solution for literate programming in this language. Also, since it is based on Galaaz, Ruby chunks can have access to R variables and Polyglot Programming with Ruby and R is quite natural.</p>
421
+ <p>Galaaz has already been describe in the following posts:</p>
395
422
  <ul>
396
423
  <li><a href="https://towardsdatascience.com/ruby-plotting-with-galaaz-an-example-of-tightly-coupling-ruby-and-r-in-graalvm-520b69e21021" class="uri">https://towardsdatascience.com/ruby-plotting-with-galaaz-an-example-of-tightly-coupling-ruby-and-r-in-graalvm-520b69e21021</a>.<br />
397
424
  </li>
398
425
  <li><a href="https://medium.freecodecamp.org/how-to-make-beautiful-ruby-plots-with-galaaz-320848058857" class="uri">https://medium.freecodecamp.org/how-to-make-beautiful-ruby-plots-with-galaaz-320848058857</a></li>
399
426
  </ul>
400
- <p>This is not a blog post on R markdown, and the interested user is directed to the following links for detailed information on its capabilities and use.</p>
427
+ <p>This is not a blog post on <strong>R markdown</strong>, and the interested user is directed to the following links for detailed information on its capabilities and use.</p>
401
428
  <ul>
402
429
  <li><a href="https://rmarkdown.rstudio.com/" class="uri">https://rmarkdown.rstudio.com/</a> or</li>
403
430
  <li><a href="https://bookdown.org/yihui/rmarkdown/" class="uri">https://bookdown.org/yihui/rmarkdown/</a></li>
404
431
  </ul>
405
- <p>Here, we will describe quickly the main aspects of R markdown, so the user can start gKnitting Ruby and R documents quickly.</p>
432
+ <p>In this post, we will describe just the main aspects of <strong>R markdown</strong>, so the user can start gKnitting Ruby and R documents quickly.</p>
406
433
  <div id="the-yaml-header" class="section level2">
407
434
  <h2>The Yaml header</h2>
408
- <p>An R markdown document should start with a Yaml header and be stored in a file with ‘.Rmd’ extension. This document has the following header for gKitting an HTML document.</p>
435
+ <p>An <strong>R markdown</strong> document should start with a Yaml header and be stored in a file with ‘.Rmd’ extension. This document has the following header for gKitting an HTML document.</p>
409
436
  <pre><code>---
410
437
  title: &quot;How to do reproducible research in Ruby with gKnit&quot;
411
438
  author:
@@ -425,7 +452,7 @@ output:
425
452
  <p>For more information on the options in the Yaml header, check <a href="https://bookdown.org/yihui/rmarkdown/html-document.html" class="uri">https://bookdown.org/yihui/rmarkdown/html-document.html</a>.</p>
426
453
  </div>
427
454
  <div id="r-markdown-formatting" class="section level2">
428
- <h2>R Markdown formatting</h2>
455
+ <h2><strong>R Markdown</strong> formatting</h2>
429
456
  <p>Document formatting can be done with simple markups such as:</p>
430
457
  <div id="headers" class="section level3">
431
458
  <h3>Headers</h3>
@@ -451,7 +478,7 @@ output:
451
478
  3. Item 3
452
479
  + Item 3a
453
480
  + Item 3b</code></pre>
454
- <p>Please, go to <a href="https://rmarkdown.rstudio.com/authoring_basics.html" class="uri">https://rmarkdown.rstudio.com/authoring_basics.html</a>, for more R markdown formatting.</p>
481
+ <p>For more R markdown formatting go to <a href="https://rmarkdown.rstudio.com/authoring_basics.html" class="uri">https://rmarkdown.rstudio.com/authoring_basics.html</a>.</p>
455
482
  </div>
456
483
  <div id="r-chunks" class="section level3">
457
484
  <h3>R chunks</h3>
@@ -459,12 +486,12 @@ output:
459
486
  Inserting a code chunk is done by adding code in a block delimited by three back ticks followed by an open curly brace (‘{’) followed with the engine name (r, ruby, rb, include, …), an any optional chunk_label and options, as shown bellow:</p>
460
487
  <pre><code>```{engine_name [chunk_label], [chunk_options]}
461
488
  ```</code></pre>
462
- <p>for instance, let’s add an R chunk to the document labeled ‘first_r_chunk’. This is a very simple code just to create a variable and print it out. The code block should be defined as follows:</p>
489
+ <p>for instance, let’s add an R chunk to the document labeled ‘first_r_chunk’. This is a very simple code just to create a variable and print it out, as follows:</p>
463
490
  <pre><code>```{r first_r_chunk}
464
491
  vec &lt;- c(1, 2, 3)
465
492
  print(vec)
466
493
  ```</code></pre>
467
- <p>If this block is added to an R markdown document and gKnitted the result will be:</p>
494
+ <p>If this block is added to an <strong>R markdown</strong> document and gKnitted the result will be:</p>
468
495
  <pre class="r"><code>vec &lt;- c(1, 2, 3)
469
496
  print(vec)</code></pre>
470
497
  <pre><code>## [1] 1 2 3</code></pre>
@@ -476,8 +503,8 @@ print(vec3)
476
503
  ```</code></pre>
477
504
  <p>Here is how this block will show up in the document. Observe that the code is not shown and we only see the execution result in a white box</p>
478
505
  <pre><code>## [1] 10 40 90</code></pre>
479
- <p>A description of the available chunk options can be found in the documentation cited above.</p>
480
- <p>Let’s add another R chunkd with a function definition. In this example, a vector ‘r_vec’ is created and a new function ‘reduce_sum’ is defined. The chunk specification is</p>
506
+ <p>A description of the available chunk options can be found in <a href="https://yihui.name/knitr/" class="uri">https://yihui.name/knitr/</a>.</p>
507
+ <p>Let’s add another R chunk with a function definition. In this example, a vector ‘r_vec’ is created and a new function ‘reduce_sum’ is defined. The chunk specification is</p>
481
508
  <pre><code>```{r data_creation}
482
509
  r_vec &lt;- c(1, 2, 3, 4, 5)
483
510
 
@@ -485,7 +512,7 @@ reduce_sum &lt;- function(...) {
485
512
  Reduce(sum, as.list(...))
486
513
  }
487
514
  ```</code></pre>
488
- <p>and this is how it will look like once executed. From now on, we will not show the chunk definition any longer.</p>
515
+ <p>and this is how it will look like once executed. From now on, to be concise in the presentation we will not show chunk definitions any longer.</p>
489
516
  <pre class="r"><code>r_vec &lt;- c(1, 2, 3, 4, 5)
490
517
 
491
518
  reduce_sum &lt;- function(...) {
@@ -500,10 +527,12 @@ reduce_sum &lt;- function(...) {
500
527
  <div id="r-graphics-with-ggplot" class="section level3">
501
528
  <h3>R Graphics with ggplot</h3>
502
529
  <p>In the following chunk, we create a bubble chart in R using ggplot and include it in this document. Note that there is no directive in the code to include the image, this occurs automatically. The ‘mpg’ dataframe is natively available to R and to Galaaz as well.</p>
530
+ <p>For the reader not knowledgeable of ggplot, ggplot is a graphics library based on “the grammar of graphics” <span class="citation">(Wilkinson 2005)</span>. The idea of the grammar of graphics is to build a graphics by adding layers to the plot. More information can be found in <a href="https://towardsdatascience.com/a-comprehensive-guide-to-the-grammar-of-graphics-for-effective-visualization-of-multi-dimensional-1f92b4ed4149" class="uri">https://towardsdatascience.com/a-comprehensive-guide-to-the-grammar-of-graphics-for-effective-visualization-of-multi-dimensional-1f92b4ed4149</a>.</p>
531
+ <p>In the plot bellow the ‘mpg’ dataset from base R is used. “The data concerns city-cycle fuel consumption in miles per gallon, to be predicted in terms of 3 multivalued discrete and 5 continuous attributes.” (Quinlan, 1993)</p>
532
+ <p>First, the ‘mpg’ dataset if filtered to extract only cars from the following manumactures: Audi, Ford, Honda, and Hyundai and stored in the ‘mpg_select’ variable. Then, the selected dataframe is passed to the ggplot function specifying in the aesthetic method (aes) that ‘displacement’ (disp) should be plotted in the ‘x’ axis and ‘city mileage’ should be on the ‘y’ axis. In the ‘labs’ layer we pass the ‘title’ and ‘subtitle’ for the plot. To the basic plot ‘g’, geom_jitter is added, that plots cars from the same manufactures with the same color (col=manufactures) and the size of the car point equal its high way consumption (size = hwy). Finally, a last layer is plotter containing a linear regression line (method = “lm”) for every manufacturer.</p>
503
533
  <pre class="r"><code># load package and data
504
534
  library(ggplot2)
505
535
  data(mpg, package=&quot;ggplot2&quot;)
506
- # mpg &lt;- read.csv(&quot;http://goo.gl/uEeRGu&quot;)
507
536
 
508
537
  mpg_select &lt;- mpg[mpg$manufacturer %in% c(&quot;audi&quot;, &quot;ford&quot;, &quot;honda&quot;, &quot;hyundai&quot;), ]
509
538
 
@@ -515,16 +544,16 @@ g &lt;- ggplot(mpg_select, aes(displ, cty)) +
515
544
 
516
545
  g + geom_jitter(aes(col=manufacturer, size=hwy)) +
517
546
  geom_smooth(aes(col=manufacturer), method=&quot;lm&quot;, se=F)</code></pre>
518
- <p><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAqAAAAHgCAIAAAD17khjAABeiklEQVR42u2dC1xUZf7/MVHxsi6RaSWpa/5afuVfLd1d3ai0n7WuZsuqpWtUZrVZr9rSxUuApqZppOYttdTVak1KE0rF+x2ROwqKIeENlPtNYIZhYPg/eGyahpkzZ4YBZob353VevM4cnjmXz5zzfZ/vc57zPG61CCGEEHI5uWEBQgghBOARQgghBOARQgghBOARQgghBOARQgghBOARQgghAI8QQgghAI8QQgghAI8QQgghAG+H47ypRi3QqLuHEEIIuRrg3QzUtm1bHx+fjz76qKamBsBz34AQQshFAK/XjBkzADyARwgh5PSAl+YrKipCQkLExy5dugB4AI8QQshFAC+k0WjERw8PD3mSGS2RPt64cePll1/u3Llzp06d/Pz8Ll26ZG0Bw0189dVXjz/++G9/+9u2bdved99906dPLykpkTkQrVa7fPnygQMHduzYsX379uK7P/zwg9HWX3jhhQ4dOtxxxx0zZ87U6XT67+7fv3/UqFFiW+KLQ4YMOXjwYP2DLSsre/311728vFq3bm2y5oPTHSGEALyDAl6lUi1dulR8FLSzAfDPPPOMIfC8vb0LCwutKiDNC/ROnDixPkEffPDB0tJSk0dRVVX11FNPmYOuNC9uKQz/tWrVKqP916tNmzbx8fEyRwfgEUIIwDsH4A3b2b344ot5eXk2AF7k2TExMRqNJjo6+ne/+53hs3yFBaT59evXi3lRIDw8XGTtAt4Ct4888ohYKDJvk0exZMkS8d/f/OY34rsFBQViE1FRUYLohiv/05/+lJ6eXlFR8fbbb4uPgwYN0n993LhxCQkJ4luZmZkTJkwQ/xV/jY6uR48ehw4dEmVkbEEIIQTgHRTwQt27d//0009tAPy+ffv0S/bs2SOW/O///q9VBaR5QWIxHxsba7jFrKwssfB//ud/TB5F//79xX//+9//yhxjUlKS9DE3N1d87Nixo8nCxcXF4r/33nuv0dcjIiJkKj8QQggBeEcEvDSv1WrPnz//97//XSxZtmyZtYBXqVT6JSJRNnyWr7CANN+hQwc3M2rTpo3Jo2jfvr30mFzmGKurq03uv1j+8ccfDxgwwHC7bdu2NSosdhjAI4QQckrASyooKJAekJsrI4jYqICXaG1ONgPe3JKpU6fKb8jcdgE8QggBeOcDfLt27fRLpNQ2NzdX+piYmNioVfSDBg0S8ykpKcqPQuTf4itbtmyxAfBeXl5iPjQ0tKSkRKfTlZaWKgR8q1atxHLD1vgIIYQAvCMCXqTmP/74o1RF//DDD+vLDBw4UCz517/+JVLw9PR06Rl5fQT26dMnJiamqqoqOjq6d+/e9dvQWSwgzf/nP/+RGrV98cUXV69e1Wq1lZWVaWlpn3/++ZAhQ0wehdT4/7e//a34bmFhoUajOXXqlFEjO3NHLWX/4eHhYisZGRnjx49XCPg77rhDLD98+DCMRwghAO+ggDeSu7u7yLD1ZVatWmX437/97W8mETh69Gj5t+AsFtCvUGrorryKXtw0/N///Z/8a3LmAC/d0Oj19NNPKwT8uHHjeE0OIYQAvBMAvnXr1nfffffYsWNFhm1YRmSoM2fOFAnrb37zmxdeeOHGjRsmEVhaWjp58uTbb7+9Y8eO4ibg4sWL1hYw3OjBgwcFQbt3796mTRuRZD/44INvvvlmTEyMuQMRjP/444/79evn4eEh1j906FCjjm7MAT4/P3/MmDEdOnTw9PScNGlSSUmJQsBfu3ZNeOXl5SXV1XO6I4QQgEcIIYQQgEcIIYQQgEcIIYQQgEcIIYQQgEcIIYQAPBYghBBCAB4hhBBCAB4hhBBCAB4hhBBCAB4hhBBCAB4hhBAC8AghhBAC8AghhBAC8AghhBAC8AghhBAC8AghhBCAR/IG/awOHTr07t37ueeei4iIMCrQkJXjsIz27t07atSoLl26uLu7d+vWbcyYMQcOHLCLb2INI0eONPkvsVy//vozCCEE4F0H8NJMZWXlpUuXNm/e7OPj88orr7RwwDfBns+ePfvhhx/euXNnUVFRVVVVXFzc2LFjpe02nLvii927d09KSjJaLpaI5QAeIQTgWxDg9SovL+/Xr99XX33lFJh0UsDv27evf//+KpXKaPmHH35ol90QX/z000+fffZZo+Xjxo1bs2ZN/dUCeIQQgLc/SLZs2TJo0KD27dt37Nhx+PDhKSkpERERf/7znzt06CCW/P3vf8/Ly9MXXrduXZ8+fdq0adO7d+9NmzYZruqzzz7r1auX+JcoIIoZhmyZ8G3yX999990TTzxhVCA1NfWvf/1r586d27ZtK1LP0NBQi3tluPKcnJw33nhDHGbXrl3ffPPNiooK/b++//77gQMHtmvXrkePHhs2bDBcPmDAALG5nj17Gi63yjSL63nooYfEpsVxiQRa+pbbr2VkTmFh4R133CH+Gi3s0qWL+GvOJSM9/fTTwmT5H6X+bvj6+oaFhRmWzM/Pv/322412RvquRqMRP8ePP/6oX3j+/HmxpKqqSj6DN2eX/I8oc/rJrBAhhFwZ8H379j1x4oQIxwUFBa+//rqXl5fI7Y4fP15ZWSktGTNmjL7wfffdFxMTIwpHR0eLYL1jxw7pXwIkIrBK/xJ/RbGGAF5wTuyGUQEfH59Vq1aVlpZKm1CyV4Yr7969++bNm9VqdVZWlr+//9tvvy0t37Vrl7e394EDB8Txpqenv/DCC9LyvXv3CnSJVYnlZ86cuf/++8PDw20wTX49/fr1i4yMFOsRh/zyyy/7+fkpyWhfe+21RYsWGWXeYqGMS0YSdwOGtyDmfhSj3dizZ89jjz1muGThwoWGz1OM1rBx48aXXnpJv/DFF1/8z3/+Y3L9+hkZu2R+RJnTT36FCCHkyoA/e/as/mNRUZFYcu7cOcMlnTp10hfet2+fYbgfPHiwNP/HP/5x//79+n+JYgorXU0W02q17u7uRgU8PDxEWDe5BnN7ZW4fbty4cffdd0vzQ4YM2blzZ/0yjz76qP5GQSguLk7A2AbT5NcjEm7Db4nsXwngU1JSxE2JSIWlj2JGkE8slHHJSMJeYbK1gBcaOHBgQkKC/mcSu3H69Glza6iurn7ggQcuXbok5sVfMS+WyANexi6ZH1Hm9FO+QoQQcjXA63Q6i0v0M4ZPbSsqKtq3b6+nr9G/GgL43NxckWIaFZg6dWrXrl3feOMNkcNlZmYarsHcXum/K1Y4efJkQcHWrVtLFc633Xab9C9R2LCmV68OHToY1VHrv2KVadauRwnghZ544oktW7ZI8//973/1TzTMuVQ/g8/Pz7cB8Nu3bxepszT/zTff+Pr6yq9B7KTYGTEzZcqUr7/+2tz6ldgl8yPKnH4yK0QIIRcHvPIlTQZ4QZHhw4fXLyByx5CQkOeee87Ly0tfR60E8MOGDfvXv/6VlpamVqullFf/L3OAF0dUVlbWcNNsW49F98LDw//whz9I84MGDfr+++/lXTLSqFGjLD6DN7kb4o6kf//+165dE/OPPPKIYLz8GmpqakTSHx8fL3ZSzFsEvIxdMj+izOkns0KEEALwv0RhmSp66RVqSfv377cZ8OXl5f/v//2/rVu3yqDu4sWLIjOzuFf677Zp00aiQv3dGzJkyK5du+pvQtDr6NGjDTfNtvW0atXKKLk3koDl7373u8jIyBMnTvTu3VvPTnMuGUm4NGDAAHOt6OV348svvwwMDBS3ESKZNlfPb3ho4k5C3GoY1pPLAF7GLpkfUeb0k1khQggB+F+isNSUSSRPUnM2kWpL/woNDf2f//mfuLg46Y1qMW9tIzuNRnP58uUvvvjCx8fn9ddfr19gxIgRInAL/IuE7PPPP3/wwQct7pX+uyKJnDNnTmFhoUDaDz/8cPfdd+v/JT7ee++9hw4dEjtg2Mju4MGDIumMioqqrKwUGxUf9T23WGWabevx9vY+fPiwPOOXLl06duzYMWPGLFu2TL/QnEv1JSAtbBE3NyUlJebegze5GwLq4oieffbZ+fPnW1UxowTwMnbJ/Igyp5/MChFCCMD/EoXXrl173333ubu7i/Rx48aNhsXWrVvXs2dP6T2l1atXt23bViHgJbVv316s87nnnhPJpcmt7969+/HHH5feKBs1alRaWprFvdJ/V5D7ySef9PDwEF/v37+/uI0wSjGl16h69epl+HWR+Q0bNqxjx45i34YOHapP9K0yzbb1fPXVVyI/Fgm0jHUCzL+9KTGjX2jOJZOKiIj461//escdd+h7shP8U7Iba9asEXbl5OTYHfAydsn/iDKnn7kVIoSQKwO+gXcD5pSQkCAScUfbK2QvLVy4UN/UzgHVlKcfQgjAuz7gRcS/cOGCVqtNSkoaOHBgSEgIgHdJRUZGdu3a9fLlyw61V811+iGEALzrA37z5s19+vRxd3fv2bPnvHnzTDb7AvAucA7cc889u3fvdrQda67TDyEE4BFCCCEE4BFCCCEE4BFCCCEE4BFCCCEE4BFCCCEE4BFCCCEAjxBCCCEAbz8lJSXNRQgh5PC6dOkSNAXwVuif//znU0899U8FevXVV1977bV/OoMmT578yiuvOMWuOpGrGIuxGNuMxg4dOlQwHpoCeOsAr/CkqaysrKqqcgq7S0pKnGXwbydyFWMxFmOb0VjlsRoBeABPuMRYjMVYAI8APIAnXGIsxmIsgEcAnquacImxGIuxAB7AA3iuasIlxmIsxgJ4AA/gCZcYi7EYC+ARgAfwhEuMxViMBfAIwFtx/qlrajZczxl39rxPTEKvU3F9YxP9U9NCc/O1Oh1XNeESYzEWYwE8gHdKwIfnF951MtbtSGT9qU90/ImSUq5qwiXGYizGAngA72SAX3I1yyTa9ZP70ZMileeqJlxiLMZirOMA3s2NgVEAvOz5J8gtT3c945srjydcYizGYiyAB/AA3jrAF2u1nieilQBeqqtvlufxhEuMxViMBfAAHsBbB/jFVzIV0l2amqWinnCJsRiLsQDeJOC3bNny0EMPtWvXrnPnzmPHjs3LyxPLP/roo2eeeUZf7MaNG97e3obWDRgwIDo62tfXNywszHCF+fn5t99+e2FhIYB3BcD7JiZbBXj/1DSuasIlxmIsxjoI4Pv16xcZGanRaATaX375ZT8/P7H84sWLHh4egutSsVWrVnXo0OHTTz+VPl65cuWee+7R6XR79ux57LHHDFe4cOHCV155hQzeRQDf6fgpqwDfNzaRq5pwibEYi7EOAvjU1FT9x6Kioo4dO0rzDz/88NatW8WMALmPj8/27dsfeOABPe/feOMNaX7gwIEJCQnSvFarFYn+6dOnAbyLAN4quovJOyqWq5pwibEYi7EOAnjdr9tF6Z/KL1q0aOzYsWJm7969TzzxhJgZNmzYgQMHxMyTTz65b98+qZgAv7+/vzT/zTff+Pr61rZ4uQ7gPY5FWQV4n5gErmrCJcZiLMY6CODNLUlPT+/QoUNFRcWoUaO+++47ieXPPPNMaWlp165d9fsm7g/69+9/7do1Mf/II48IxgN41wH8oPjTVgF+3NnzXNWES4zFWIx1cMDX3mxJt3jx4h49elRXV9ferIEX8x999NHEiRMNv/Lll18GBgYmJCR0795dlAHwrgP44ItXrAL8hus5XNWES4zFWIx1fMAvWLDA3d39gw8+0C+ZP39+mzZttm3bZvgVAfVBgwY9++yz4r/Q3aUAn63RKK+lv+tkrLqmhquacImxGIuxjg/4tLS0tm3b5uT8kpVlZ2d37ty5vodr1qwxKgngXQHwYmZ55jWFgA/PL+SqJlxiLMZirIMA3l5auHChvqkdcrW+6N+6kGGR7kuuZnFVEy4xFmMx1sUAHxkZ2bVr18uXL4N21wS8lMebq6v3PBHdjCPNEC4xFmMxFsA3Fszc3O65557du3fDdVcGvFC2RhN88cqg+NMS6TsdP+WbmLz4SmZxc7erJFxiLMZiLIBHAN52wHNVEy4xFmMxFsADeADPVU24xFiMxVgAD+ABPFc1xmIsxmIsgAfwAJ5wibEYi7EAHgH4X500c+bMqVKgiooKlUpV5QwqLi4uLS11il11IlcxFmMxthmNBfAA3hbAz549u1KBysvLxSlY6QwqKioSd+5OsatO5CrGYizGNqOxAB7AU0VPhSfGYizGUkWPADyAJ1xiLMZiLIBHAB7AEy4xFmMxFsAjAM9VTbjEWIzFWAAP4AE8VzXGYizGYiyAB/AAnnCJsRiLsQAeAXgAT7jEWIzFWACPADyAJ1xiLMZiLIBHAJ6rmnCJsRiLsQAewAN4rmrCJcZiLMYCeAAP4AmXGIuxGAvgATyAB/CES4zFWIwF8I4Cv59lbrnJ/wJ4AE+4xFiMxVgA7xyYt7gEwAN4wiXGYizGAngAD+ABPOESYzEWYwG8lcrMzAwICOjbt6/YYnFxcSMB3svLq02bNvfff/+HH35YXV0N4AE84RJjMRZjAXzjatKkSfqn43bZqLl8XXD9zJkzw4YNe/fddwE8gCdcYizGYiyAb1x16tRJD3gfH5/GA7yk7OxsT09PAA/gCZcYi7EYC+AbV+PGjdMDPiAgoLEBn5ub27lzZwAP4AmXGIuxGAvgG1cpKSmC8SKPnzRpUmZmZmMAfsKECWIrWq32p59+Gjly5OTJkwG8awL+VOmNd9MvDk440+tUnJh8E5ODL15JKa/gqiZcYizGYmzTA96e8DPzvvu3337br18/d3f37t27T506VaVSAXhXA3y6Sj389Fm3I5EmpwnnfszWaAiXhEuMxViMpSc7AO9MgD9RUtolMsYc3aVJJPTnK1Qt+aomXGIsxmIsgAfwzgR4gW3PE9HydNcz3to8nnBJuMRYjAXwCMA3D+AHJ5xRQnd9XT3hknCJsRgL4KEpgHd0wO8qKFJOd2myqs0d4ZJwibEYC+ARgG8GwPunplkL+OCLVwiXhEuMxVgAjwC8QwPeOyrWWsD7JiYTLgmXGIuxAB4BeIcGvLV0l5raES4JlxiLsQAeAXhXA7xI+gmXhEuMxVgAjwC8QwP+rpNWV9EPTjhDuCRcYizGAngE4B0a8H4p560F/LvpFwmXhEuMxVgAjwC8QwM+NDffWsCfKr1BuCRcYizGAngE4B0a8FqdzicmQTndh58+S7gkXGIsxgJ4aArgHR3wtTdHkPM4FqWE7l0iY9JVasIl4RJjMRbAQ1MA7wSAF9qeV2CR8Z4nok+UlBIuCZcYi7EAHsADeKcBvJTHy9TVD044Y8NQcoRLwiXGYiyARwC+mQFfe/N5fGhuvl/Kef27c95Rsf6pabsKiriqCZcYi7EYC+ABvLMCnquacImxGIuxAB7AA3jCJcZiLMYCeATgATzhEmMxFmMBPALwAJ5wibEYi7EAHgF4rmrCJcZiLMa6FOCLi4uDg4OHDx/eq1evvn37LliwQK1W16LmAnxCQkJQUNDYsWMnTpy4dOlScUJLy0f/WgCecImxGIuxAF5GR44c8fb2dvu1fHx8UlJSbF7nnj17nnjiCQ8PDy8vr+effz43N1dartPpZsyY4enpefvtt8+aNUt8BPAmNHv27Pj4eHGTJU7ltWvXCtjrAd/0Gfzm7NxL6soGHlG2RrM889rTyak+MQm9TsX1jU30Szm/4XpOsVZLuCRcYizGAvjGUH5+fpcuXdxMSTDe5jz+ySefjIiIEL+CQPubb74pYC8tX7du3eDBg6/dlJhZv349gLd8iowZM6YZAS+9yG4z47U6XfDFK+a6t/M8ES3AT7gkXGIsxgJ4u+vVV191M6/Fixc3fBMVFRXt2rWT5ocMGXLo0CFpXsw88sgjAN6CoqOjp0+frgf8xIkT/fz8pkyZsm3btpqaGjsCXl1TI1LqcWfP65Ns/9S0cWd/lEg8K+OybYn74IQzFrumF5l9WXU14ZJwibEYC+DtqE6dOskA/umnn274JsLDwwXXpfnOnTuXlpbqfyZPT08AL6eMjIyXX35Z/DVcKLh+6dKlwMBAowqQuT/rqaeeCgoKKlMg8RuI30PMhGZe6xYZI4/haecvnCssKlOs/NLSh2MTFQ4uNyIxWX5thYWFRUVWbL0ZpXfVKYSxGIuxzWVsYwPeTVbe3t4NXH9SUpJYifgrfbztttv0aaeYad26NYA3q+TkZEH3s2dND6sqTvEJEyYY3QxKGjp0qMB/iQKJlRQXFy+48JPyYV6T8/JLlOmNs+etGh5+cXqGzNoKCgrEhV3iDJJcLXESYSzGYmxzGdvYgO/Tp48M4H18fBqycqn53rFjx/RLyOCV6vjx4y+99FJaWppMPdX48eMbXkW/5XqOVRhWWFefrlK7Hz1p1Zo9T0TLtLmjwpMKT4zFWKrorZK/v78M4AMCAmxec2ho6D333BMTE2O4kGfwihQWFjZ58uSrV68aLQ8JCbl8+XJ1dXV2dva8efNWrFjRwJMmp7xcYNUqDEuMt9jmLvjiFWtXK6YN13MIl4RLjMVYAG8XXbp0ydxjeJF8FxcX27bapUuX9ujRIzU11Wj52rVrBeOlVvRihlb0pjW6nqT3GSIjI99++20/P79JkyZt2LBBo9E08KRZkHHJBgwraVc/IC7JhnX6pZwnXBIuMRZjAby9JFLt+ozv0qXLkSNHbIdfPUm/iE6nmz59uudNzZw5k/fgG0XKT5o/x5+2CsA9omIV1tV3On7KBsD3jU0kXBIuMRZjAbx98/hx48Z5eHgIEvft23fKlCn5+fm1yOUBby2GH4xNXJ11Xf9R5hV222oFvKNiCZeES4zFWACPAHxDTxobAKzV6cYZNI83x3hzPdvITz4xCYRLwiXGYiyARwC+oSeNtRiWAKyE8Q8qfgPeqMcbwiXhEmMxFsAjAN/Qk2aglU3hBNelL8ozPlujuftkrA2Al6nzJ1wSLjEWYwE8AvBKT5r30i/a/BqbOcara2oGWdl2T5o8jkVlm3kvgHBJuMRYjAXwCMBbcdJcKStTXkvveSLaqMd4k4x/18qbBv0UfPEK4ZJwibEYC+ARgLfDSSPOv6WXrypncJ/o+BMlpTKMD7542doO7KRpcMIZrexLk4RLwiXGYiyARwDeutHk/nLmnHISC36H5ubLMN6GqdepOJnKecIl4RJjMRbAIwBvNeDzVCpre6sVjJfP462dRptvPE+4JFxiLMYCeATgbQH8wouXbUByn+h4oxp18XGENTUBCjuwI1wSLjEWYwE8AvC2AP6RhDO2Udmool5oV0GR3TuwI1wSLjEWYwE8AvC2AN62TuPF5J9qPJStSOLbHrVzB3aES8IlxmIsgEcA3hbA2/zg3GS9el97d2BHuCRcYizGAngE4G0BvG2dxpurV7ftJXiZDuwIl4RLjMVYAI8AvC2AH2jTwO3m6tWTysrt24Ed4ZJwibEYC+ARgLcF8IE/XbIN8Pp+6Y3kn5pmxw7sCJeES4zFWACPALwtgL9aXm5bLb1hv/SGKtZq+0TH26sDO8Il4RJjMRbAIwBvC+DF+bc885q1dL/rZKy6psbcas9XqJQwflD8aSWV84RLwiXGYiyARwDeFsCLmbcuZFgF+PD8Qvk1izxepq7e/ejJd9MvytwiEC4JlxiLsQAeAXg7AF5I5PEK6+qXXM1SuCdJZeUC5H1jEw3fj/9zQnK6Sk24JFxiLMYC+CYAfHFx8eLFi319fXvd1PDhw1evXq1Wq2tRywG8ULZGE3zxyr1RsTIjxtbvwE6JtDrd6qzr+vXMyrh8SV1JuCRcYizGAvhG3Yfw8HBPT0+3evL29j5x4oRt69yzZ88TTzzh4eHh5eX1/PPP5+bm3oLirwXgHQvwQiK3FowfGJ8kWN7u2MnbjtSN/drx+CnfxOTFVzKLtVqb96r+gDRWMZ5wSbjEWIwF8FYpNDTUzbzc3d1tY/yTTz4ZEREhfgWB9jfffFPAXg94MngHBbwA8FsXMkyO5u5xLGrB5cyG75gR40UeT7gkXGIsxgL4xlB2dnanTp3cZCXy+AbW1VdUVLRr1w7AOzTgBXqHJqVY2/m8bYy3ra6ecEm4xFiMBfDKFRAQ4KZAq1evbshWwsPDhwwZoge8l5dXmzZt7r///g8//LC6uhrAOwTgX/0xXUnzusbI4xXW1RMuCZcYi7EAXrn69OmjBPDDhw+3eRNJSUne3t7ir+FCwfUzZ84MGzbs3XffBfDND3jl/csq7FbWWsYrqasnXBIuMRZjAbwViFKmXr162bb+I0eOCLofO3bM5H+zs7M9PT0BfPMDXmH6bsckvrZeXb3F8WYIl4RLjMVYAG93wAtI27Dy0NDQe+65JyYmxlyB3Nzczp07A/jmB3yvU3HKAT80KcVe+2mUx8sznnBJuMRYjAXwyiXIrQTwvr6+1q556dKlPXr0SE01HuZ7woQJKSkpWq32p59+Gjly5OTJkwF88wPeqj7sxN2AHXdVOeMJl4RLjMVYAK9cU6ZMUQL4xYsXN7xuQPpFvv322379+rm7u3fv3n3q1KkqlQrAOxngTQ4D3wSMJ1wSLjEWYwG8cqWnpwvWytPd09OzuLi4Frkw4O86Gasc8IMTzth9h5UwnnBJuMRYjAXwVmn58uXygA8PD4flLg54q0ZwVzh8u90ZT7gkXGIsxgJ4GxhvMo/v1KlTaGgoIHd9wB8pLlFId/ejJ20YJ8YujCdcEi4xFmMBvA1KT0+fMmWKvs1dnz59AgICsrOzoXiLALyYeTo5VQng37qQ0ah7LsN4wiXhEmMxFsAjAG814Muqq31iEiy+ICcA3Ng7b8T4pLJywiXhEmMxFsAjAG8j4CXGy+Txr/6Y3gR01zN+xJlzRnk84ZJwibEYC+ARgLd9uNgjxSX+qWn6dvW9TsUJtOvT6CbTroIiw9sLwXjCJeESYzEWwCMAbzvgHUQiiReMN8zjT2TnEC4JlxiLsQAeAfi5LnBhG9XVnyssIlwSLjEWYwE8AvCucGEb1tWvu3TFNa5qwiXGYizGAngA39IBbzjoHOGScImxGAvgEYCf6zIXtvQ8ftb5C4RLwiXGYiyARy0d8HPmzKlSoIqKCpVKVeUMKi4uLi0tdYpddSJXMRZjMbYZjQXwAN4WwM+ePbtSgcrLy8UpWOkMKioqEnfuTrGrTuQqxmIsxjajsQAewLf0KnoqPDEWYzGWKnoE4AE84RJjMRZjATwC8ACecImxGIuxAB4BeK5qwiXGYizGAngAD+C5qjEWYzEWY5sZ8Gq1esOGDePGjfPx8enVq1ffvn39/f1DQ0O1Wi0gB/Bc1YRLjMVYjHVKwIeHh991111uptSnT58TJ07AcgDPVU24xFiMxVgnA/ySJUvcZOXu7i5SeXAO4LmqCZcYi7EY6zSAF+R2UyDBeGvz+N27dz/22GPt2rXz8vIaP358VlaWtFyn082YMcPT0/P222+fNWuW+AjgATzhEmMxFmMBvD1VXFwsQOumTH369LHqefywYcN27NghNnHjxo0FCxYMGTJEWr5u3brBgwdfuykxs379egAP4AmXGIuxGAvg7anFixe7WSObK+pVKpWHh4c0L0h/6NAhaV7MPPLIIwAewBMuMRZjMRbA21O+vr5WAd7f39+GrZSXly9atGjUqFHSx86dO5eWlup/Jk9PTwAP4AmXGIuxGAvg7alOnTpZBfi+fftajcCb6tq1a3p6urTktttuq6mpkebFTOvWrQE8gCdcYizGYiyAtyufrJS3t7cNWxH5+vz58x999FEyeADPVY2xGIuxGNsUgPfw8LAK8D4+PrZtSKVStWvXTprnGTyA56rGWIzFWIxtXMAPGjTIKsCPGzdO+cpfeOGF1NRUrVabnZ09bdq0oUOHSsvXrl0rGC+1ohcztKIH8IRLjMVYjAXwdlZwcLBVgN+wYYPylX/77bf9+vVzd3fv2rXrSy+9lJubKy3X6XTTp0/3vKmZM2fyHjyAJ1xiLMZiLIC3s0RurbyW/q677lKr1bUIwLfwq1pdWHv1YG3KZ7WJS+qmcxtrs47WVpURLuEQxmKsAwFeaPny5QoBHx4eDtEBvCLpCvK0+3ZVrV6qWfS+mKrWraw+tE93o9TZr2pdTe2lnbXRc2pPBRtPMXPrME+4hEMYi7GOA3iht956yyLdlyxZAs4BvALV1GjDt1XOeqdyxtvGU+A0gXnnvaoF3UWyXh/thlP6NsIlHMJYjHUgwEt5vLm6ek9PT0aaAfBK6S6SdRNoN5i0W7900qs6I8wC3aVJyuMJl3AIYzG21mHGg8/Ozg4ODh40aJBE+k6dOvn6+i5evLi4uBiQA3hF0m7/Wp7u0mRzHt+MV3X5dUV0l+rqq8oIl3AIYzHWgQCPAHyDpLuWpYTuUl29wufxRs/yVauXqfbsbPiz/MZL3/VJPOESDmEsxgJ4AO8igFeYvitN4hvzWb4NSlxiBeDPbSRcwiGMxVgAD+BdBfAiw1YO+Kp1K+Xp3qjP8m2QcrqLSdwNEC7hEMZiLIAH8C4CeOV0F5O4G7C5MuDc3MD31n/+x7Dvex053utU3NCklAWXM7M1GscBfEII4RIOYSzGAngA3zIBv3C2ufXIPMsvn/mvNzZvcj98wu1IpNHkcSxKYL4xnKzR1ubG10bPtQLwKZ8RLuEQxmIsgAfwrgJ4zQdBVlTRr15qbfou6P7Ydzvqo91w8k9Ns6+NRam18YutS9/FdPUg4RIOYSzGAngA7yqA1279Ujngtft2mb1RMPMs/+Uvv5SnuzTZMY+/Hmk12sUUPaeuL1vCJRzCWIwF8ADeRQBfk3FBKeBnvaMryDO7P6a+ErNgthK6S3X1dnkeX5BsC93FdGkn4RIOYSzGAngA70KAF6ra9Jmi9D18m9z+NCB9t1cSr1XXxi2whe7nNtb1aEu4hEMYi7EAHsC7FOBrNZWajxdYfkGupkZuHaae5feM2Kcc8EOTUhp4HNeO20L3jLBbdCdcwiGMxVgAD+BdC/A3GS+Tx2u3fy1P91ozz/KV011MvU7FNfAgzq63Du1Jy+r6siVcwiGMxVgAD+BdF/A3VZNxQXBan4trFr0v0K67lqXwuw0EvHdUbAP3P3a+dYA/s4pwCYcwFmMBPIBvAYBvoOrXAXTbe1A54AcnnGngDlhbOZ8QQriEQxiLsY4L+FOnTr377ruDBw/udVO+vr7BwcEpKSm1CMA3teo9y//Hlv8qB3zwxSsN3H7MXOsAf3oF4RIOYSzGOiLg09PThw8f7mZGEyZMyM7OhuUAvqkZb5jH71/8gUK6ux89ma5SN3DjyWutA3zaVsIlHMJYjHU4wJ84caJLly5ushIJ/fnz58E5gG9qGT7LH/nNt0oA/9aFjIZv9+pB6wCfG0+4hEMYi7GOBXiBbU9PTzcFEownjwfwzQL5W+PGFrw39fe7Iiy+IKfV6Rq+zaoyK2rp4xfX9VdPuIRDGIuxDgX4wYMHuynWhAkTrFr57t27H3vssXbt2nl5eY0fPz4r61YbaqPVAngAL0d3w3FjBeNl8vhXf0y3C90lZUcpBXxRKuESDmEsxjoW4Hft2uVmpaxqczds2LAdO3YUFxffuHFjwYIFQ4YM0QOeDB7AK5LJgWf2L/7gH1v+q29X3zNi3yuHjyaVldt965d2Wqb79UjCJRzCWIx1OMD7+/tbC/jg4GDbtqVSqTw8PAA8gLdCMuPGGk+B03Q3ShtjH0Qeb66uPm5BXX/1hEs4hLEY64CA9/b2thbwvr6+NmyovLx80aJFo0aN0gPey8urTZs2999//4cfflhdXQ3gAbzS9N3cVH1oXyPtRlVZXZu75LW3SB87v66fu2vH6/qrJ1zCIYzFWMcEvJv16tWrl21b6dq1a3p6uuFywfUzZ84MGzbs3XffbVmALywsVFIsISEhKCho7NixEydOXLp0qTihb+W1Ot2mTZsmTJjwj3/844svvtCZeersAoA3N26s2S7uCZeES4zFWABvK+BF0m/DhkpLS+fPn//oo4/W/1d2dranp2fLAryXl9crr7ySlJQkX2z27Nnx8fFqtVqcymvXrhWwl5bv2bMnICCg8KbEzL59+1wV8MrpLvWGS7gkXGIsxgJ4SXfddZe1gB88eLBt21KpVO3atau/PDc3t3Pnzi0L8Pn5+QsXLhT3SuKW55tvvtFqtUpOkTFjxkjz06dPP3PmVlesYmbGjBkuDPjcmZ//GBibFJwTF1QWG6SKDVbFB5WeDrp+4b2ogpkrfwX4hbMJl4RLjMVYAC/Jz8/PWsBbVZ3+wgsvpKamCn6JNH3atGlDhw6Vlk+YMCElJUUs/+mnn0aOHDl58uSWBXhJ4vgF3f/85z937979gw8+EHc6MoWjo6MF16X58ePHV1RUSPNixtzLi84O+Mri2jNzsiwMvh6YWjFz1q0q+tVLCZeES4zFWAAvKTQ01FrAnzp1Svn6v/322379+rm7u3ft2vWll17SI0y/XKBt6tSpIrlviYDXKyEh4dlnn23btq2/v//ly5frF8jIyHj55ZfFX+njM888o3/uLmb+9re/GRae+7OeeuqpoKCgMgUSl0ppaWmZI6kwsyJukU7ROK3BORLjK3bucKhDcEBX5QwvLCwqKnKKXcVYjHUxYxsJ8CKH9PHxUU734cOH1yL7Av7atWuBgYGDBg1as2bNwoULxa3Qnj17DAskJycLup89e1a/RD6D/+fPGjp0qFhziQKJ66S4uLjEYVRcVJK4vFp5N7Eij6+c9U7ppYwSR5KjuSqvgoICETGdYlcxFmNdzNjG68lOZOQeHh5K6N6lSxejZvCoQYAXibtI2fv37//ll1/qH8NHRkZ2795dX+b48eMvvfRSWlqa4Rdd/hl8XqLVo7UWfXWUCk8qPDEWY6miN9L27dstMt7T0/PEiRPg3D6ADwsLe+yxxwYOHCisr/+Sm74bIFFs8uTJV69eNSoQEREhGC+1ohczrteKPnVjjbWAz9ihc7qrmnCJsRiLsbWNP1ysyONl6uoHDx7MUHL2BLyvr69RPbxJja4ntbquaxX9e/BCmzdvdr334GPfr7YW8GdWES4JlxiLsQDetLRabWhoqJ+fn/7dOW9vb39//127dkFxOwPeZFe9du+/13kBby3dxZQQQrgkXGIsxgJ45HiAF1l4q1atALykmGCttYA/vYJwSbjEWIwF8MjBAC/ofvjwYdv6CHRJwCcHZVgL+PRthEvCJcZiLIBHzQd4k20cRO5+7733fv311wBeUmZQmNWt6FMJl4RLjMVYAI8cLINvJDkv4NUrPokPKraihd2CfMIl4RJjMRbAo+YH/IYNG1544QXDJeLjxo0bAbwk7b5dRTM/jg2uVEL3uKDSimMJhEvCJcZiLIBHzQ/4Hj16GPUZJD7aMBCvqwJed6O0MnCaYLzFPP500PUbHyyr1VY541VNuMRYjMVYAO9qgG/btq1GozE6A0yOtdcyAS9UfeJI5Yy3VTOmZb73XXJQRkxwlcB5dHBNdPAvHdQnBeVkzdqauyuzPItwSbjEWIwF8MgBAP/www8fOnTIcMmBAwcGDBgA4A2lDd9mctx3093Rb6zNja/r47aymHAJhzAWYwE8aibA79ix49577921a1fFTe3cudPb21ssBPAm8vjAaUaAv/RexMXA/XHBN8zV22dHES7hEMZiLIBHzQF4oR9++GHIkCHtb0rMCMbbfc9cAPC1N5/Ha/ft0qz8WCK9Oujf6lVLqo8cqLmhEvl65uHaK/tr4xebTeibsfaecFlfRal1PRacXlGbuKSud+GMsNrSixgL4AE8gHctwDeBXAPwSq7qGm2tBPvzX8jV3jcx7AmXv3KjuDZ5rekaF/GraSswFsADeATgWwzga84la7d+qfl4gWbR+5plH2q3f12TcSHv8o2fIjQpn9WlgGIS8M46Wlv182Wuq6nNiTaR0DcL7AmXeqkL5X4Uqadh5YzHWM5YAI8AvNO+JldUWFcn/+tH7+oZ7/z03rHoYBMjycbMrcN8/YTeZO19k7XLI1zq77rOrLLcn4HI4zEWwAN4BOBdGfC6gjzNB0H16Z4SdMGG7ugVwl781+5pPeFSkjBWYY+ECp/HYyyAB/AIwDsc4HV5ORY6pamp0Sz7sP6rcRfei1JCCMM83jbY27EOn3ApKXWTUsBnhGEsgAfwCMA7J+DrUvPAaVXrVlYfiKi5lFG/QHV8TH26585aq5AQMXN/eR4vL/l2eXrY29DGm3BppNj5iscUWIWxAB7AIwDvhIAX6bsRuTULZ2t/+K4m44I+ra9av9qoTOnM+TFBVcoHnpFP4k3sVU1t8Y9yab3NOT3hUpLy3y4hBGMBPIBHAN4ZAZ99vWrLpvrP1+umn9P6yqB/Gz16Px103apxY881YMgei3X4VrXLI1xKipmr9Lc7vQIOAXgAjwC8EwLeMJWvjo6sS9ZnvWOyM1r9dH3WV9YODJ+4xD47KWCfHdWgdnmES0ln1yv97Uw2k8RYAA/gEYB3GsD/Qvry8urYKLNp/Yy3i2cuvvxeRHJQht2ree2V09c9Of7UdB0+4VKSuE9S+NsVpcIhAA/gEYB3CcDXT+s1788wSfqymbOvzvouJeiCNKyczJTyWWPtoaqgNnGp5QcEetjrXbVL/6zOGy7FTZK467JI9+S1cAjAA3gE4F0R8JKkUWJlJtWMaQUzV8qk9VcPNsqOqQtr4xZZ97AgZX1NblK1vfpndepwKW535NvSxy+2oruhJjtd1VXFx9MWrz/mu2RvLzFtihwenbFaW60G8AAewAN4AG+9tFWahbP1OD8dnJUeGJk/a7V6xjtK0vroOXUktn/tQk1t0nLLRI9+37o7AKv6Z3X2cCkYby6PP7PKul+taU7X1OvhC3Z6Bu9wM5pC9nhfLjgB4AE8gAfwAN56mmZeqQwOkBCuT9Njg8ovBEZlz9pUPjNIJq2/tiWjMXYpN0Eps6/ss9xrnm39s7pAuJTaLZ5df6tdvcjpUzfVPc4Q90+OxqHkzND6aNdPc8LclTMewAN4AA/gAfyvGC/l8ZnvfVcfiknBOTJp/a136y/Zk/SnVyoF/I9f/nxPEG/n/lkJl012upaps+f/0EkG8FIer7CuHmM5YwE8gHdZwOsK8rT7dlWtXlo3KNyi9+vedz+0T3ej1MLXtFV1z+M/XRUfVGIOjfJpff1edGxW9ByltI5beOsryvtnjf+o+Yeuh0N6pV4PX3ngAXm6S1N0xmqM5YwF8AC+pQK+pkYbvs30y+6B0wTmlazDYvusmLm1RWmy79bLdo6rRMofq0e/f+srsfNqrX2DvxmHrodDQsUVl9YeGaQE7dK0KXI4xgJ4AA/gWyTga2oEVuWbxGu3fqmQ8crbZ916t95MLzq2pfVWAH7OzX2osYXuJmHfZKRv4RwqLE9fHHGXcrqLacneXhgL4AE8gG+JgNdu/1qe7tKkMI+3oX2WhV50rEnro2crpXLsgrryygdIreuZ5yPLA9w1wXP6lsyhGp121cG+VtFdegyPsQAewAP4Fgd43bUsJXSXQGv5eXyDr2r5znEtpvWJyxSn3Rvqyit/AG/YP6t8r3mNXXvfkjmUeGWztXQX0/pjvhgL4AE8gG9xgFeYvluVxNvlqrYtrb8eaV1nq8oHSDXXP6sEe7sPcAeHTGpT5HAbAH88bTHGAngAD+BbHOA1i95XDnjN8sXNclUrT+sFbuMVdGN35udW1TY0yjMni2Pe2Av2LZlDFl+Kqz8t2OmprirGWAAP4AF8iwO8crpLU9XGNSK3bq6rWklar/ou4uz7cmPexH34S2erygdITfpE0R4qGfNGTGcX5+bsybGN9BaNrTmXrN36pebjBXWvOy77ULv967q7H5fgkA3pe+r1cO6cADyAB/AAXlke//ECJYxv7KtaPq0vn2V6zBujxvx2HyC1Puyv7lZdXBQdF1RqOq3/vNratF7GWF1RoWblxw28M3NkDs393kM52kW6n5wZStUIgAfwAL6FAt7c8K8W83jHuarl03qpc9wrwREX12TUb8xv9wFSjfetIE/aK7Eb12d9dem9iIuB+83CXlkjfHPG6rfVwDszR+bQ+mO+Cum+8sADZersFsshAA/gATyAr9Vu/dIGwIvJYq1vs1zV1jbCt/sAqb9O4Ws0yz40ec8hYG+O9BYf1Zs21sy2bLgzc2QORf203O418wAewAN4AO+agBe0sw3w2u1fO/JVrbwRvn0HSDVUdXyMxRF1pbT+8rdFyhvhmzTW4raU35k5Moe01eqQPd4W6b72yKAWziEAD+ABPICvU9Wmz2x5Er/sQ2e5qi2m9eX//fb8wjSjp/W2DZD6K2PFFhXfLSlshC9Ib9JYq7bl1BzKKoqTb0u/OOKu4opLAB7AA3hz2rp1a7du3dxuCsC7OOBrNZWajxdYDfiFs53uqpZP69WzphW/v/JKUERyUIbNA6T+6sf6eSxd5XdLShrhn/lMe/VkpVFab8O2nJdDgvHm8vhVB/sWlqfDIQAP4GXk7e198uRJ21HqkLcFAF6O8dbm8eKewKmv6gZ2mafox2rY3ZIS2Ovr8ItmfmyvOzOn4JC2Wh310/L1x3yldvUip98UOTzxyuYanRYOAXgAL69WrVrpdDoA32IALxEl44Jm3ntKa3otDT/jLFe1SOsro45XfrWx4T3hG/9YgdPsdbck31+eNKUEXSiYubLh24JDAB5jGxXwApBbtmwZNGhQ+/btO3bsOHz48JSUlIiIiD//+c8dOnQQS/7+97/n5eXpy+fk5LzxxhuicNeuXd98882KigrD9Tz00EPt2rXr3Lnz2LFj9d+qz2D9EjcDya9f6Pvvvx84cKBYf48ePTZs2GD0dcN1ymxO7OQf//hHcVy33XabfrUDBgxo27Ztz549pdXKFAbwdlPdyO4K22qdS3a9q9q+aX3Vmk/sdbdkSPorJ1UZezXmYC8wf23W19dnfWUup1e+LTgE4DG2kQDft2/fEydOaDSagoKC119/3cvLq3///sePHxc7IC0ZM2aMvnz37t03b96sVquzsrL8/f3ffvtt/Xr69esXGRkp1iPQ/vLLL/v5+Vkkbv3/mlv/rl27vL29Dxw4IPYqPT39hRdeULLy+oB/4IEHTp48qTd27969t99++44dO8Rqz5w5c//994eHh5sr7CKAnzNnTpUCiXsrlUpV1XhSVVQuCLbMpBUhFtdUXFxcWlpa5Qyq76qmuFhz6oRMWq9Zu0Kzd6cmPU1mtZqjB5X2K5CcpHxv9cZWqqqy46ovb82+OOeIyTfuJNgbkd6qbdndWEeWU5+xGNs0xtoL8GfPntV/LCoqEkvOnTtnuKRTp04mv3vjxo27775bv57U1FTDb4nE1wbAm1v/kCFDdu7cqaSKXh7wsbGxhv969NFHBd31H+Pi4sRtirnCLgL42bNnVypQeXm5OAUrG1UZ6RZabM0PrMzJtrgacbaJO/dKZ5AFV7OuVkYerfxspcm0vu5+KOzbyh/PVZaX1VtvmcK7Jav29lfGxkXr37jLfO87c13o/JLWL/nCgYx1MLnOGYuxjWasvQBv9Ajc5BJpJjc3d/LkySLJbt26tVQrrq+7lvmWcsDLrL99+/aG1fU2A766utrwXx06dDCq5zc8IqPCVNE3wmPpzCuahbPNtcHWFeS1zApPi+/Wa9asLN4Q8dOqjMQltWJK3VSbvbdIFTjdwhh9yUm2VXjqbpQa3Yop7C+vUUezpSaZKnqq6C0CXvmSYcOG/etf/0pLS1Or1XUP/qqqFD75/lXs0unMAV5m/TYD3nBz9Qt7eHiYOx8a0nwPwFsjbVX1iSN1T5GllmLBAVXrV1fHx9TW1LTAq9oE7GWf1pfN/KUn/PjgksKZn1ho1m5NW329sdpdYRZ70ZEhfRPAHg4BeADfQMC3adNGQq+k/fv3KwG8yJKLior0y8+dO2cO8DLrHzJkyK5du+rvf/1G+DKbq7+TjzzyyNGjRwG8c1/YLSRcSml92aebymea7Qn/8nu7i2cukkvio47bYKzmo/lKHvD/Kq2fXWYR9rZ12weHADyAbwzADxw4cM6cOYWFhSqV6ocffrj77ruVAN7Pz2/y5Mn5+fnicE6ePNm/f39zgJdZv/h47733Hjp0SKPRGDay8/b2Pnz4sCHjZTZXfycPHjw4aNCgqKgo6ZmI+Dhy5EgAD+AdNFxWld3q7DYpOCc9MDJ/1mr1DFNP62f8y2wju/WrbTDWhv4H1QvnKRnNNjsKDgF4jHUIwAuyPvnkkx4eHu3atRPg/OKLL5QAPjc3d+zYsb/5zW/atm07YMCALVu2mAO8zPqFvvvuO+l9tl69em3cuFFa+NVXX3Xv3l3k8Uo2Z5LZIoMfNmxYx44d27dvP3ToUH09AYAH8A4XLi/vNQZkbFD5hcCo7Fmm03oTtfSL3m8awFet+WVYe/mOdERC3/B6ezgE4AE8ahoBeK7qRnE1aZncWDUGaf2/ZF5MsMFYcw0h5Z4FHDlgcp162J//4pc9VzJ2LRwC8AAeAXgA77LhUuGI8qcDM+Vy63UrFY7z9ksjux3fWAf492fUqlTyK9fV1OZE1yX05zbCIQCPsQAewAN4AK9gig8qtlyFLjCfnqbQWF1BnulX823tfNAwobdLUzs4BOABPALwAN5Zw6VWXRv7gSLAJwdlmEZv0DTN/EDlfeIaGqu0a+HggJrTCXCIMxZjATyAB/Bc1YpUlFobt0BpBn/lve/NJtY3ex0w0X+OqaFujIytY7z5PF7z0XztrjDdjVI4ZE6p18O3xfmvOOATEtFjxf4HwhJfvZh/BMATCgA8gAfwLRfwBclK0S6muGBV+cwZFhJrgfnYKItD3ZQU5BsZqyvI0+74Rt/mrnmh7kSna3HFpbVHBpkcV/6LkyMqNPkAnlAA4AE8gG9xgNe/+65wKowpVc5gi33iqj/9xLYRbOGQXoXl6Ysj7jJJd2kSOb3DMh7AA3gE4LmqGytc1n/33dwk7gMKkm3fN/uOYAuHJNXotKsO9pWhuz6PB/CEAgAP4AF8ywK8/Lvv+ilhSV2ubxfp0/rKX7fIk3laD4fMKfHKZot0lybHfB4P4AE8AvBc1Y0VLhWm74lLGsXY8ssXnSKtd9jTdVPkcIWAD0t8FcATCgA8gAfwAL5eBh9SW3MuWbv1S83HCzSL3tcs+1C7/WuFHdooMdbi0/rmTesd9nSd/0MnhYBfdbAvgCcUAHgAD+BbEOAFuZUAPmVelukObTauEWy2r7EO+LTeYU9XhXQXU8gebwBPKADwAB7AtyDAX/y+Qe++1xH34wW2Md6isY6T1jvs6Tr3ew+FgF9xwAfAEwoAPIB3OcCrVNVHDlSt+aSubnnR+yI1rBu2XHH+59qAVxfWRs+x9O57kKl333+dxzd2uGzetN5hObT+mK9CwG+L8wfwAB7AA3iXAnzNueTK92eYRILCzM/lO7rJjrIA+NyZn1vuH9765/G2Gdssab3Dcijqp+UKAZ96PRzAA3gAD+BdB/A1pxPksDTrHSUYaAld1QrGm8zjY2dXZc/apKSXeO32r5s+XDZZWu+wHNJWq0P2eFuk+9ojg6wzNvu6dleYMPZWg8ofvtMV5AF4AI8AvKMAXnejtDI4QB5LggEWo38LGbpDXVj7047a2J97pBe8T1xSezU4QjVjmhLACww0Y7hs7LTekTmUVRQn35Z+ccRdxRWXFN8U11QfOWDihmnWO9WH9gF4AI8AvENc2CIFUUKmuufxAN78eDPxQcWFMz+xDHhxq+QY4VJRWm8l6R2cQ4Lx5vL4VQf7FpanW3HVbP9a7mKJjQLwAB4B+Oa/sDUfzVcCeEECAC8/3kx0cI1Fxms+XuBo4VI+rbeqAt/xOaStVkf9tHz9MV+pXf287ztuihyeeGVzjU6rfCXCDYvD9eqKCgE8gEcAvpkvbEXji4tAv+j9Fg54JePNiDxevq5eu/VLRw6Xcmm9ggr8FsKhqi/WW25ssW8XgAfwCMA7CeAt1S27POAVjjeTNetbuVb056weiKZZjL2V1lvZLs/BOaSuKj6etlik70v29hLT+qNDj6UuFTm91eePpTYrdTVemz4D8ADeWdnp5uYEOwnglUg/pKmFgLXmkxYOeIXjzZwN/NHsTdLKj50uXFrVLs+ROZR6PXzBTk+TXdddLjhh93tiGxpbAHgA72iAd2TSA3hF0u74RlEjuyMHWjjglXZHH1RoOuJ/EGTbc1nHMdZiu7zKsG81aakOOJRtcmaoTPv5OWHuVjFeSbMVGxpbAHgATwYP4O0dtQvyTMbrX03vz6hVqQC8kik+qNjk23E2vyHtgMY6+Jg3RipTZ1scbEbk8crr6qu+2tgYHR4A+JYMeF1JsXZXmAgU4sKxGGwtKiMjY/To0Z06dWrXrt2IESNyc3NNklv/UfgwadKkDh06dOvWLSQkhAzedQAvVH3iiIX+1xQ8OXZ5wCsdb2ZpSdWaTwTkpNbUdT3+xsfU1tS4arh0wDFvjLQ3JUBJH3bRGasVrrAmLdUi4HXXsgA8gP9VmI2PkZk0a5f/8jz0i/XyhS1u64EHHjh06JBKpRK/xTvvvPP888/LA3769OmjRo0S9wE5OTnihgDAuxTgbzHeZB4fHFBzOqGlXdUmpXC8mWvHW2i4FGl9ZdTxyq82Nk1ar9Eq9WTZvj5KAL8pcrjyrcs/2NKGb3OEMxbAOxTgFTZnVjJZtd2Kioo777xTHvDdu3dPT7/VD0RaWhqAdzXA196sqxdhS9/mTvPRfO2uMN2N0hZ4VZuUovFmFtRq1XbeW2c0tgnS+o3Hh4rpYv4RiyUV9kK/ZG8va+4vKqs2fWayX+e6F+QaUGED4AF8wwF/8uRJX1/fjh07ut1Uq1at5AHfunXr6urqWzevWi2Ad0HAc1VblMXxZopSMbbKKK1vjKf1gut6MAvMZ+QdbDjgbRgJvuZcct1NzM3HMXV90W/9subKJYc6YwkFjgN4cZ7LTNqwbzRLF1a+927V8sXanTvkC1vclsjIQ0NDxQ+h0+lKS0v1nHZ3dxcJvTRfUFBgMoO/cOECgAfwLRHwtTLjzcyv6+fOhBo2CK8rGWvHtD71evjiiLuM8ByR/O7VwlP1CysZZkZM64/5uuQZSyhwEMA3pby8vMLDw8XRZWRkjB8/Xs/pgQMHzps3TzA+Kytr3Lhx+uUBAQGjR4/Oy8vLzc0dOXIkgAfwLRTwtTfr6i9+/0ubu6RldX3gVJWZzvAaOAivSxprl7Re6nTWCPNSQm9Ub/990hQlgD+ethjAEwpcA/BhYWG9e/du3bp1jx49Vq5cqed0YmLiQw89JPL4nj17rlmzRr9crVa/+OKL7du379q1K63oAXyLBrxC2WUQXpc3toFpvcB8/OUNmyKHzwlzN8K8vt6+sDzd6L/1pwU7PdVVxQCeUOAagG8JAvBc1c3mqr0G4W05xjYwra/Q5NdP6PX19uJf8oBPvR7OLSmhAMADeAAP4C3LXoPwmja2wc/1HdxYm9N6mXr7nWfeMpnHz/+hU3JmKGcsoQDAA3gAD+AVyV6D8NY31i7P9Z3FWNvSenP19uuO/GnDiaELd3ndei9uT++die+UqbM5YwkFAB7AA3gAr3gTdhqE18hYez3Xd0ZjbUjrTdbb66fPDvueuxrhpGfs6av/3Rbnv+pg3yV7e30V9fTZa9sJBQAewAN4rmpnGoTX0Fg7Ptd36kTT2rTeXL29wtfoHe2MLVNnC6Kb7IlPee9+hAIAD+ABPIC3UfYahNfQWDs+13dqwNuW1gvMJ17ZfPj8XDHtPztL+Wv0DnXGiqMQWbu5poLfxU8iFAB4AN9Qjf5Z5pab/C+AbxGAv9kCznRyaf0gvIbG2vG5vssAviFp/eGzixft7mbxNXqHOmMjLyyRfx3gx+xdhAIAD+Dtg3mLSwB8iwK8uRZwNg/Ca2isHZ/rux7gbUjrSwryi0vyLb5G71BnrEz6Lk3zvvdYsrdHyJ7uomRE8ruF5emEAgAP4AE8V3WD6S7fAs6mQXhtAbyC5/quDXjlab3600+ktF7+NXrHOWMV9quvn8SNy9EfFxAKADyAtw/gJ06c6OfnN2XKlG3bttWYGVQKwLse4JW0gLNhEF5DY+34XL+FAN7atF5z6UeF3d82l7Hzf+hkLePFFH95A6EAwAP4hgL+ViZXU3Pp0qXAwMD169cbLp/7s5566qmgoKAyBRKXSmlpaZkzqLCwsKioyCl2tTFcVYV9qwjtc2eJkmXZ120wVvXNf5VsQrVvtysZa3/l5lacOKL6Yr163nv13RM5fUly7Mm0TzccG2ZUb//5kUfPXtnZvMauOzzEBsC/H972Wv45QoENZyyAB/CmJU7xCRMmGN0MSho6dKjAf4kCiZUUFxeXOIMKCgrEhe0Uu9oYrqoXzVVE37XLbTa29FKGyezzV3yaM700J8eVjG3UM7Y4Pa3syAHxoxgZq1q97MbpxOz8jPoN8Rbvvics7o3UKweaxdi9p4NtAHzdS3TH/0IosOGMBfAA3mw91fjx46mibyFV9I3XAs7Q2OoTR+zyXL8FVtHLG1v3tP7EEaNH9bfq7dNToi4sbd56e72xNTrtp4cG2AD4OWHuxRWXCAVU0QN42wEfEhJy+fLl6urq7OzsefPmrVixAsAD+Aa2gDMyto7xJvN4a57rt0zAq6uKD54L3hQ5fMneXqsO9hXZcHFJ/q9KaKvqY15qjqdatzQ24p3/HHikWdrbGxqbd+O8whHujSZx7IQCAA/gFaHd5PvukZGRb7/9tp+f36RJkzZs2KDRaAB8CwF847WAq2+sriBPu+Mb/RY1H83X7grT3Sh1SWPtJZFt1+fiJ/vuzylNMS4qMB8bZa45XvFH/478fvLinXc2ZXt7I2OlO5U5YW2sAvxXUU8TCgA8gG90AXjX45Agrr16tsFYu6tCk//hri4msbfigI+2Wm3yWzJv2ZXPfPP4iqGLt3dumnp7k8ZujRlnFeDFXQihAMADeAAP4K2WyKottoBT2LMNxtpdYYmvypDveNpiy7+vqbfsBOajl/zfpmNDG7ve3qSx6Tl7rQK8uJUhFAB4AA/gAbwtaqQWcBjbcMm/Pm5V3bVRWq/5eEGtmWHr7Fhvb87Y75OmKAe8uMshFAB4AA/gAXwDGG/vFnAY23A1Ut21SOsNx+c1N2xdw+vtzRmr0ZaZHFnO5HS9JIlQAOABPICHQ7bL7i3gMLbhWravT5PVXQvM271/e3ljU6+H39xca5lj3Hn6LUJBywH81q1bu3Xr5uZmOwQb8l0AD+DhEMY2nbbF+csC/oHG2KhMvX3ilc1iyiqKs6Ox5rJ5cZ9x8FxwjU7LGdtyAO/t7X3y5MkG4RPAA3g4hLFOYWxxxSX5x/ACt420aXP19lbV3is3Vsrm537vIVa+6mBfcWfT9IPlAPhmV6tWrXQ6HYAH8FzVGNsijE3ODJVhvLXviIuEWGBb6jNHfNfi/YG5enuFtfecsQDeKjbrJT6q1epXX32180299tpr4qO+2LJly0SuL+4GJCsmTZrUoUOHbt26hYSEAHgAD4cw1pmMFXm8XdrZCboLJButQeTKSr5boakbgf7w+bn7z85S3uqeM9aijLopPPrjAnPdGzQX4KXnMuamhMsbf0h6Y8UBn4/39tgW/4J8Yavy73//+98jR47Mzc3Nycn5y1/+EhAQoC8zfvz4vLw86eP06dNHjRolFRsxYgSAB/BwCGOdzFhzre0EGJSvRODZLvX8ylvdc8bKy2Q3hQKWJropbD7A2zZKkMnJKsDfc889Fy5ckObT0tK6d++uL3Pt2jV9MbE8PT1dXwzAA3g4hLFOZqxIkU1GTAFa5SsRCaId+4JV0uqeM1a+UsSGbgpbDuBbt25dXV1962TTat3d3euXqV8MwAN4OISxTmasRlsmgn79jNmqRuaN1BesTKv7jJzjnLHm1JBuCpsS8IfPz5WZFuz0NNztRbu7yBS2NoM3TM3FR5OAN8zgRcYP4AE8HMJY5zNWMF4gU6qrX7H/AREurX2FbMneng2v55dJ6E3W22849niTjU7rXGdsQ7opdJxGduJGxHC3lVBcIeCnTp0qPVwXGjFixLRp00wCPiAgYPTo0Xl5eaLYyJEjATyAh0MY2xKNXbbvvobX81vEvN17y3HVM7Yh3RQ6DuDFfed38ZPEzcqqg32jM1Y3sN8CQzyrVKrJkyf/5qbEjOrn4TCMEK5Wq1988cX27dt37dqVVvQAHg5hrJMZa/Ru28kf19pm7IKdv60Pkvnfd2qMzmSkevtFu7s15ei0znXGNqSbQrqqdV4BeDgE4DH2F7rXf7dt66kJNqzKZJ3wigO/b7ydL68oOZG2tDF6uXeBM1a+m8K9KQEAHsADeDiEsa5srL3ebRPaFDm8icdqk4x1lnr7Jj5jZbopDNnjra4qBvAAHsDDIYx1ZWPt+G7b9ZIkI8Qu2OlZqspsMmMbe3RapztjTXZT+OGuLharNwA8gAfwcAhjnd5Y+77bJhgvMmkBFYH2Laf8RBLZ9MY23ui0znjGip9ga8w4fSf83ydNEbdBDT9jATyAB/BwCGMd3Vi79GHngMY6YL09fdEjAA/g4RDGNp3s0oedIxvrOPX2AB4BeAAPhzC26WSyD7vPjzzalAOlN4GxjlBvD+ARgAfwcAhjm5rx+j7sVh3sG5E0q/RGsUsaK1NvL5ZLI5JlFcVxxgJ4AA/g4RDGYqxTGmuy3r6x03oAjwA8gIdDGIuxTWGsuXr7RmqO11zGGvVUqKSHAwAP4AE84RJjMdbpjRWYF8yThiPbf3ZW4zXHaxZjTfZUuC3OH8ADeABPuMRYjG1ZxjZec7xmMda2ngoBPIAH8IRLjMVY1zS2MV6jbxZjbeupEMADeABPuMRYjHVxY+34Gn2zGOvsw8UiAE+4hEMYi7GNKLvU2zeLsbb1VAjgATyAJ1xiLMY6kLE2NBe3FvMNqbdvFmNt66kQwAN4AA+HMBZjHcVYmebi6qrig+eCJfCvOtj36I8LBKobsl3b6u2bxViTPRUKo+R7KgTwAB7AwyGMxVhHMdZcc/F9Z2cJ9BotFMzLKU1peEJvVb19cxlr1FOhMMpiP8QAHsADeDiEsRjrKMaaay7+fnhbk8sF4xuYx+sxr7Denp7sEIAH8HAIYzHWamPNNReXmY6nLbbjzlistwfwCMADeDiEsRhrtbHmmovLTPLvgtuc0Jurt0+5vAvANzP83NycaLUAnnAJhzAWY+tkrrm4zCT/LngDMW+y3n7BD56C/Y3Rwh/AA3gAT7iEQxhrLKNG5ntPBxeX5DudsSabi88Lby8DeFG+sfdQZti6zZEjADyAB/AAHg5hbGPpYv6R+o3MP9l3f8MbmTe9sfWbi38b97wM4PemBDTNfor7J9N3GPt9GmNcWlcCvFanC83NH5qUMiAuaXXW9YaTeO3atT179mzTps2AAQOSkpJu3eOq1a+++mrnm3rttdfER/nywp9JkyZ16NChW7duISEhesBnZGSMHj26U6dO7dq1GzFiRG5uLoAH8HAIY5tHIr/8cFeXRm1k3rzGXik4IVM/r64qbpr9NNfCv5HGpXUuwG/OzpWZ/nrmnNuRSP00Nf2iTGElgB8/fnxWVlZ5efm8efP+8Ic/SMv//e9/jxw5UvA4JyfnL3/5S0BAgHz56dOnjxo1SiovQK4H/AMPPHDo0CGVSiWi0zvvvPP8888DeAAPhzC2eRSW+GqTNTJvFmO3nPIzeWhzwlo3ZeqssEFARPK7iVc2iymrKK7lAN6Q3w2clAC+sLDw1t1tRYW7u7s0f88991y4cEGaT0tL6969u3x5USA9PV1f3mQVvSh/5513AngAD4cwtnk0/4dOTdzIvImNXbDT0+ShbYv3b8r9NNfCf/mB+00+nm/2tN6FAW/yY+vWraurq6V5rVarB7nC8vrlJ0+e9PX17dixo9tNtWrVCsADeDiEsc2j5mpk3mTGmryDmR3WulSV2ZT7KdMhvLn29g0Zts65AD/30lWZafjps4YIH5qUIlPYZsCLDN4wIxcf5csbZvAi9TdcHhoaKkKTTqcrLS1tlsZ3Dg34OXPmVClQRUWFSqWqcgYVFxeLX9opdtWJXMVYu2jp3vtkAL98/++d3dj/nPi/+se1Nfq5Jt7PclWRMNNoNzYce7xS88vOl5Rfj8n47MDZ2XuTZ9RP60XhC9kHbNv6xdwT38RMXHngwY/39BTHfr0opeHGNlkju7Lq6knnL3Q6fqpvbOLqrOtana5B8DMD7KlTp0rP1IVGjBgxbdo0+fIBAQGjR4/Oy8sT5UeOHKlf7uXlFR4eLm6PMjIyxo8fD+CNAT979uxKBSovLxenYKUzqKioSNzQOcWuOpGrGGsXhUb/Qwbwu09PdXZjL+fFGL+JvtMzvySj6Xf1RnlBWNwbS/b0FvsgWLs/JVilLjd7XBUl0T+t23j8CaOdX3/0sR+v7bFquwfPzjVaydzvPWIzNjTQWNd4TU7/UdzNTJ48+Tc3JWbER/nyarX6xRdfbN++fdeuXQ1b0YeFhfXu3bt169Y9evRYuXIlgKeKnppkjG02FVdcMvcYvikbmTeqsddLkjZFDheHKdC+5ZSfOGQnOmNtG7ZOr4v5R0z+uILxeTfOO0gVPQLwAB7AY2yjKDkztD7jF+68wzHfz26ZZ6y1w9bp9dnRweaqZ8ISXwXwAB7AwyGMdXFjRVK7NWacyOqk/mG2xUzOK7qMsY52xsoMW2cO8zLPXz49NADAA3gAD4cwFmMx1oGMNVlvb/K1OpnXIOVfkQDwAB7AEy4xFmMxtnmMNVlvb/R4fv0xX9s6OQDwAB7AEy4xFmMxtjmNlX88f/badjMd+bnLt9ED8AAewBMuMRZjMbb5jZV5PP9l1Mj6gD/644IGGgvgATyAJ1xiLMZibNMZa/Lx/MJddyzafYfUB4C4CVDyfgSAB/AAnnCJsRiLsQ5nrM2v1QF4AA/gCZcYi7EY6+jGytTbWxytDsADeABPuMRYjMVYRze2fr29xTwewAN4AE+4xFiMxVjnMFZfby8y+IYbC+ABPIAnXGIsxmKsAxkrMK+kN34AD+ABPOESYzEWY1uisQAewAN4wiXGYizGAngE4AE84RJjMRZjATwC8ACecImxGIuxAB4BeK5qwiXGYizGAngAD+C5qjEWY13C2BqdNuqn5Zsihy/Z2+urqKcTr2zGWAAP4AE8VzXGYqxzGyvovvH4UKMeW7fF+bdMY5Xf6wB4AA/g4RDGYqxDG3v4/FyT46U2Sx7fvMZada8D4AE8gIdDGIuxDm3sqoN9TQJe5K8tzVir7nVcFfBubm4utiEAT7iEQxjbQo01iTQxhezxbmnGWnWvA+Abe0ONtycAnnAJhzC2RRi7bF8fk1TbFDm8pRlr1b0OgCeDB/BwCGMx1qGNjUh+1yTVon5a3tKMtepex3EAr6upLUiuPbexNvnT2pxoO3B37dq1PXv2bNOmzYABA5KSkoqKirp06ZKfny8VEEd955135ubmGhFa/7H+GvSOTZo0qUOHDt26dQsJCdGXz8jIGD16dKdOndq1azdixAixZjJ4AA+HMBZj7WCsRlu24oCPEdI2Hh9ao9O2NGOtutdpSsDnJcpN57+oPRX8y3Q5Qq6wEsCPHz8+KyurvLx83rx5f/jDH8TCt956a+HChVKBffv2jRo1qj6ADQFffw1C06dPF18U/M7JyREg15d/4IEHDh06pFKpxK//zjvvPP/88wAewMMhjMVY+xgrGC/YJuWvqw72PXx+brPQvdmNtepepykBb8jvBk5KAF9YWCjNV1RUuLu7S0l2jx49pOOdMmXK1q1b5QFffw1C3bt3T09Pl+bT0tJM8luUv/POOwE8gIdDGIuxGGt/xiu813FhwJv8OG7cuK+//lqn0/3+978X2bY84E0ub926dXV1tTSv1Wr1y0+ePOnr69uxY0e3m2rVqhWAB/CES4zFWIx1XGPtCPjMw3JT6qZfIfzcRrnCNgM+Ojr6T3/6k4DxpEmTpCUiNRcJtzRfUFBgEfCGGfyFCxcMl4eGhoqfXtw9lJaWmlsPgAfwhEuMxViMdTXAy6taU/vTd7Wx82vPrKprZKeraRj8zOBZSOTZjz/++KFDh6SPAwcOnDdvnmB8VlaWyO8tAj4gIGD06NF5eXm5ubkjR47UL/fy8goPDxd+ZmRkjB8/HsADeMIlxmIsxjaWSlWZe1MCpCp6dVWxgwPezvAzD3iBYW9v75qaW3cQiYmJDz30kMjje/bsuWbNGouAV6vVL774Yvv27bt27WrYij4sLKx3796tW7fu0aPHypUrATyAJ1xiLMZibGPpu/hJ+kZ2gvEtCvAyWrdu3YwZM1zgQAA84ZJwibEY20KNnf9DJz3gVxzwAfDST/P73/8+MzMTwAN4wiXGYizGOquxW2PG6QG/NyUAwLu5ud12222rVq1ykcMB8IRLwiXGYmzLNDanNEUwXuTx38VPKlVlAngXE4AnXBIuMRZjMdZ2YwE8gAfwhEuMxViMBfAIwAN4wiXGYizGAngE4AE84RJjMRZjATwC8FzVhEuMxViMBfAAHsBzVWMsxmIsxgJ4AA/gCZcYi7EYC+CRKwN+9M8yWq7T6TZt2jRhwoR//OMfX3zxhfgI4AmXGIuxGAvgkZNl8PUBv2fPnoCAgMKbEjP79u0D8IRLjMVYjAXwyOkBP3369DNnzkjzYsZcn/4AnnCJsRiLsQAeORPgx48fX1FRIc2LmQkTJgB4wiXGYizGAnjk9IB/5pln9M/dxczf/vY3w//O/VlPPfVUUFBQmQKJS6W0tLTMGVRYWFhUVOQUu+pErmIsxmJsMxoL4AG80gz+nz9r6NChgYGBJQokrpPi4uISZ1BBQYG4sJ1iV53IVYzFWIxtRmMBPID/Rcqfwfv5+c11LT311FOud1AYi7GoJRsrjgXAA/hbioiIEIyXWtGLGXOt6A8dOvRPl9PQoUPFxfBPhLEYi7EuZGxSUhI0bVmAH/1r6Zfr34MX2rx5s7n34F1S1GVhLMYijEUuksEjrmqMxViEsQjAI4QQQgjAI4QQQgjAI4QQQgAeIYQQQgAeIYQQQgC+pSkhISEoKGjs2LETJ05cunRpSUkJnthFcXFxs2bNGjNmjDA2JCSkoKAAT+wrYW/93iyQzTL3/jBCAN5ZNXv27Pj4eLVaLdC+du1aAXs8sYsCAwOjoqLKy8tVKtU333wzffp0PLGjDh06JCyFQ/YFPCYgAO+yqqysFBknPthdGo1m7Nix+GAvlZWVTZ48OSsrCyYBeATgkSJFR0eTaNpdarV627Zt8+bNwwp76dNPP92xYwdMsjvgJ06c6OfnN2XKFHHG1tTU4AkC8C6ijIyMl19+WfzFCvsGTSF/f//r16/jhl2UlpYmbkOlnqQBvN0luH7p0qXAwMD169fjBgLwrqDk5GRB97Nnz2KF3VVRUREaGjpr1iyssIsE3TMzM/X3TxjSGCoqKjIaLxshAO+UOn78+EsvvSQSI6xoJGk0Gho32Euj6wlP7K6SkpLx48fjAwLwzq2wsLDJkydfvXoVK+yrZcuWCVerq6tFMrRx48bAwEA8aQzYY4K9FBIScvnyZXHGZmdnz5s3b8WKFXiCALyr5UNqtRpbGq7IyMi3337bz8/P39//k08+oYMBAO8sZ+ykSZM2bNig0WjwBAF4hBBCCAF4hBBCCMAjhBBCCMAjhBBCCMAjhBBCCMAjhBBCCMAjhBBCCMAjhBBCAB4hhBBCAB4hhBBCAB4hV72u3NyMZhqyEoQQAvAIAXiEEALwCDUy4Jt9JQghAI8Qsl3/+c9/evfu3aZNmz59+qxbt65+Bp+amvrXv/61c+fObdu2ffjhh0NDQ/UFRHnxLfFdsYZNmzYBeIQQgEfIIbRjx4777rsvJiZGo9GcOnXqd7/7XX3A+/j4rFq1qrS0VJQRJceMGaMvoP9udHS0YLxYG4BHCAF4hJpfgwcP3rdvn/7jnj176gPew8MjKyvLxBXo5mb0XbE2AI8QAvAINb/at2+vUqn0HysqKuoDfurUqV27dn3jjTc2b96cmZlpCHij74q1AXiEEIBHyDkAL5SQkBASEvLcc895eXktWrQIwCOEADxCDi0lVfSGunjxYocOHfQFqKJHCAF4hBxR27Zt69OnT0xMTFVVVXR0tMlGdiNGjNi/f395eXlZWdnnn3/+4IMP6gsYfrd3797bt28H8AghAI+QQ2jDhg29evWSeU1u9+7djz/+eLt27Tp37jxq1Ki0tDR9gbVr1953333u7u7izmDjxo2/XJwAHiEE4BFy1isQiiOEADxCAB4hhAA8QgAeIQTgEUIIIQTgEUIIIQTgEUIIIQTgEUIIIQTgEUIIIQTgEUIIIQCPEEIIIQCPEEIIIUfQ/wcVYdzjAw2QcQAAAABJRU5ErkJggg==" /><!-- --></p>
547
+ <p><img src="data:image/png;base64,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eBm7ZE6izOUns0GEEALw/43CMlX00ivUkr7//nu7AV9aWvq///u/GzZskEHd+fPnRWZm86iM323SpIlEhdqH16dPn23bttXehaDX/v37626afdtp1KiRWXJvJgHLX//613FxcbGxsV26dDGy05pLZhIu9ejRw1orevnD+PzzzydPnixuI0Qyba2e3/SniTsJcathWk8uA3gZu2ROoszlJ7NBhBAC8P+NwlJTJpE8Sc3ZRKot/SsyMvI3v/nN0aNHpTeqxbzaRnY6ne7ixYufffZZUFDQv/71r9orDBgwQARugX+RkH366acPPvigzaMyflckkdOmTSsoKBBI++677+655x7jv8THe++9d+/eveIATBvZ7dmzRySd8fHx5eXlYqfio7HnFlWm2bedwMDAH374QZ7xCxcuHDZs2NChQxctWmRcaM2l2hKQFraIm5sbN25Yew/e4mEIqItf9Le//W3mzJmqKmaUAF7GLpmTKHP5yWwQIYQA/H+j8IoVK+677z5fX1+RPq5Zs8Z0tZUrV3bq1El6T2nZsmVNmzZVCHhJzZs3F9t87rnnRHJpce/bt29/4oknpDfKBg0alJ6ebvOojN8V5H7qqaf8/PzE1x966CFxG2GWYkqvUXXu3Nn06yLz69evX8uWLcWx9e3b15joqzLNvu188cUXIj8WCbSMdQLMv7wlMWNcaM0li4qJifnzn/981113GXuyE/xTchjLly8XduXk5Dgc8DJ2yZ9EmcvP2gYRQsiTAV/HuwFrSkpKEom4qx0VcpRmz55tbGrngnLm5YcQAvCeD3gR8c+dO6fX61NSUnr27BkREQHgPVJxcXFt27a9ePGiSx1VQ11+CCEA7/mAX7duXdeuXX19fTt16jRjxgyLzb4AvAdcA+3bt9++fburHVhDXX4IIQCPEEIIIQCPEEIIIQCPEEIIIQCPEEIIIQCPEEIIIQCPEEIIAXiEEEIIAXjHKSUlZTpCCCGX14ULF6ApgFehf/7zn08//fQ/FejVV1/9xz/+8U930JgxY1555RW3OFQ3chVjcRVXG9DVvn37CsZDUwCvDvAKL5ry8vKKigq3sPvGjRvuMvi3G7mKsbiKqw3oqvJYjQA8gCdiYiyu4iqARwCesg3gMRZXcRXAIwBP2QbwGIuruArgATyAp2wDeFCEq7gK4AE8gCdiYiyXK64CeATgATwR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" /><!-- --></p>
519
548
  </div>
520
549
  <div id="ruby-chunks" class="section level3">
521
550
  <h3>Ruby chunks</h3>
522
551
  <p>Including a Ruby chunk is just as easy as including an R chunk in the document: just change the name of the engine to ‘ruby’. It is also possible to pass chunk options to the Ruby engine; however, this version does not accept all the options that are available to R chunks. Future versions will add those options.</p>
523
552
  <pre><code>```{ruby first_ruby_chunk}
524
553
  ```</code></pre>
525
- <p>In this example, the ruby chunk is called ‘first_ruby_chunk’. One important aspect of chunk labels is that they cannot be duplicated. If a chunk label is duplicated, gKnitting will stop with an error.</p>
526
- <p>Another relevant point with Ruby chunks is that they are evaluated in the scope of a class called RubyChunk. To make sure that variables are available between chunks, they should be made as instance variables of the RubyChunk class. In the following chunk, variable ‘@a’, ‘@b’ and ‘@c’ are standard Ruby variables and ‘@vec’ and ‘@vec2’ are two vectors created by calling the ‘c’ method on the R module.</p>
527
- <p>In Galaaz, the R module allows us to access R functions transparently. The ‘c’ function in R, is a function that concatenates its arguments making a vector. Calling the ‘c’ method in the R module is automatically converted to calling the ‘c’ function in R, that, through Galaaz and the Truffle interface creates the vector.</p>
554
+ <p>In this example, the ruby chunk is called ‘first_ruby_chunk’. One important aspect of chunk labels is that they cannot be duplicated. If a chunk label is duplicated, gKnit will stop with an error.</p>
555
+ <p>Another important point with Ruby chunks is that they are evaluated in the scope of a class called RubyChunk. To make sure that variables are available between chunks, they should be made as instance variables of the RubyChunk class. In the following chunk, variable ‘@a’, ‘@b’ and ‘@c’ are standard Ruby variables and ‘@vec’ and ‘@vec2’ are two vectors created by calling the ‘c’ method on the R module.</p>
556
+ <p>In Galaaz, the R module allows us to access R functions transparently. The ‘c’ function in R, is a function that concatenates its arguments making a vector.</p>
528
557
  <p>It should be clear that there is no requirement in gknit to call or use any R functions. gKnit will knit standard Ruby code, or even general text without any code.</p>
529
558
  <pre class="ruby"><code>@a = [1, 2, 3]
530
559
  @b = &quot;US$ 250.000&quot;
@@ -537,7 +566,7 @@ g + geom_jitter(aes(col=manufacturer, size=hwy)) +
537
566
  puts @vec * @vec2</code></pre>
538
567
  <pre><code>## [1, 2, 3]
539
568
  ## [1] 10 40 90</code></pre>
540
- <p>Note that <span class="citation">@a</span> is a standard Ruby Array and <span class="citation">@vec</span> and <span class="citation">@vec2</span> are vectors that behave accordingly, where multiplication works as expected.</p>
569
+ <p>Note that @a is a standard Ruby Array and @vec and @vec2 are vectors that behave accordingly, where multiplication works as expected.</p>
541
570
  </div>
542
571
  <div id="accessing-r-from-ruby" class="section level3">
543
572
  <h3>Accessing R from Ruby</h3>
@@ -550,7 +579,7 @@ puts @vec * @vec2</code></pre>
550
579
  </div>
551
580
  <div id="ruby-plotting" class="section level3">
552
581
  <h3>Ruby Plotting</h3>
553
- <p>We have seen an example of plotting with R. Plotting with Ruby does not require anything different from plotting with R. In the following example we plot a diverging bar graph using the ‘mtcars’ dataframe from R. This data was extracted from the 1974 Motor Trend US magazine, and comprises fuel consumption and 10 aspects of automobile design and performance for 32 automobiles (1973–74 models). The ten aspects are:</p>
582
+ <p>We have seen an example of plotting with R. Plotting with Ruby does not require anything different from plotting with R. In the following example, we plot a diverging bar graph using the ‘mtcars’ dataframe from R. This data was extracted from the 1974 Motor Trend US magazine, and comprises fuel consumption and 10 aspects of automobile design and performance for 32 automobiles (1973–74 models). The ten aspects are:</p>
554
583
  <ul>
555
584
  <li>mpg: Miles/(US) gallon</li>
556
585
  <li>cyl: Number of cylinders</li>
@@ -564,17 +593,50 @@ puts @vec * @vec2</code></pre>
564
593
  <li>gear: Number of forward gears</li>
565
594
  <li>carb: Number of carburetors</li>
566
595
  </ul>
596
+ <pre class="ruby"><code># copy the R variable :mtcars to the Ruby mtcars variable
597
+ @mtcars = ~:mtcars
598
+
599
+ # create a new column 'car_name' to store the car names so that it can be
600
+ # used for plotting. The 'rownames' of the data frame cannot be used as
601
+ # data for plotting
602
+ @mtcars.car_name = R.rownames(:mtcars)
603
+
604
+ # compute normalized mpg and add it to a new column called mpg_z
605
+ # Note that the mean value for mpg can be obtained by calling the 'mean'
606
+ # function on the vector 'mtcars.mpg'. The same with the standard
607
+ # deviation 'sd'. The vector is then rounded to two digits with 'round 2'
608
+ @mtcars.mpg_z = ((@mtcars.mpg - @mtcars.mpg.mean)/@mtcars.mpg.sd).round 2
609
+
610
+ # create a new column 'mpg_type'. Function 'ifelse' is a vectorized function
611
+ # that looks at every element of the mpg_z vector and if the value is below
612
+ # 0, returns 'below', otherwise returns 'above'
613
+ @mtcars.mpg_type = (@mtcars.mpg_z &lt; 0).ifelse(&quot;below&quot;, &quot;above&quot;)
614
+
615
+ # order the mtcar data set by the mpg_z vector from smaler to larger values
616
+ @mtcars = @mtcars[@mtcars.mpg_z.order, :all]
617
+
618
+ # convert the car_name column to a factor to retain sorted order in plot
619
+ @mtcars.car_name = @mtcars.car_name.factor levels: @mtcars.car_name
620
+
621
+ # let's look at the first records of the final data frame
622
+ puts @mtcars.head</code></pre>
623
+ <pre><code>## mpg cyl disp hp drat wt qsec vs am gear carb
624
+ ## Cadillac Fleetwood 10.4 8 472 205 2.93 5.250 17.98 0 0 3 4
625
+ ## Lincoln Continental 10.4 8 460 215 3.00 5.424 17.82 0 0 3 4
626
+ ## Camaro Z28 13.3 8 350 245 3.73 3.840 15.41 0 0 3 4
627
+ ## Duster 360 14.3 8 360 245 3.21 3.570 15.84 0 0 3 4
628
+ ## Chrysler Imperial 14.7 8 440 230 3.23 5.345 17.42 0 0 3 4
629
+ ## Maserati Bora 15.0 8 301 335 3.54 3.570 14.60 0 1 5 8
630
+ ## car_name mpg_z mpg_type
631
+ ## Cadillac Fleetwood Cadillac Fleetwood -1.61 below
632
+ ## Lincoln Continental Lincoln Continental -1.61 below
633
+ ## Camaro Z28 Camaro Z28 -1.13 below
634
+ ## Duster 360 Duster 360 -0.96 below
635
+ ## Chrysler Imperial Chrysler Imperial -0.89 below
636
+ ## Maserati Bora Maserati Bora -0.84 below</code></pre>
567
637
  <pre class="ruby"><code>require 'ggplot'
568
638
 
569
- mtcars = ~:mtcars
570
-
571
- mtcars.car_name = mtcars.rownames # create new column for car names
572
- mtcars.mpg_z = ((mtcars.mpg - mtcars.mpg.mean) / mtcars.mpg.sd).round 2
573
- mtcars.mpg_type = (mtcars.mpg_z &lt; 0).ifelse('below', 'above')
574
- mtcars = mtcars[mtcars.mpg_z.order, :all]
575
- mtcars.car_name = R.factor(mtcars.car_name, levels: mtcars.car_name)
576
-
577
- puts mtcars.ggplot(E.aes(x: :car_name, y: :mpg_z, label: :mpg_z)) +
639
+ puts @mtcars.ggplot(E.aes(x: :car_name, y: :mpg_z, label: :mpg_z)) +
578
640
  R.geom_bar(E.aes(fill: :mpg_type), stat: 'identity', width: 0.5) +
579
641
  R.scale_fill_manual(name: 'Mileage',
580
642
  labels: R.c('Above Average', 'Below Average'),
@@ -591,7 +653,6 @@ puts mtcars.ggplot(E.aes(x: :car_name, y: :mpg_z, label: :mpg_z)) +
591
653
  ```{rb puts @b}
592
654
  ```
593
655
  and is followed by some other text!</code></pre>
594
- <p>Note that it is important not to add any new line before of after the code block if we want everything to be in only one line, resulting in the following sentence with inline Ruby code</p>
595
656
  <div style="margin-bottom:30px;">
596
657
 
597
658
  </div>
@@ -599,21 +660,22 @@ and is followed by some other text!</code></pre>
599
660
  <div style="margin-bottom:30px;">
600
661
 
601
662
  </div>
663
+ <p>Note that it is important not to add any new line before of after the code block if we want everything to be in only one line, resulting in the following sentence with inline Ruby code.</p>
602
664
  </div>
603
665
  <div id="the-outputs-function" class="section level3">
604
666
  <h3>The ‘outputs’ function</h3>
605
- <p>He have previously used the standard ‘puts’ method in Ruby chunks in order to get some output. As can be seen, the result of a ‘puts is formatted inside a white box that follows the code block. Many times however, we would like to do some processing in the Ruby chunk and have the result of this processing generate and output that is included in the document as if we had typed it in R markdown.</p>
606
- <p>For example, suppose we want to create a new heading in our document, but the heading phrase is the result of some code processing: maybe it’s the first line of a file we are going to read. Method ‘outputs’ adds its output as if typed in the R markdown document.</p>
607
- <p>Take now a look at variable ‘<span class="citation">@c</span>’ (it was defined in a previous block above) as ‘<span class="citation">@c</span> = “The ‘outputs’ function”. “The ‘outputs’ function” is actually the name of this section and it was created using the ’outputs’ function inside a Ruby chunk.</p>
667
+ <p>He have previously used the standard ‘puts’ method in Ruby chunks in order produce output. The result of a ‘puts’, as seen in all previous chunks that use it, is formatted inside a white box that follows the code block. Many times however, we would like to do some processing in the Ruby chunk and have the result of this processing generate and output that is included in the document as if we had typed it in <strong>R markdown</strong> document.</p>
668
+ <p>For example, suppose we want to create a new heading in our document, but the heading phrase is the result of some code processing: maybe it’s the first line of a file we are going to read. Method ‘outputs’ adds its output as if typed in the <strong>R markdown</strong> document.</p>
669
+ <p>Take now a look at variable ‘@c (it was defined in a previous block above) as ‘@c = “The ‘outputs’ function”. “The ‘outputs’ function” is actually the name of this section and it was created using the ’outputs’ function inside a Ruby chunk.</p>
608
670
  <p>The ruby chunk to generate this heading is:</p>
609
671
  <pre><code>```{ruby heading}
610
672
  outputs &quot;### #{@c}&quot;
611
673
  ```</code></pre>
612
- <p>The three ‘###’ are the way we add a Heading 3 in R markdown.</p>
674
+ <p>The three ‘###’ is the way we add a Heading 3 in <strong>R markdown</strong>.</p>
613
675
  </div>
614
676
  <div id="html-output-from-ruby-chunks" class="section level3">
615
677
  <h3>HTML Output from Ruby Chunks</h3>
616
- <p>We’ve just seen the use of method ‘outputs’ to add text to the the R markdown document. This technique can also be used to add HTML code to the document. In R markdown any html code typed directly in the document will be properly rendered.<br />
678
+ <p>We’ve just seen the use of method ‘outputs’ to add text to the the <strong>R markdown</strong> document. This technique can also be used to add HTML code to the document. In <strong>R markdown</strong>, any html code typed directly in the document will be properly rendered.<br />
617
679
  Here, for instance, is a table definition in HTML and its output in the document:</p>
618
680
  <pre><code>&lt;table style=&quot;width:100%&quot;&gt;
619
681
  &lt;tr&gt;
@@ -673,12 +735,10 @@ Jackson
673
735
  <div style="margin-bottom:30px;">
674
736
 
675
737
  </div>
676
- <p>But manually creating HTML output is not always easy or desirable. The above table certainly looks ugly. The ‘kableExtra’ library is a great library for creating beautiful tables. Take a look at <a href="https://cran.r-project.org/web/packages/kableExtra/vignettes/awesome_table_in_html.html" class="uri">https://cran.r-project.org/web/packages/kableExtra/vignettes/awesome_table_in_html.html</a></p>
738
+ <p>But manually creating HTML output is not always easy or desirable, specially if we intend the document to be rendered in other formats, for example, as Latex. Also, The above table looks ugly. The ‘kableExtra’ library is a great library for creating beautiful tables. Take a look at <a href="https://cran.r-project.org/web/packages/kableExtra/vignettes/awesome_table_in_html.html" class="uri">https://cran.r-project.org/web/packages/kableExtra/vignettes/awesome_table_in_html.html</a></p>
677
739
  <p>In the next chunk, we output the ‘mtcars’ dataframe from R in a nicely formatted table. Note that we retrieve the mtcars dataframe by using ‘~:mtcars’.</p>
678
740
  <pre class="ruby"><code>R.install_and_loads('kableExtra')
679
741
  outputs (~:mtcars).kable.kable_styling</code></pre>
680
- <pre><code>## The following packages are missing and will be installed:
681
- ## [1] &quot;kableExtra&quot;</code></pre>
682
742
  <table class="table" style="margin-left: auto; margin-right: auto;">
683
743
  <thead>
684
744
  <tr>
@@ -1939,15 +1999,15 @@ Volvo 142E
1939
1999
  </tbody>
1940
2000
  </table>
1941
2001
  </div>
1942
- <div id="including-ruby-files" class="section level3">
1943
- <h3>Including Ruby files</h3>
1944
- <p>R is a language that was created to be easy and fast for statisticians to use. As far as I know (and please correct me if you think otherwise), tt was not a language to be used for developing large systems. Of course, there are large systems and libraries in R, but the focus of the language is for developing statistical models and distribute that to peers.</p>
1945
- <p>Ruby on the other hand, is a language for large software development. Systems written in Ruby will have dozens, hundreds or even thousands of files. In order to document a large system with literate programming we cannot expect the developer to add all the files in a single ‘.Rmd’ file. gKnit provides the ‘include’ chunk engine to include a Ruby file as if it had being typed in the ‘.Rmd’ file.</p>
1946
- <p>To include a file, the following chunk should be created, where <filename> is the name of the file to be include and where the extension, if it is ‘.rb’, does not need to be added. If the ‘relative’ option is not included, then it is treated as TRUE. When ‘relative’ is true, ‘require_relative’ semantics is used to load the file, when false, Ruby’s $LOAD_PATH is searched to find the file and it is ’require’d.</p>
2002
+ <div id="including-ruby-files-in-a-chunk" class="section level3">
2003
+ <h3>Including Ruby files in a chunk</h3>
2004
+ <p>R is a language that was created to be easy and fast for statisticians to use. As far as I know, it was not a language to be used for developing large systems. Of course, there are large systems and libraries in R, but the focus of the language is for developing statistical models and distribute that to peers.</p>
2005
+ <p>Ruby on the other hand, is a language for large software development. Systems written in Ruby will have dozens, hundreds or even thousands of files. To document a large system with literate programming, we cannot expect the developer to add all the files in a single ‘.Rmd’ file. gKnit provides the ‘include’ chunk engine to include a Ruby file as if it had being typed in the ‘.Rmd’ file.</p>
2006
+ <p>To include a file, the following chunk should be created, where <filename> is the name of the file to be included and where the extension, if it is ‘.rb’, does not need to be added. If the ‘relative’ option is not included, then it is treated as TRUE. When ‘relative’ is true, ruby’s ‘require_relative’ semantics is used to load the file, when false, Ruby’s $LOAD_PATH is searched to find the file and it is ’require’d.</p>
1947
2007
  <pre><code>```{include &lt;filename&gt;, relative = &lt;TRUE/FALSE&gt;}
1948
2008
  ```</code></pre>
1949
- <p>Here we include file ‘model.rb which is in the same directory of this blog.<br />
1950
- This code uses R ‘caret’ package to split a dataset in a train and test sets. The ‘caret’ package is a very important a useful package for doing Data Analysis, it has hundreds of functions for all steps of the Data Analysis workflow. To just split a dataset it is using the proverbial cannon to kill the fly. We use it here only to show that integrating Ruby and R and using even a very comples package as ‘caret’ is trivial with Galaaz.</p>
2009
+ <p>Bellow we include file ‘model.rb’, which is in the same directory of this blog.<br />
2010
+ This code uses R ‘caret’ package to split a dataset in a train and test sets. The ‘caret’ package is a very important a useful package for doing Data Analysis, it has hundreds of functions for all steps of the Data Analysis workflow. To use ‘caret’ just to split a dataset is like using the proverbial cannon to kill the fly. We use it here only to show that integrating Ruby and R and using even a very complex package as ‘caret’ is trivial with Galaaz.</p>
1951
2011
  <p>A word of advice: the ‘caret’ package has lots of dependencies and installing it in a Linux system is a time consuming operation. Method ‘R.install_and_loads’ will install the package if it is not already installed and can take a while.</p>
1952
2012
  <pre><code>```{include model}
1953
2013
  ```</code></pre>
@@ -2013,8 +2073,8 @@ puts model.test.head</code></pre>
2013
2073
  </div>
2014
2074
  <div id="documenting-gems" class="section level3">
2015
2075
  <h3>Documenting Gems</h3>
2016
- <p>gKnit also allows developers to document and load files that are not in the same directory of the ‘.Rmd’ file. When using ‘relative = FALSE’ in a chunk header, gKnit will look for the file in Ruby’s $LOAD_PATH and load it if found.</p>
2017
- <p>Here is an example of loading the ‘find.rb’ file from TruffleRuby.</p>
2076
+ <p>gKnit also allows developers to document and load files that are not in the same directory of the ‘.Rmd’ file.</p>
2077
+ <p>Here is an example of loading the ‘find.rb’ file from TruffleRuby. In this example, relative is set to FALSE, so Ruby will look for the file in its $LOAD_PATH, and the user does not need to no it’s directory.</p>
2018
2078
  <pre><code>```{include find, relative = FALSE}
2019
2079
  ```</code></pre>
2020
2080
  <pre class="include"><code># frozen_string_literal: true
@@ -2109,7 +2169,7 @@ end</code></pre>
2109
2169
  </div>
2110
2170
  <div id="converting-to-pdf" class="section level2">
2111
2171
  <h2>Converting to PDF</h2>
2112
- <p>One of the beauties of knitr is that the same input can be converted to many different outputs. One very useful format, is, of course, PDF. In order to converted an R markdown file to PDF it is necessary to have LaTeX installed on the system. We will not explain here how to install LaTeX as there are plenty of documents on the web showing how to proceed.</p>
2172
+ <p>One of the beauties of knitr is that the same input can be converted to many different outputs. One very useful format, is, of course, PDF. In order to converted an <strong>R markdown</strong> file to PDF it is necessary to have LaTeX installed on the system. We will not explain here how to install LaTeX as there are plenty of documents on the web showing how to proceed.</p>
2113
2173
  <p>gKnit comes with a simple LaTeX style file for gknitting this blog as a PDF document. Here is the Yaml header to generate this blog in PDF format instead of HTML:</p>
2114
2174
  <pre><code>---
2115
2175
  title: &quot;gKnit - Ruby and R Knitting with Galaaz in GraalVM&quot;
@@ -2119,15 +2179,16 @@ date: &quot;29 October 2018&quot;
2119
2179
  output:
2120
2180
  pdf_document:
2121
2181
  includes:
2122
- in_header: [&quot;../../sty/galaaz.sty&quot;]
2123
- number_sections: yes
2182
+ in\_header: [&quot;../../sty/galaaz.sty&quot;]
2183
+ number\_sections: yes
2124
2184
  ---</code></pre>
2125
2185
  </div>
2126
2186
  </div>
2127
2187
  <div id="conclusion" class="section level1">
2128
2188
  <h1>Conclusion</h1>
2129
- <p>One of the promises of GraalVM is that users/developers will be able to use the best tool for their task at hand, independently of the programming language the tool was written. Galaaz and gKnit are not trivial implementations atop the GraalVM and Truffle interop messages; however, the time and effort it took to wrap Ruby over R - Galaaz - (not finished yet) or to wrap Knitr with gKnit is a fraction of a fraction of a fraction of the time require to implement the original tools. Trying to reimplement all R packages in Ruby would require the same effort it is taking Python to implement NumPy, Panda and all supporting libraries and it is unlikely that this effort would ever be done. GraalVM has allowed Ruby to profit “almost for free” from this huge set of libraries and tools that make R one of the most used languages for data analysis and machine learning.</p>
2130
- <p>More interesting though than being able to wrap the R libraries with Ruby, is that Ruby adds value to R, by allowing developers to use powerful and modern constructs for code reuse that are not the strong points of R. As shown in this blog, R and Ruby can easily communicate and R can be structured in classes and modules in a way that greatly expands its power and readability.</p>
2189
+ <p>In order to do reproducible research, one of the main basic tools needed is a systhem that allows “literate programming” where text, code and possibly a set of files can be compiled onto a report that can be easily distributed to peers. Peers should be able to use this same set of files to rerun the compilation by their own obtaining the exact same original report. gKnit is such a system for Ruby and R. It uses <strong>R Markdown</strong> to integrate text and code chunks, where code chunks can either be part of the <strong>R Markdwon</strong> file or be imported from files in the system. Ideally, in reproducible research, all the files needed to rebuild a report should be easilly packed together (in the same zipped directory) and distributed to peers for reexecution.</p>
2190
+ <p>One of the promises of Oracle’s GraalVM is that users/developers will be able to use the best tool for their task at hand, independently of the programming language the tool was written on. We developed and implemented Galaaz atop the GraalVM and Truffle interop messages and the time and effort to wrap Ruby over R - Galaaz - or to wrap Knitr with gKnit was a fraction of a fraction of a fraction (one man effort for a couple of hours a day, for approximately six months) of the time require to implement the original tools. Trying to reimplement all R packages in Ruby would require the same effort it is taking Python to implement NumPy, Pandas and all supporting libraries and it is unlikely that this effort would ever be done. GraalVM has allowed Ruby to profit “almost for free” from this huge set of libraries and tools that make R one of the most used languages for data analysis and machine learning.</p>
2191
+ <p>More interesting than wrapping the R libraries with Ruby, is that Ruby adds value to R, by allowing developers to use powerful and modern constructs for code reuse that are not the strong points of R. As shown in this blog, R and Ruby can easily communicate and R can be structured in classes and modules in a way that greatly expands its power and readability.</p>
2131
2192
  </div>
2132
2193
  <div id="installing-gknit" class="section level1">
2133
2194
  <h1>Installing gKnit</h1>
@@ -2159,6 +2220,17 @@ output:
2159
2220
  </ul>
2160
2221
  </div>
2161
2222
  </div>
2223
+ <div id="references" class="section level1 unnumbered">
2224
+ <h1>References</h1>
2225
+ <div id="refs" class="references">
2226
+ <div id="ref-Knuth:literate_programming">
2227
+ <p>Knuth, Donald E. 1984. “Literate Programming.” <em>Comput. J.</em> 27 (2). Oxford, UK: Oxford University Press: 97–111. <a href="https://doi.org/10.1093/comjnl/27.2.97" class="uri">https://doi.org/10.1093/comjnl/27.2.97</a>.</p>
2228
+ </div>
2229
+ <div id="ref-Wilkinson:grammar_of_graphics">
2230
+ <p>Wilkinson, Leland. 2005. <em>The Grammar of Graphics (Statistics and Computing)</em>. Berlin, Heidelberg: Springer-Verlag.</p>
2231
+ </div>
2232
+ </div>
2233
+ </div>
2162
2234
 
2163
2235
 
2164
2236
 
@@ -5,6 +5,7 @@ author:
5
5
  - "Daniel Mossé - University of Pittsburgh"
6
6
  tags: [Tech, Data Science, Ruby, R, GraalVM]
7
7
  date: "20/02/2019"
8
+ bibliography: stats.bib
8
9
  output:
9
10
  html_document:
10
11
  self_contained: true
@@ -19,7 +20,8 @@ output:
19
20
 
20
21
  # Introduction
21
22
 
22
- The idea of "literate programming" was first introduced by Donald Knuth in the 1980's.
23
+ The idea of "literate programming" was first introduced by Donald Knuth in the
24
+ 1980's [@Knuth:literate_programming].
23
25
  The main intention of this approach was to develop software interspersing macro snippets,
24
26
  traditional source code, and a natural language such as English in a document
25
27
  that could be compiled into
@@ -35,19 +37,22 @@ single document or set of documents that when distributed to peers could be reru
35
37
  the same output and reports.
36
38
 
37
39
  The R community has put a great deal of effort in reproducible research. In 2002, Sweave was
38
- introduced and it allowed mixing R code with Latex generating high quality PDF documents. Those
39
- documents could include the code, the result of executing the code, graphics and text. This
40
- contained the whole narrative to reproduce the research. But Sweave had many problems and in
41
- 2012, Knitr, developed by Yihui Xie from RStudio was released, solving many of the long lasting
42
- problems from Sweave and including in one single package many extensions and add-on packages that
40
+ introduced and it allowed mixing R code with Latex generating high quality PDF documents. A
41
+ Sweave
42
+ document could include code, the results of executing the code, graphics and text such that it
43
+ contained the whole narrative to reproduce the research. In
44
+ 2012, Knitr, developed by Yihui Xie from RStudio was released to replace Sweave and to
45
+ consolidate in one single package the many extensions and add-on packages that
43
46
  were necessary for Sweave.
44
47
 
45
- With Knitr, R markdown was also developed, an extension to the
46
- Markdown format. With R markdown and Knitr it is possible to generate reports in a multitude
47
- of formats such as HTML, markdown, Latex, PDF, dvi, etc. R markdown also allows the use of
48
- multiple programming languages in the same document. In R markdown text is interspersed with
48
+ With Knitr, __R markdown__ was also developed, an extension to the
49
+ Markdown format. With __R markdown__ and Knitr it is possible to generate reports in a multitude
50
+ of formats such as HTML, markdown, Latex, PDF, dvi, etc. __R markdown__ also allows the use of
51
+ multiple programming languages such as R, Ruby, Python, etc. in the same document.
52
+
53
+ In __R markdown__, text is interspersed with
49
54
  code chunks that can be executed and both the code and its results can become
50
- part of the final report. Although R markdown allows multiple programming languages in the
55
+ part of the final report. Although __R markdown__ allows multiple programming languages in the
51
56
  same document, only R and Python (with
52
57
  the reticulate package) can persist variables between chunks. For other languages, such as
53
58
  Ruby, every chunk will start a new process and thus all data is lost between chunks, unless it
@@ -55,46 +60,102 @@ is somehow stored in a data file that is read by the next chunk.
55
60
 
56
61
  Being able to persist data
57
62
  between chunks is critical for literate programming otherwise the flow of the narrative is lost
58
- by all the effort of having to save data and then reload it. Probably, because of
59
- this impossibility,
60
- it is very rare to see any R markdown document in the Ruby community. Also, the use of
61
- R markdown for the Ruby community would also require the Ruby developer to download R and
62
- have some minimal knowledge of Knitr.
63
+ by all the effort of having to save data and then reload it. Although this might, at first, seem like
64
+ a small nuisance, not being able to persist data between chunks is a major issue. For example, let's
65
+ take a look at the following simple example in which we want to show how to create a list and the
66
+ use it. Let's first assume that data cannot be persisted between chunks. In the next chunk we
67
+ create a list, then we would need to save it to file, but to save it, we need somehow to marshal the
68
+ data into a binary format:
69
+
70
+
71
+ ```ruby
72
+ lst = R.list(a: 1, b: 2, c: 3)
73
+ lst.saveRDS("lst.rds")
74
+ ```
75
+ then, on the next chunk, where variable 'lst' is used, we need to read back it's value
76
+
77
+
78
+ ```ruby
79
+ lst = R.readRDS("lst.rds")
80
+ puts lst
81
+ ```
82
+
83
+ ```
84
+ ## $a
85
+ ## [1] 1
86
+ ##
87
+ ## $b
88
+ ## [1] 2
89
+ ##
90
+ ## $c
91
+ ## [1] 3
92
+ ```
93
+
94
+ Now, any single code has dozens of variables that we might want to use and reuse between chunks.
95
+ Clearly, such an approach becomes quickly unmanageable. Probably, because of
96
+ this problem, it is very rare to see any __R markdown__ document in the Ruby community.
97
+
98
+ When variables can be used accross chunks, then no overhead is needed:
99
+
100
+
101
+ ```ruby
102
+ @lst = R.list(a: 1, b: 2, c: 3)
103
+ # any other code can be added here
104
+ ```
105
+
106
+
107
+ ```ruby
108
+ puts @lst
109
+ ```
110
+
111
+ ```
112
+ ## $a
113
+ ## [1] 1
114
+ ##
115
+ ## $b
116
+ ## [1] 2
117
+ ##
118
+ ## $c
119
+ ## [1] 3
120
+ ```
63
121
 
64
122
  In the Python community, the same effort to have code and text in an integrated environment
65
123
  started around the first decade of 2000. In 2006 iPython 0.7.2 was released. In 2014,
66
124
  Fernando Pérez, spun off project Jupyter from iPython creating a web-based interactive
67
125
  computation environment. Jupyter can now be used with many languages, including Ruby with the
68
- iruby gem (https://github.com/SciRuby/iruby). I am not sure if multiple languages can be used
69
- in a Jupyter notebook and if variables can persist between chunks.
126
+ iruby gem (https://github.com/SciRuby/iruby). In order to have multiple languages in a Jupyter
127
+ notebook the SoS kernel was developed (https://vatlab.github.io/sos-docs/).
70
128
 
71
129
  # gKnitting a Document
72
130
 
73
- This document describes gKnit. gKnit uses Knitr and R markdown to knit a document in Ruby or R
74
- and output it in any of the available formats for R markdown.
131
+ This document describes gKnit. gKnit is based on knitr and __R markdown__ and can knit a document
132
+ written both in Ruby and/or R and output it in any of the available formats of __R markdown__. gKnit
133
+ allows ruby developers to do literate programming and reproducible research by allowing them to
134
+ have in a single document, text and code.
135
+
75
136
  gKnit runs atop of GraalVM, and Galaaz (an integration
76
- library between Ruby and R). In gKnit, Ruby variables are persisted between chunks, making
77
- it an ideal solution for literate programming in this language. Also, since it is based on
78
- Galaaz, Ruby chunks can have access to R variables and Polyglot Programming with Ruby and R
79
- is quite natural.
137
+ library between Ruby and R - see bellow). In gKnit, Ruby variables are persisted between
138
+ chunks, making it an ideal solution for literate programming in this language. Also,
139
+ since it is based on Galaaz, Ruby chunks can have access to R variables and Polyglot Programming
140
+ with Ruby and R is quite natural.
80
141
 
81
- Galaaz has been describe already in the following posts:
142
+ Galaaz has already been describe in the following posts:
82
143
 
83
144
  * https://towardsdatascience.com/ruby-plotting-with-galaaz-an-example-of-tightly-coupling-ruby-and-r-in-graalvm-520b69e21021.
84
145
  * https://medium.freecodecamp.org/how-to-make-beautiful-ruby-plots-with-galaaz-320848058857
85
146
 
86
- This is not a blog post on R markdown, and the interested user is directed to the following links
147
+ This is not a blog post on __R markdown__, and the interested user is directed to the following links
87
148
  for detailed information on its capabilities and use.
88
149
 
89
150
  * https://rmarkdown.rstudio.com/ or
90
151
  * https://bookdown.org/yihui/rmarkdown/
91
152
 
92
- Here, we will describe quickly the main aspects of R markdown, so the user can start gKnitting
93
- Ruby and R documents quickly.
153
+ In this post, we will describe just the main aspects of __R markdown__, so the user can start
154
+ gKnitting Ruby and R documents quickly.
94
155
 
95
156
  ## The Yaml header
96
157
 
97
- An R markdown document should start with a Yaml header and be stored in a file with
158
+ An __R markdown__ document should start with a Yaml header and be stored in a file with
98
159
  '.Rmd' extension. This document has the following header for gKitting an HTML document.
99
160
 
100
161
  ```
@@ -118,7 +179,7 @@ output:
118
179
 
119
180
  For more information on the options in the Yaml header, check https://bookdown.org/yihui/rmarkdown/html-document.html.
120
181
 
121
- ## R Markdown formatting
182
+ ## __R Markdown__ formatting
122
183
 
123
184
  Document formatting can be done with simple markups such as:
124
185
 
@@ -154,7 +215,7 @@ Ordered Lists
154
215
  + Item 3b
155
216
  ```
156
217
 
157
- Please, go to https://rmarkdown.rstudio.com/authoring_basics.html, for more R markdown formatting.
218
+ For more R markdown formatting go to https://rmarkdown.rstudio.com/authoring_basics.html.
158
219
 
159
220
  ### R chunks
160
221
 
@@ -170,8 +231,7 @@ any optional chunk_label and options, as shown bellow:
170
231
  ````
171
232
 
172
233
  for instance, let's add an R chunk to the document labeled 'first_r_chunk'. This is
173
- a very simple code just to create a variable and print it out. The code block should
174
- be defined as follows:
234
+ a very simple code just to create a variable and print it out, as follows:
175
235
 
176
236
  ````
177
237
  ```{r first_r_chunk}
@@ -180,7 +240,7 @@ print(vec)
180
240
  ```
181
241
  ````
182
242
 
183
- If this block is added to an R markdown document and gKnitted the result will be:
243
+ If this block is added to an __R markdown__ document and gKnitted the result will be:
184
244
 
185
245
 
186
246
  ```r
@@ -210,9 +270,9 @@ and we only see the execution result in a white box
210
270
  ## [1] 10 40 90
211
271
  ```
212
272
 
213
- A description of the available chunk options can be found in the documentation cited above.
273
+ A description of the available chunk options can be found in https://yihui.name/knitr/.
214
274
 
215
- Let's add another R chunkd with a function definition. In this example, a vector
275
+ Let's add another R chunk with a function definition. In this example, a vector
216
276
  'r_vec' is created and
217
277
  a new function 'reduce_sum' is defined. The chunk specification is
218
278
 
@@ -226,8 +286,8 @@ reduce_sum <- function(...) {
226
286
  ```
227
287
  ````
228
288
 
229
- and this is how it will look like once executed. From now on, we will not
230
- show the chunk definition any longer.
289
+ and this is how it will look like once executed. From now on, to be concise in the
290
+ presentation we will not show chunk definitions any longer.
231
291
 
232
292
 
233
293
 
@@ -264,12 +324,29 @@ this document. Note that there is no directive in the code to include the image
264
324
  occurs automatically. The 'mpg' dataframe is natively available to R and to Galaaz as
265
325
  well.
266
326
 
327
+ For the reader not knowledgeable of ggplot, ggplot is a graphics library based on "the
328
+ grammar of graphics" [@Wilkinson:grammar_of_graphics]. The idea of the grammar of graphics
329
+ is to build a graphics by adding layers to the plot. More information can be found in
330
+ https://towardsdatascience.com/a-comprehensive-guide-to-the-grammar-of-graphics-for-effective-visualization-of-multi-dimensional-1f92b4ed4149.
331
+
332
+ In the plot bellow the 'mpg' dataset from base R is used. "The data concerns city-cycle fuel
333
+ consumption in miles per gallon, to be predicted in terms of 3 multivalued discrete and 5
334
+ continuous attributes." (Quinlan, 1993)
335
+
336
+ First, the 'mpg' dataset if filtered to extract only cars from the following manumactures: Audi, Ford,
337
+ Honda, and Hyundai and stored in the 'mpg_select' variable. Then, the selected dataframe is passed
338
+ to the ggplot function specifying in the aesthetic method (aes) that 'displacement' (disp) should
339
+ be plotted in the 'x' axis and 'city mileage' should be on the 'y' axis. In the 'labs' layer we
340
+ pass the 'title' and 'subtitle' for the plot. To the basic plot 'g', geom\_jitter is added, that
341
+ plots cars from the same manufactures with the same color (col=manufactures) and the size of the
342
+ car point equal its high way consumption (size = hwy). Finally, a last layer is plotter containing
343
+ a linear regression line (method = "lm") for every manufacturer.
344
+
267
345
 
268
346
  ```r
269
347
  # load package and data
270
348
  library(ggplot2)
271
349
  data(mpg, package="ggplot2")
272
- # mpg <- read.csv("http://goo.gl/uEeRGu")
273
350
 
274
351
  mpg_select <- mpg[mpg$manufacturer %in% c("audi", "ford", "honda", "hyundai"), ]
275
352
 
@@ -300,20 +377,17 @@ available to R chunks. Future versions will add those options.
300
377
 
301
378
  In this example, the ruby chunk is called 'first_ruby_chunk'. One important
302
379
  aspect of chunk labels is that they cannot be duplicated. If a chunk label is
303
- duplicated, gKnitting will stop with an error.
380
+ duplicated, gKnit will stop with an error.
304
381
 
305
- Another relevant point with Ruby chunks is that they are evaluated in the scope
382
+ Another important point with Ruby chunks is that they are evaluated in the scope
306
383
  of a class called RubyChunk. To make sure that variables are
307
384
  available between chunks, they should be made as instance variables of the
308
385
  RubyChunk class. In the following chunk, variable '\@a', '\@b' and '\@c'
309
386
  are standard Ruby variables and '\@vec' and '\@vec2' are two vectors created
310
387
  by calling the 'c' method on the R module.
311
388
 
312
- In Galaaz, the R module allows us to access R functions transparently. The 'c'
389
+ In Galaaz, the R module allows us to access R functions transparently. The 'c'
313
390
  function in R, is a function that concatenates its arguments making a vector.
314
- Calling the 'c' method in the R module is automatically converted to calling the
315
- 'c' function in R, that, through Galaaz and the Truffle interface creates the
316
- vector.
317
391
 
318
392
  It
319
393
  should be clear that there is no requirement in gknit to call or use any R
@@ -343,7 +417,7 @@ puts @vec * @vec2
343
417
  ## [1] 10 40 90
344
418
  ```
345
419
 
346
- Note that @a is a standard Ruby Array and @vec and @vec2 are vectors that behave accordingly,
420
+ Note that \@a is a standard Ruby Array and \@vec and \@vec2 are vectors that behave accordingly,
347
421
  where multiplication works as expected.
348
422
 
349
423
 
@@ -379,7 +453,7 @@ puts R.reduce_sum(~:r_vec)
379
453
  ### Ruby Plotting
380
454
 
381
455
  We have seen an example of plotting with R. Plotting with Ruby does not require
382
- anything different from plotting with R. In the following example we plot a
456
+ anything different from plotting with R. In the following example, we plot a
383
457
  diverging bar graph using the 'mtcars' dataframe from R. This data was extracted
384
458
  from the 1974 Motor Trend US magazine, and comprises fuel consumption and 10 aspects
385
459
  of automobile design and performance for 32 automobiles (1973–74 models). The
@@ -400,17 +474,57 @@ ten aspects are:
400
474
 
401
475
 
402
476
  ```ruby
403
- require 'ggplot'
477
+ # copy the R variable :mtcars to the Ruby mtcars variable
478
+ @mtcars = ~:mtcars
404
479
 
405
- mtcars = ~:mtcars
480
+ # create a new column 'car_name' to store the car names so that it can be
481
+ # used for plotting. The 'rownames' of the data frame cannot be used as
482
+ # data for plotting
483
+ @mtcars.car_name = R.rownames(:mtcars)
484
+
485
+ # compute normalized mpg and add it to a new column called mpg_z
486
+ # Note that the mean value for mpg can be obtained by calling the 'mean'
487
+ # function on the vector 'mtcars.mpg'. The same with the standard
488
+ # deviation 'sd'. The vector is then rounded to two digits with 'round 2'
489
+ @mtcars.mpg_z = ((@mtcars.mpg - @mtcars.mpg.mean)/@mtcars.mpg.sd).round 2
490
+
491
+ # create a new column 'mpg_type'. Function 'ifelse' is a vectorized function
492
+ # that looks at every element of the mpg_z vector and if the value is below
493
+ # 0, returns 'below', otherwise returns 'above'
494
+ @mtcars.mpg_type = (@mtcars.mpg_z < 0).ifelse("below", "above")
495
+
496
+ # order the mtcar data set by the mpg_z vector from smaler to larger values
497
+ @mtcars = @mtcars[@mtcars.mpg_z.order, :all]
498
+
499
+ # convert the car_name column to a factor to retain sorted order in plot
500
+ @mtcars.car_name = @mtcars.car_name.factor levels: @mtcars.car_name
406
501
 
407
- mtcars.car_name = mtcars.rownames # create new column for car names
408
- mtcars.mpg_z = ((mtcars.mpg - mtcars.mpg.mean) / mtcars.mpg.sd).round 2
409
- mtcars.mpg_type = (mtcars.mpg_z < 0).ifelse('below', 'above')
410
- mtcars = mtcars[mtcars.mpg_z.order, :all]
411
- mtcars.car_name = R.factor(mtcars.car_name, levels: mtcars.car_name)
502
+ # let's look at the first records of the final data frame
503
+ puts @mtcars.head
504
+ ```
505
+
506
+ ```
507
+ ## mpg cyl disp hp drat wt qsec vs am gear carb
508
+ ## Cadillac Fleetwood 10.4 8 472 205 2.93 5.250 17.98 0 0 3 4
509
+ ## Lincoln Continental 10.4 8 460 215 3.00 5.424 17.82 0 0 3 4
510
+ ## Camaro Z28 13.3 8 350 245 3.73 3.840 15.41 0 0 3 4
511
+ ## Duster 360 14.3 8 360 245 3.21 3.570 15.84 0 0 3 4
512
+ ## Chrysler Imperial 14.7 8 440 230 3.23 5.345 17.42 0 0 3 4
513
+ ## Maserati Bora 15.0 8 301 335 3.54 3.570 14.60 0 1 5 8
514
+ ## car_name mpg_z mpg_type
515
+ ## Cadillac Fleetwood Cadillac Fleetwood -1.61 below
516
+ ## Lincoln Continental Lincoln Continental -1.61 below
517
+ ## Camaro Z28 Camaro Z28 -1.13 below
518
+ ## Duster 360 Duster 360 -0.96 below
519
+ ## Chrysler Imperial Chrysler Imperial -0.89 below
520
+ ## Maserati Bora Maserati Bora -0.84 below
521
+ ```
522
+
523
+
524
+ ```ruby
525
+ require 'ggplot'
412
526
 
413
- puts mtcars.ggplot(E.aes(x: :car_name, y: :mpg_z, label: :mpg_z)) +
527
+ puts @mtcars.ggplot(E.aes(x: :car_name, y: :mpg_z, label: :mpg_z)) +
414
528
  R.geom_bar(E.aes(fill: :mpg_type), stat: 'identity', width: 0.5) +
415
529
  R.scale_fill_manual(name: 'Mileage',
416
530
  labels: R.c('Above Average', 'Below Average'),
@@ -438,10 +552,6 @@ This is some text with inline Ruby accessing variable \@b which has value:
438
552
  and is followed by some other text!
439
553
  ````
440
554
 
441
- Note that it is important not to add any new line before of after the code
442
- block if we want everything to be in only one line, resulting in the following sentence
443
- with inline Ruby code
444
-
445
555
  <div style="margin-bottom:30px;">
446
556
  </div>
447
557
 
@@ -452,21 +562,26 @@ and is followed by some other text!
452
562
  <div style="margin-bottom:30px;">
453
563
  </div>
454
564
 
565
+ Note that it is important not to add any new line before of after the code
566
+ block if we want everything to be in only one line, resulting in the following sentence
567
+ with inline Ruby code.
568
+
455
569
 
456
570
  ### The 'outputs' function
457
571
 
458
- He have previously used the standard 'puts' method in Ruby chunks in order to get some
459
- output. As can be seen, the result of a 'puts' is formatted inside a white box that
572
+ He have previously used the standard 'puts' method in Ruby chunks in order produce
573
+ output. The result of a 'puts', as seen in all previous chunks that use it, is formatted
574
+ inside a white box that
460
575
  follows the code block. Many times however, we would like to do some processing in the
461
576
  Ruby chunk and have the result of this processing generate and output that is
462
- 'included' in the document as if we had typed it in R markdown.
577
+ "included" in the document as if we had typed it in __R markdown__ document.
463
578
 
464
- For example, suppose we want to create a new 'heading' in our document, but the heading
579
+ For example, suppose we want to create a new heading in our document, but the heading
465
580
  phrase is the result of some code processing: maybe it's the first line of a file we are
466
- going to read. Method 'outputs' adds its output as if typed in the R markdown document.
581
+ going to read. Method 'outputs' adds its output as if typed in the __R markdown__ document.
467
582
 
468
- Take now a look at variable '@c' (it was defined in a previous block above) as
469
- '@c = "The 'outputs' function". "The 'outputs' function" is actually the name of this
583
+ Take now a look at variable '\@c' (it was defined in a previous block above) as
584
+ '\@c = "The 'outputs' function". "The 'outputs' function" is actually the name of this
470
585
  section and it was created using the 'outputs' function inside a Ruby chunk.
471
586
 
472
587
  The ruby chunk to generate this heading is:
@@ -477,14 +592,14 @@ outputs "### #{@c}"
477
592
  ```
478
593
  ````
479
594
 
480
- The three '###' are the way we add a Heading 3 in R markdown.
595
+ The three '###' is the way we add a Heading 3 in __R markdown__.
481
596
 
482
597
 
483
598
  ### HTML Output from Ruby Chunks
484
599
 
485
- We've just seen the use of method 'outputs' to add text to the the R markdown
486
- document. This technique can also be used to add HTML code to the document. In R
487
- markdown any html code typed directly in the document will be properly rendered.
600
+ We've just seen the use of method 'outputs' to add text to the the __R markdown__
601
+ document. This technique can also be used to add HTML code to the document. In
602
+ __R markdown__, any html code typed directly in the document will be properly rendered.
488
603
  Here, for instance, is a table definition in HTML and its output in the document:
489
604
 
490
605
  ```
@@ -530,8 +645,10 @@ Here, for instance, is a table definition in HTML and its output in the document
530
645
  <div style="margin-bottom:30px;">
531
646
  </div>
532
647
 
533
- But manually creating HTML output is not always easy or desirable. The above
534
- table certainly looks ugly. The 'kableExtra' library is a great library for
648
+ But manually creating HTML output is not always easy or desirable, specially
649
+ if we intend the document to be rendered in other formats, for example, as Latex.
650
+ Also, The above
651
+ table looks ugly. The 'kableExtra' library is a great library for
535
652
  creating beautiful tables. Take a look at https://cran.r-project.org/web/packages/kableExtra/vignettes/awesome_table_in_html.html
536
653
 
537
654
  In the next chunk, we output the 'mtcars' dataframe from R in a nicely formatted
@@ -543,11 +660,6 @@ R.install_and_loads('kableExtra')
543
660
  outputs (~:mtcars).kable.kable_styling
544
661
  ```
545
662
 
546
- ```
547
- ## The following packages are missing and will be installed:
548
- ## [1] "kableExtra"
549
- ```
550
-
551
663
  <table class="table" style="margin-left: auto; margin-right: auto;">
552
664
  <thead>
553
665
  <tr>
@@ -1017,39 +1129,38 @@ outputs (~:mtcars).kable.kable_styling
1017
1129
  </tbody>
1018
1130
  </table>
1019
1131
 
1020
- ### Including Ruby files
1132
+ ### Including Ruby files in a chunk
1021
1133
 
1022
1134
  R is a language that was created to be easy and fast for statisticians to use. As far
1023
- as I know (and please correct me if you think otherwise), tt was not a
1135
+ as I know, it was not a
1024
1136
  language to be used for developing large systems. Of course, there are large systems and
1025
1137
  libraries in R, but the focus of the language is for developing statistical models and
1026
1138
  distribute that to peers.
1027
1139
 
1028
1140
  Ruby on the other hand, is a language for large software development. Systems written in
1029
- Ruby will have dozens, hundreds or even thousands of files. In order to document a
1030
- large system with
1031
- literate programming we cannot expect the developer to add all the files in a single '.Rmd'
1032
- file. gKnit provides the 'include' chunk engine to include a Ruby file as if it had being
1033
- typed in the '.Rmd' file.
1141
+ Ruby will have dozens, hundreds or even thousands of files. To document a
1142
+ large system with literate programming, we cannot expect the developer to add all the
1143
+ files in a single '.Rmd' file. gKnit provides the 'include' chunk engine to include
1144
+ a Ruby file as if it had being typed in the '.Rmd' file.
1034
1145
 
1035
1146
  To include a file, the following chunk should be created, where <filename> is the name of
1036
- the file to be include and where the extension, if it is '.rb', does not need to be added.
1147
+ the file to be included and where the extension, if it is '.rb', does not need to be added.
1037
1148
  If the 'relative' option is not included, then it is treated as TRUE. When 'relative' is
1038
- true, 'require_relative' semantics is used to load the file, when false, Ruby's \$LOAD_PATH
1039
- is searched to find the file and it is 'require'd.
1149
+ true, ruby's 'require\_relative' semantics is used to load the file, when false, Ruby's
1150
+ \$LOAD_PATH is searched to find the file and it is 'require'd.
1040
1151
 
1041
1152
  ````
1042
1153
  ```{include <filename>, relative = <TRUE/FALSE>}
1043
1154
  ```
1044
1155
  ````
1045
1156
 
1046
- Here we include file 'model.rb' which is in the same directory of this blog.
1157
+ Bellow we include file 'model.rb', which is in the same directory of this blog.
1047
1158
  This code uses R 'caret' package to split a dataset in a train and test sets.
1048
1159
  The 'caret' package is a very important a useful package for doing Data Analysis,
1049
1160
  it has hundreds of functions for all steps of the Data Analysis workflow. To
1050
- just split a dataset it is using the proverbial cannon to kill the fly. We use
1051
- it here only to show that integrating Ruby and R and using even a very comples
1052
- package as 'caret' is trivial with Galaaz.
1161
+ use 'caret' just to split a dataset is like using the proverbial cannon to
1162
+ kill the fly. We use it here only to show that integrating Ruby and R and
1163
+ using even a very complex package as 'caret' is trivial with Galaaz.
1053
1164
 
1054
1165
  A word of advice: the 'caret' package has lots of dependencies and installing
1055
1166
  it in a Linux system is a time consuming operation. Method 'R.install_and_loads'
@@ -1133,10 +1244,11 @@ puts model.test.head
1133
1244
  ### Documenting Gems
1134
1245
 
1135
1246
  gKnit also allows developers to document and load files that are not in the same directory
1136
- of the '.Rmd' file. When using 'relative = FALSE' in a chunk header, gKnit will look for the
1137
- file in Ruby's \$LOAD_PATH and load it if found.
1247
+ of the '.Rmd' file.
1138
1248
 
1139
- Here is an example of loading the 'find.rb' file from TruffleRuby.
1249
+ Here is an example of loading the 'find.rb' file from TruffleRuby. In this example, relative
1250
+ is set to FALSE, so Ruby will look for the file in its $LOAD\_PATH, and the user does not
1251
+ need to no it's directory.
1140
1252
 
1141
1253
  ````
1142
1254
  ```{include find, relative = FALSE}
@@ -1238,7 +1350,7 @@ end
1238
1350
  ## Converting to PDF
1239
1351
 
1240
1352
  One of the beauties of knitr is that the same input can be converted to many different outputs.
1241
- One very useful format, is, of course, PDF. In order to converted an R markdown file to PDF
1353
+ One very useful format, is, of course, PDF. In order to converted an __R markdown__ file to PDF
1242
1354
  it is necessary to have LaTeX installed on the system. We will not explain here how to
1243
1355
  install LaTeX as there are plenty of documents on the web showing how to proceed.
1244
1356
 
@@ -1254,25 +1366,36 @@ date: "29 October 2018"
1254
1366
  output:
1255
1367
  pdf_document:
1256
1368
  includes:
1257
- in_header: ["../../sty/galaaz.sty"]
1258
- number_sections: yes
1369
+ in\_header: ["../../sty/galaaz.sty"]
1370
+ number\_sections: yes
1259
1371
  ---
1260
1372
  ```
1261
1373
 
1262
1374
  # Conclusion
1263
1375
 
1264
- One of the promises of GraalVM is that users/developers will be able to use the best tool
1265
- for their task at hand, independently of the programming language the tool was written. Galaaz
1266
- and gKnit are not trivial implementations atop the GraalVM and Truffle interop messages;
1267
- however, the time and effort it took to wrap Ruby over R - Galaaz - (not finished yet) or to
1268
- wrap Knitr with gKnit is a fraction of a fraction of a fraction of the time require to
1376
+ In order to do reproducible research, one of the main basic tools needed is a systhem that
1377
+ allows "literate programming" where text, code and possibly a set of files can be compiled
1378
+ onto a report that can be easily distributed to peers. Peers should be able to use this
1379
+ same set of files to rerun the compilation by their own obtaining the exact same original
1380
+ report. gKnit is such a system for Ruby and R. It uses __R Markdown__ to integrate
1381
+ text and code chunks, where code chunks can either be part of the __R Markdwon__ file or
1382
+ be imported from files in the system. Ideally, in reproducible research, all the files
1383
+ needed to rebuild a report should be easilly packed together (in the same zipped directory)
1384
+ and distributed to peers for reexecution.
1385
+
1386
+ One of the promises of Oracle's GraalVM is that users/developers will be able to use the best tool
1387
+ for their task at hand, independently of the programming language the tool was written on.
1388
+ We developed and implemented Galaaz atop the GraalVM and Truffle interop messages and
1389
+ the time and effort to wrap Ruby over R - Galaaz - or to
1390
+ wrap Knitr with gKnit was a fraction of a fraction of a fraction (one man effort for a couple
1391
+ of hours a day, for approximately six months) of the time require to
1269
1392
  implement the original tools. Trying to reimplement all R packages in Ruby would require the
1270
- same effort it is taking Python to implement NumPy, Panda and all supporting libraries and it
1393
+ same effort it is taking Python to implement NumPy, Pandas and all supporting libraries and it
1271
1394
  is unlikely that this effort would ever be done. GraalVM has allowed Ruby to profit "almost
1272
1395
  for free" from this huge set of libraries and tools that make R one of the most used
1273
1396
  languages for data analysis and machine learning.
1274
1397
 
1275
- More interesting though than being able to wrap the R libraries with Ruby, is that Ruby adds
1398
+ More interesting than wrapping the R libraries with Ruby, is that Ruby adds
1276
1399
  value to R, by allowing developers to use powerful and modern constructs for code reuse that
1277
1400
  are not the strong points of R. As shown in this blog, R and Ruby can easily communicate
1278
1401
  and R can be structured in classes and modules in a way that greatly expands its power and
@@ -1303,3 +1426,6 @@ the gnu compiler and tools should be enough. I am not sure what is needed on th
1303
1426
  ## Usage
1304
1427
 
1305
1428
  * gknit \<filename\>
1429
+
1430
+ # References
1431
+