<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Data Wrangling on Posit Open Source</title>
    <link>https://posit-open-source.netlify.app/categories/data-wrangling/</link>
    <description>Recent content in Data Wrangling on Posit Open Source</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <lastBuildDate>Tue, 10 Feb 2026 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://posit-open-source.netlify.app/categories/data-wrangling/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>`dplyr::if_else()` and `dplyr::case_when()` are up to 30x faster</title>
      <link>https://posit-open-source.netlify.app/blog/tidyverse/dplyr-performance/</link>
      <pubDate>Tue, 10 Feb 2026 00:00:00 +0000</pubDate>
      <guid>https://posit-open-source.netlify.app/blog/tidyverse/dplyr-performance/</guid>
      <dc:creator>Davis Vaughan</dc:creator><description><![CDATA[<p>In this technical post, we&rsquo;ll dive into some performance improvements we&rsquo;ve made to dplyr 1.2.0 to make <a href="https://dplyr.tidyverse.org/reference/if_else.html" target="_blank" rel="noopener"><code>if_else()</code></a>
 and <a href="https://dplyr.tidyverse.org/reference/case-and-replace-when.html" target="_blank" rel="noopener"><code>case_when()</code></a>
 up to 30x faster and use up to 10x less memory.</p>
<p>If you haven&rsquo;t seen our <a href="https://tidyverse.org/blog/2026/02/dplyr-1-2-0/" target="_blank" rel="noopener">previous post</a>
 about the exciting new features in dplyr 1.2.0, you&rsquo;ll want to go check that out first!</p>
<p>Here&rsquo;s a before-and-after benchmark with <a href="https://dplyr.tidyverse.org/reference/if_else.html" target="_blank" rel="noopener"><code>if_else()</code></a>
:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='c'># Using https://github.com/DavisVaughan/cross</span></span>
<span><span class='nf'>cross</span><span class='nf'>::</span><span class='nf'><a href='https://rdrr.io/pkg/cross/man/bench_versions.html'>bench_versions</a></span><span class='o'>(</span>pkgs <span class='o'>=</span> <span class='nf'><a href='https://rdrr.io/r/base/c.html'>c</a></span><span class='o'>(</span><span class='s'>"tidyverse/dplyr@v1.1.4"</span>, <span class='s'>"tidyverse/dplyr"</span><span class='o'>)</span>, <span class='o'>&#123;</span></span>
<span>  <span class='kr'><a href='https://rdrr.io/r/base/library.html'>library</a></span><span class='o'>(</span><span class='nv'><a href='https://dplyr.tidyverse.org'>dplyr</a></span><span class='o'>)</span></span>
<span>  <span class='nf'><a href='https://rdrr.io/r/base/Random.html'>set.seed</a></span><span class='o'>(</span><span class='m'>123</span><span class='o'>)</span></span>
<span></span>
<span>  <span class='nv'>condition</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://rdrr.io/r/base/sample.html'>sample</a></span><span class='o'>(</span><span class='nf'><a href='https://rdrr.io/r/base/c.html'>c</a></span><span class='o'>(</span><span class='kc'>TRUE</span>, <span class='kc'>FALSE</span>, <span class='kc'>NA</span><span class='o'>)</span>, size <span class='o'>=</span> <span class='m'>1e7</span>, replace <span class='o'>=</span> <span class='kc'>TRUE</span><span class='o'>)</span></span>
<span>  <span class='nv'>x</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://rdrr.io/r/base/sample.html'>sample</a></span><span class='o'>(</span><span class='m'>10</span>, size <span class='o'>=</span> <span class='m'>1e7</span>, replace <span class='o'>=</span> <span class='kc'>TRUE</span><span class='o'>)</span></span>
<span>  <span class='nv'>y</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://rdrr.io/r/base/sample.html'>sample</a></span><span class='o'>(</span><span class='m'>10</span>, size <span class='o'>=</span> <span class='m'>1e7</span>, replace <span class='o'>=</span> <span class='kc'>TRUE</span><span class='o'>)</span></span>
<span>  <span class='nv'>z</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://rdrr.io/r/base/sample.html'>sample</a></span><span class='o'>(</span><span class='m'>10</span>, size <span class='o'>=</span> <span class='m'>1e7</span>, replace <span class='o'>=</span> <span class='kc'>TRUE</span><span class='o'>)</span></span>
<span></span>
<span>  <span class='nf'>bench</span><span class='nf'>::</span><span class='nf'><a href='https://bench.r-lib.org/reference/mark.html'>mark</a></span><span class='o'>(</span>if_else <span class='o'>=</span> <span class='nf'><a href='https://dplyr.tidyverse.org/reference/if_else.html'>if_else</a></span><span class='o'>(</span><span class='nv'>condition</span>, <span class='nv'>x</span>, <span class='nv'>y</span>, missing <span class='o'>=</span> <span class='nv'>z</span><span class='o'>)</span><span class='o'>)</span></span>
<span><span class='o'>&#125;</span><span class='o'>)</span></span></code></pre>
</div>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="c1">#&gt; # A tibble: 2 × 6</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt;   pkg                    expression      min   median `itr/sec` mem_alloc</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt;   &lt;chr&gt;                  &lt;bch:expr&gt; &lt;bch:tm&gt; &lt;bch:tm&gt;     &lt;dbl&gt; &lt;bch:byt&gt;</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; 1 tidyverse/dplyr@v1.1.4 if_else    248.25ms 249.25ms      4.02   381.6MB</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; 2 tidyverse/dplyr        if_else      7.27ms   7.51ms    132.      38.2MB</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>And with <a href="https://dplyr.tidyverse.org/reference/case-and-replace-when.html" target="_blank" rel="noopener"><code>case_when()</code></a>
:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nf'>cross</span><span class='nf'>::</span><span class='nf'><a href='https://rdrr.io/pkg/cross/man/bench_versions.html'>bench_versions</a></span><span class='o'>(</span>pkgs <span class='o'>=</span> <span class='nf'><a href='https://rdrr.io/r/base/c.html'>c</a></span><span class='o'>(</span><span class='s'>"tidyverse/dplyr@v1.1.4"</span>, <span class='s'>"tidyverse/dplyr"</span><span class='o'>)</span>, <span class='o'>&#123;</span></span>
<span>  <span class='kr'><a href='https://rdrr.io/r/base/library.html'>library</a></span><span class='o'>(</span><span class='nv'><a href='https://dplyr.tidyverse.org'>dplyr</a></span><span class='o'>)</span></span>
<span>  <span class='nf'><a href='https://rdrr.io/r/base/Random.html'>set.seed</a></span><span class='o'>(</span><span class='m'>123</span><span class='o'>)</span></span>
<span></span>
<span>  <span class='nv'>column</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://rdrr.io/r/base/sample.html'>sample</a></span><span class='o'>(</span><span class='m'>100</span>, size <span class='o'>=</span> <span class='m'>1e7</span>, replace <span class='o'>=</span> <span class='kc'>TRUE</span><span class='o'>)</span></span>
<span></span>
<span>  <span class='nv'>x_condition</span> <span class='o'>&lt;-</span> <span class='nv'>column</span> <span class='o'>&lt;</span> <span class='m'>20</span></span>
<span>  <span class='nv'>y_condition</span> <span class='o'>&lt;-</span> <span class='nv'>column</span> <span class='o'>&lt;</span> <span class='m'>50</span></span>
<span>  <span class='nv'>z_condition</span> <span class='o'>&lt;-</span> <span class='nv'>column</span> <span class='o'>&lt;</span> <span class='m'>80</span></span>
<span></span>
<span>  <span class='nv'>x</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://rdrr.io/r/base/sample.html'>sample</a></span><span class='o'>(</span><span class='m'>10</span>, size <span class='o'>=</span> <span class='m'>1e7</span>, replace <span class='o'>=</span> <span class='kc'>TRUE</span><span class='o'>)</span></span>
<span>  <span class='nv'>y</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://rdrr.io/r/base/sample.html'>sample</a></span><span class='o'>(</span><span class='m'>10</span>, size <span class='o'>=</span> <span class='m'>1e7</span>, replace <span class='o'>=</span> <span class='kc'>TRUE</span><span class='o'>)</span></span>
<span>  <span class='nv'>z</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://rdrr.io/r/base/sample.html'>sample</a></span><span class='o'>(</span><span class='m'>10</span>, size <span class='o'>=</span> <span class='m'>1e7</span>, replace <span class='o'>=</span> <span class='kc'>TRUE</span><span class='o'>)</span></span>
<span></span>
<span>  <span class='nf'>bench</span><span class='nf'>::</span><span class='nf'><a href='https://bench.r-lib.org/reference/mark.html'>mark</a></span><span class='o'>(</span></span>
<span>    case_when <span class='o'>=</span> <span class='nf'><a href='https://dplyr.tidyverse.org/reference/case-and-replace-when.html'>case_when</a></span><span class='o'>(</span></span>
<span>      <span class='nv'>x_condition</span> <span class='o'>~</span> <span class='nv'>x</span>,</span>
<span>      <span class='nv'>y_condition</span> <span class='o'>~</span> <span class='nv'>y</span>,</span>
<span>      <span class='nv'>z_condition</span> <span class='o'>~</span> <span class='nv'>z</span></span>
<span>    <span class='o'>)</span></span>
<span>  <span class='o'>)</span></span>
<span><span class='o'>&#125;</span><span class='o'>)</span></span></code></pre>
</div>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="c1">#&gt; # A tibble: 2 × 6</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt;   pkg                    expression      min   median `itr/sec` mem_alloc</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt;   &lt;chr&gt;                  &lt;bch:expr&gt; &lt;bch:tm&gt; &lt;bch:tm&gt;     &lt;dbl&gt; &lt;bch:byt&gt;</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; 1 tidyverse/dplyr@v1.1.4 case_when   228.3ms  231.2ms      4.33   419.9MB</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; 2 tidyverse/dplyr        case_when    15.5ms   15.8ms     62.8     38.3MB</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>So a 33x speed improvement for <a href="https://dplyr.tidyverse.org/reference/if_else.html" target="_blank" rel="noopener"><code>if_else()</code></a>
, a 15x speed improvement for <a href="https://dplyr.tidyverse.org/reference/case-and-replace-when.html" target="_blank" rel="noopener"><code>case_when()</code></a>
, and a 10x improvement in memory usage for both! In the rest of this post, we&rsquo;ll explain how we&rsquo;ve achieved these numbers.</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='kr'><a href='https://rdrr.io/r/base/library.html'>library</a></span><span class='o'>(</span><span class='nv'><a href='https://dplyr.tidyverse.org'>dplyr</a></span><span class='o'>)</span></span></code></pre>
</div>
<h2 id="lets-talk-memory">Let&rsquo;s talk memory
</h2>
<p>We&rsquo;ll start with <a href="https://dplyr.tidyverse.org/reference/case-and-replace-when.html" target="_blank" rel="noopener"><code>case_when()</code></a>
, because <a href="https://dplyr.tidyverse.org/reference/if_else.html" target="_blank" rel="noopener"><code>if_else()</code></a>
 is actually just a small variant of that.</p>
<p>The most important place to start is with the memory usage. Memory usage and raw speed are often related, as allocating memory takes time. Let&rsquo;s look at the memory usage of <a href="https://dplyr.tidyverse.org/reference/case-and-replace-when.html" target="_blank" rel="noopener"><code>case_when()</code></a>
 in dplyr 1.1.4:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nf'><a href='https://rdrr.io/r/base/Random.html'>set.seed</a></span><span class='o'>(</span><span class='m'>123</span><span class='o'>)</span></span>
<span></span>
<span><span class='nv'>column</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://rdrr.io/r/base/sample.html'>sample</a></span><span class='o'>(</span><span class='m'>100</span>, size <span class='o'>=</span> <span class='m'>1e7</span>, replace <span class='o'>=</span> <span class='kc'>TRUE</span><span class='o'>)</span></span>
<span></span>
<span><span class='nv'>x_condition</span> <span class='o'>&lt;-</span> <span class='nv'>column</span> <span class='o'>&lt;</span> <span class='m'>20</span></span>
<span><span class='nv'>y_condition</span> <span class='o'>&lt;-</span> <span class='nv'>column</span> <span class='o'>&lt;</span> <span class='m'>50</span></span>
<span><span class='nv'>z_condition</span> <span class='o'>&lt;-</span> <span class='nv'>column</span> <span class='o'>&lt;</span> <span class='m'>80</span></span>
<span></span>
<span><span class='nv'>x</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://rdrr.io/r/base/sample.html'>sample</a></span><span class='o'>(</span><span class='m'>10</span>, size <span class='o'>=</span> <span class='m'>1e7</span>, replace <span class='o'>=</span> <span class='kc'>TRUE</span><span class='o'>)</span></span>
<span><span class='nv'>y</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://rdrr.io/r/base/sample.html'>sample</a></span><span class='o'>(</span><span class='m'>10</span>, size <span class='o'>=</span> <span class='m'>1e7</span>, replace <span class='o'>=</span> <span class='kc'>TRUE</span><span class='o'>)</span></span>
<span><span class='nv'>z</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://rdrr.io/r/base/sample.html'>sample</a></span><span class='o'>(</span><span class='m'>10</span>, size <span class='o'>=</span> <span class='m'>1e7</span>, replace <span class='o'>=</span> <span class='kc'>TRUE</span><span class='o'>)</span></span></code></pre>
</div>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="n">profmem</span><span class="o">::</span><span class="nf">profmem</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">  <span class="n">threshold</span> <span class="o">=</span> <span class="m">1000</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nf">case_when</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">x_condition</span> <span class="o">~</span> <span class="n">x</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">y_condition</span> <span class="o">~</span> <span class="n">y</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">z_condition</span> <span class="o">~</span> <span class="n">z</span>
</span></span><span class="line"><span class="cl">  <span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; Rprofmem memory profiling of:</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; case_when(x_condition ~ x, y_condition ~ y, z_condition ~ z)</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt;</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; Memory allocations (&gt;= 1000 bytes):</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt;        what     bytes                                           calls</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; 1     alloc  40000048     case_when() -&gt; vec_case_when() -&gt; vec_rep()</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; 2     alloc  40000048                  case_when() -&gt; vec_case_when()</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; 3     alloc  40000056       case_when() -&gt; vec_case_when() -&gt; which()</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; 4     alloc   7600664       case_when() -&gt; vec_case_when() -&gt; which()</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; 5     alloc  40000048                  case_when() -&gt; vec_case_when()</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; 6     alloc  40000056       case_when() -&gt; vec_case_when() -&gt; which()</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; 7     alloc  12003312       case_when() -&gt; vec_case_when() -&gt; which()</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; 8     alloc  40000048                  case_when() -&gt; vec_case_when()</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; 9     alloc  40000056       case_when() -&gt; vec_case_when() -&gt; which()</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; 10    alloc  11996112       case_when() -&gt; vec_case_when() -&gt; which()</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; 11    alloc  40000056       case_when() -&gt; vec_case_when() -&gt; which()</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; 12    alloc   8400112       case_when() -&gt; vec_case_when() -&gt; which()</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; 13    alloc   7600664   case_when() -&gt; vec_case_when() -&gt; vec_slice()</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; 14    alloc  12003312   case_when() -&gt; vec_case_when() -&gt; vec_slice()</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; 15    alloc  11996112   case_when() -&gt; vec_case_when() -&gt; vec_slice()</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; 16    alloc   8400112 case_when() -&gt; vec_case_when() -&gt; vec_recycle()</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; 17    alloc  40000048 case_when() -&gt; vec_case_when() -&gt; list_unchop()</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; total       440000864</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>That&rsquo;s a lot of allocations! And it&rsquo;s pretty hard to understand where they are coming from without a bit more explanation. For that, we&rsquo;re actually going to &ldquo;manually&rdquo; implement an underpowered version of <a href="https://dplyr.tidyverse.org/reference/case-and-replace-when.html" target="_blank" rel="noopener"><code>case_when()</code></a>
 for this example.</p>
<p>Here&rsquo;s a diagram of what we need to accomplish:</p>
<p><div class="not-prose"><figure>
    <img class="h-auto max-w-full rounded-lg"
      src="https://posit-open-source.netlify.app/blog/tidyverse/dplyr-performance/images/x-y-z-default.png"
      alt="" 
      loading="lazy"
    >
  </figure></div>
</p>
<p>In bullets:</p>
<ul>
<li><code>x_condition</code> selects the blue elements of <code>x</code></li>
<li><code>y_condition</code> selects the red elements of <code>y</code></li>
<li><code>z_condition</code> selects the green elements of <code>z</code></li>
<li>A <code>default</code> is built around the unused locations</li>
<li>We combine all of the pieces into <code>out</code></li>
</ul>
<p>The trickiest part about <a href="https://dplyr.tidyverse.org/reference/case-and-replace-when.html" target="_blank" rel="noopener"><code>case_when()</code></a>
 is handling places where <code>x_condition</code> and <code>y_condition</code> overlap. In the image, even though both <code>x</code> and <code>y</code> are selected at location 5, only the value of <code>x</code> is retained since it is hit &ldquo;first&rdquo;. This forces us to have to modify <code>y_condition</code> to avoid already &ldquo;used&rdquo; locations.</p>
<p>An R implementation that computes these modified locations might look like:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>n</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://rdrr.io/r/base/length.html'>length</a></span><span class='o'>(</span><span class='nv'>x_condition</span><span class='o'>)</span></span>
<span></span>
<span><span class='nv'>unused</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://rdrr.io/r/base/rep.html'>rep</a></span><span class='o'>(</span><span class='kc'>TRUE</span>, times <span class='o'>=</span> <span class='nv'>n</span><span class='o'>)</span> <span class='c'># 1</span></span>
<span></span>
<span><span class='nv'>x_loc</span> <span class='o'>&lt;-</span> <span class='nv'>unused</span> <span class='o'>&amp;</span> <span class='nv'>x_condition</span> <span class='c'># 2</span></span>
<span><span class='nv'>x_loc</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://rdrr.io/r/base/which.html'>which</a></span><span class='o'>(</span><span class='nv'>x_loc</span><span class='o'>)</span> <span class='c'># 3,4</span></span>
<span><span class='nv'>unused</span><span class='o'>[</span><span class='nv'>x_loc</span><span class='o'>]</span> <span class='o'>&lt;-</span> <span class='kc'>FALSE</span></span>
<span></span>
<span><span class='nv'>y_loc</span> <span class='o'>&lt;-</span> <span class='nv'>unused</span> <span class='o'>&amp;</span> <span class='nv'>y_condition</span> <span class='c'># 5</span></span>
<span><span class='nv'>y_loc</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://rdrr.io/r/base/which.html'>which</a></span><span class='o'>(</span><span class='nv'>y_loc</span><span class='o'>)</span> <span class='c'># 6,7</span></span>
<span><span class='nv'>unused</span><span class='o'>[</span><span class='nv'>y_loc</span><span class='o'>]</span> <span class='o'>&lt;-</span> <span class='kc'>FALSE</span></span>
<span></span>
<span><span class='nv'>z_loc</span> <span class='o'>&lt;-</span> <span class='nv'>unused</span> <span class='o'>&amp;</span> <span class='nv'>z_condition</span> <span class='c'># 8</span></span>
<span><span class='nv'>z_loc</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://rdrr.io/r/base/which.html'>which</a></span><span class='o'>(</span><span class='nv'>z_loc</span><span class='o'>)</span> <span class='c'># 9,10</span></span>
<span><span class='nv'>unused</span><span class='o'>[</span><span class='nv'>z_loc</span><span class='o'>]</span> <span class='o'>&lt;-</span> <span class='kc'>FALSE</span></span></code></pre>
</div>
<p>Anything that is still <code>unused</code> falls through to the <code>default</code>:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>default</span> <span class='o'>&lt;-</span> <span class='kc'>NA_integer_</span></span>
<span><span class='nv'>default_loc</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://rdrr.io/r/base/which.html'>which</a></span><span class='o'>(</span><span class='nv'>unused</span><span class='o'>)</span> <span class='c'># 11,12</span></span></code></pre>
</div>
<p>With <code>x_loc</code>, <code>y_loc</code>, <code>z_loc</code>, and <code>default_loc</code> in hand, we can build the output from the pieces:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>out</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://rdrr.io/r/base/vector.html'>vector</a></span><span class='o'>(</span><span class='s'>"integer"</span>, length <span class='o'>=</span> <span class='nv'>n</span><span class='o'>)</span> <span class='c'># 17</span></span>
<span></span>
<span><span class='nv'>out</span><span class='o'>[</span><span class='nv'>x_loc</span><span class='o'>]</span> <span class='o'>&lt;-</span> <span class='nv'>x</span><span class='o'>[</span><span class='nv'>x_loc</span><span class='o'>]</span> <span class='c'># 13</span></span>
<span><span class='nv'>out</span><span class='o'>[</span><span class='nv'>y_loc</span><span class='o'>]</span> <span class='o'>&lt;-</span> <span class='nv'>y</span><span class='o'>[</span><span class='nv'>y_loc</span><span class='o'>]</span> <span class='c'># 14</span></span>
<span><span class='nv'>out</span><span class='o'>[</span><span class='nv'>z_loc</span><span class='o'>]</span> <span class='o'>&lt;-</span> <span class='nv'>z</span><span class='o'>[</span><span class='nv'>z_loc</span><span class='o'>]</span> <span class='c'># 15</span></span>
<span></span>
<span><span class='nv'>out</span><span class='o'>[</span><span class='nv'>default_loc</span><span class='o'>]</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://rdrr.io/r/base/rep.html'>rep</a></span><span class='o'>(</span><span class='nv'>default</span>, times <span class='o'>=</span> <span class='nf'><a href='https://rdrr.io/r/base/length.html'>length</a></span><span class='o'>(</span><span class='nv'>default_loc</span><span class='o'>)</span><span class='o'>)</span> <span class='c'># 16</span></span></code></pre>
</div>
<p>And sure enough, this is identical to <a href="https://dplyr.tidyverse.org/reference/case-and-replace-when.html" target="_blank" rel="noopener"><code>case_when()</code></a>
:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nf'><a href='https://rdrr.io/r/base/identical.html'>identical</a></span><span class='o'>(</span></span>
<span>  <span class='nv'>out</span>,</span>
<span>  <span class='nf'><a href='https://dplyr.tidyverse.org/reference/case-and-replace-when.html'>case_when</a></span><span class='o'>(</span></span>
<span>    <span class='nv'>x_condition</span> <span class='o'>~</span> <span class='nv'>x</span>,</span>
<span>    <span class='nv'>y_condition</span> <span class='o'>~</span> <span class='nv'>y</span>,</span>
<span>    <span class='nv'>z_condition</span> <span class='o'>~</span> <span class='nv'>z</span></span>
<span>  <span class='o'>)</span></span>
<span><span class='o'>)</span></span>
<span><span class='c'>#&gt; [1] TRUE</span></span>
<span></span></code></pre>
</div>
<p>You might be wondering what all of the comments with numbers beside them mean. Those actually map 1:1 with the allocations that <a href="https://dplyr.tidyverse.org/reference/case-and-replace-when.html" target="_blank" rel="noopener"><code>case_when()</code></a>
 was emitting. In fact, we can now split up those allocations into their respective role:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="c1">#&gt; # Tracking `unused` locations</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; 1     alloc  40000048     case_when() -&gt; vec_case_when() -&gt; vec_rep()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; # Computing `x_loc`, `y_loc`, and `z_loc`</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; 2     alloc  40000048                  case_when() -&gt; vec_case_when()</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; 3     alloc  40000056       case_when() -&gt; vec_case_when() -&gt; which()</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; 4     alloc   7600664       case_when() -&gt; vec_case_when() -&gt; which()</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; 5     alloc  40000048                  case_when() -&gt; vec_case_when()</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; 6     alloc  40000056       case_when() -&gt; vec_case_when() -&gt; which()</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; 7     alloc  12003312       case_when() -&gt; vec_case_when() -&gt; which()</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; 8     alloc  40000048                  case_when() -&gt; vec_case_when()</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; 9     alloc  40000056       case_when() -&gt; vec_case_when() -&gt; which()</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; 10    alloc  11996112       case_when() -&gt; vec_case_when() -&gt; which()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; # Computing `default_loc`</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; 11    alloc  40000056       case_when() -&gt; vec_case_when() -&gt; which()</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; 12    alloc   8400112       case_when() -&gt; vec_case_when() -&gt; which()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; # Slicing `x`, `y`, and `z` to align with `x_loc`, `y_loc`, and `z_loc`</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; 13    alloc   7600664   case_when() -&gt; vec_case_when() -&gt; vec_slice()</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; 14    alloc  12003312   case_when() -&gt; vec_case_when() -&gt; vec_slice()</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; 15    alloc  11996112   case_when() -&gt; vec_case_when() -&gt; vec_slice()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; # Recycling `default` of `NA` to align with `default_loc`</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; 16    alloc   8400112 case_when() -&gt; vec_case_when() -&gt; vec_recycle()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; # Final output container, which we assign `x`, `y`, `z`, and `default` into</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; # at locations `x_loc`, `y_loc`, and `z_loc`</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; 17    alloc  40000048 case_when() -&gt; vec_case_when() -&gt; list_unchop()</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>We sought to remove every one of these allocations except for the last one, which is the final output container that is returned to the user. In other words, we were after this, which is the actual profmem result of this <a href="https://dplyr.tidyverse.org/reference/case-and-replace-when.html" target="_blank" rel="noopener"><code>case_when()</code></a>
 call in dplyr 1.2.0:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="c1">#&gt; Rprofmem memory profiling of:</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; case_when(x_condition ~ x, y_condition ~ y, z_condition ~ z)</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt;</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; Memory allocations (&gt;= 1000 bytes):</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt;        what    bytes                          calls</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; 1     alloc 40000048 case_when() -&gt; vec_case_when()</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; total       40000048</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="sliced-assignment">Sliced assignment
</h2>
<p>To work towards this, let&rsquo;s focus on what happens to <code>x</code> throughout this process:</p>
<p><div class="not-prose"><figure>
    <img class="h-auto max-w-full rounded-lg"
      src="https://posit-open-source.netlify.app/blog/tidyverse/dplyr-performance/images/just-x.png"
      alt="" 
      loading="lazy"
    >
  </figure></div>
</p>
<p>We had a hypothesis that we could cut out the intermediate work here. Ideally, we&rsquo;d take the logical LHS <code>x_condition</code> and the RHS <code>x</code> and map that straight into the output, with no extra allocations:</p>
<p><div class="not-prose"><figure>
    <img class="h-auto max-w-full rounded-lg"
      src="https://posit-open-source.netlify.app/blog/tidyverse/dplyr-performance/images/just-x-ideal.png"
      alt="" 
      loading="lazy"
    >
  </figure></div>
</p>
<p>But this just wasn&rsquo;t possible with the way that assignment typically works in R!</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>x</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://rdrr.io/r/base/c.html'>c</a></span><span class='o'>(</span><span class='s'>"a"</span>, <span class='s'>"b"</span>, <span class='s'>"c"</span>, <span class='s'>"d"</span>, <span class='s'>"e"</span>, <span class='s'>"f"</span>, <span class='s'>"g"</span><span class='o'>)</span></span>
<span><span class='nv'>x_condition</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://rdrr.io/r/base/c.html'>c</a></span><span class='o'>(</span><span class='kc'>FALSE</span>, <span class='kc'>TRUE</span>, <span class='kc'>FALSE</span>, <span class='kc'>FALSE</span>, <span class='kc'>TRUE</span>, <span class='kc'>FALSE</span>, <span class='kc'>FALSE</span><span class='o'>)</span></span>
<span><span class='nv'>out</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://rdrr.io/r/base/vector.html'>vector</a></span><span class='o'>(</span><span class='s'>"character"</span>, length <span class='o'>=</span> <span class='nf'><a href='https://rdrr.io/r/base/length.html'>length</a></span><span class='o'>(</span><span class='nv'>x_condition</span><span class='o'>)</span><span class='o'>)</span></span>
<span></span>
<span><span class='nv'>out</span><span class='o'>[</span><span class='nv'>x_condition</span><span class='o'>]</span> <span class='o'>&lt;-</span> <span class='nv'>x</span></span>
<span><span class='c'>#&gt; Warning in out[x_condition] &lt;- x: number of items to replace is not a multiple of replacement length</span></span>
<span></span></code></pre>
</div>
<p>Instead, you must pre-slice <code>x</code> to a length that matches the locations that <code>x_condition</code> points to in <code>out</code>, i.e.:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>out</span><span class='o'>[</span><span class='nv'>x_condition</span><span class='o'>]</span> <span class='o'>&lt;-</span> <span class='nv'>x</span><span class='o'>[</span><span class='nv'>x_condition</span><span class='o'>]</span></span></code></pre>
</div>
<p>Now, in <a href="https://dplyr.tidyverse.org/reference/case-and-replace-when.html" target="_blank" rel="noopener"><code>case_when()</code></a>
 we don&rsquo;t actually use <code>[&lt;-</code> for assignment or <code>[</code> for slicing. Instead, we use tools from <a href="https://vctrs.r-lib.org/" target="_blank" rel="noopener">vctrs</a>
, a low level package for building consistent tidyverse functions. In this case, we&rsquo;d use <code>vctrs::vec_assign()</code> and <code>vctrs::vec_slice()</code>:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>out</span> <span class='o'>&lt;-</span> <span class='nf'>vctrs</span><span class='nf'>::</span><span class='nf'><a href='https://vctrs.r-lib.org/reference/vec_slice.html'>vec_assign</a></span><span class='o'>(</span><span class='nv'>out</span>, <span class='nv'>x_condition</span>, <span class='nf'>vctrs</span><span class='nf'>::</span><span class='nf'><a href='https://vctrs.r-lib.org/reference/vec_slice.html'>vec_slice</a></span><span class='o'>(</span><span class='nv'>x</span>, <span class='nv'>x_condition</span><span class='o'>)</span><span class='o'>)</span></span></code></pre>
</div>
<p>But <code>vec_assign()</code> had the same problem!</p>
<p>To solve this, we&rsquo;ve added a new boolean argument to <code>vec_assign()</code> called <code>slice_value</code>. You use it like this:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>out</span> <span class='o'>&lt;-</span> <span class='nf'>vctrs</span><span class='nf'>::</span><span class='nf'><a href='https://vctrs.r-lib.org/reference/vec_slice.html'>vec_assign</a></span><span class='o'>(</span><span class='nv'>out</span>, <span class='nv'>x_condition</span>, <span class='nv'>x</span>, slice_value <span class='o'>=</span> <span class='kc'>TRUE</span><span class='o'>)</span></span></code></pre>
</div>
<p>With <code>slice_value = TRUE</code>, <code>vec_assign()</code> assumes that both <code>out</code> and <code>x</code> are the same length and that <code>x_condition</code> applies to <em>both</em> of these. Internally, rather than materializing <code>x[x_condition]</code>, we instead just loop over both <code>out</code> and <code>x</code> at the same time (at C level) and copy over values from <code>x</code> whenever <code>x_condition</code> is <code>TRUE</code>.</p>
<p>This is huge! It means that allocations 13-15 from above related to slicing <code>x</code>, <code>y</code>, and <code>z</code> all disappear.</p>
<h2 id="logical-indices">Logical <code>i</code>ndices
</h2>
<p>You might have noticed that we&rsquo;ve been using <code>which()</code> quite a bit in the above algorithm. This turns a logical vector of <code>TRUE</code> and <code>FALSE</code> into an integer vector of locations pointing to where the logical vector was <code>TRUE</code>:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>x_condition</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://rdrr.io/r/base/c.html'>c</a></span><span class='o'>(</span><span class='kc'>TRUE</span>, <span class='kc'>FALSE</span>, <span class='kc'>TRUE</span>, <span class='kc'>FALSE</span>, <span class='kc'>FALSE</span>, <span class='kc'>TRUE</span><span class='o'>)</span></span>
<span><span class='nv'>x_loc</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://rdrr.io/r/base/which.html'>which</a></span><span class='o'>(</span><span class='nv'>x_condition</span><span class='o'>)</span></span>
<span><span class='nv'>x_loc</span></span>
<span><span class='c'>#&gt; [1] 1 3 6</span></span>
<span></span></code></pre>
</div>
<p>We perform this conversion up front due to how the following works at C level:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>out</span><span class='o'>[</span><span class='nv'>x_condition</span><span class='o'>]</span> <span class='o'>&lt;-</span> <span class='nv'>x</span><span class='o'>[</span><span class='nv'>x_condition</span><span class='o'>]</span></span></code></pre>
</div>
<p>Both <code>[</code> and <code>[&lt;-</code> will convert a logical <code>x_condition</code> into the integer <code>x_loc</code> form before proceeding with the assignment, meaning that <code>which()</code> gets called twice if we don&rsquo;t do it once up front. And vctrs is the same way! Both <code>vec_assign()</code> and <code>vec_slice()</code> here would convert <code>x_condition</code> to an integer vector.</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nf'>vctrs</span><span class='nf'>::</span><span class='nf'><a href='https://vctrs.r-lib.org/reference/vec_slice.html'>vec_assign</a></span><span class='o'>(</span><span class='nv'>out</span>, <span class='nv'>x_condition</span>, <span class='nf'>vctrs</span><span class='nf'>::</span><span class='nf'><a href='https://vctrs.r-lib.org/reference/vec_slice.html'>vec_slice</a></span><span class='o'>(</span><span class='nv'>x</span>, <span class='nv'>x_condition</span><span class='o'>)</span><span class='o'>)</span></span></code></pre>
</div>
<p>Now, with the previous optimization we&rsquo;ve already seen that we can reduce this to:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nf'>vctrs</span><span class='nf'>::</span><span class='nf'><a href='https://vctrs.r-lib.org/reference/vec_slice.html'>vec_assign</a></span><span class='o'>(</span><span class='nv'>out</span>, <span class='nv'>x_condition</span>, <span class='nv'>x</span>, slice_value <span class='o'>=</span> <span class='kc'>TRUE</span><span class='o'>)</span></span></code></pre>
</div>
<p>But <code>vec_assign()</code> still converts a logical <code>x_condition</code> to integer locations internally before doing the assignment. So now it doesn&rsquo;t matter whether we do this conversion up front via <code>which()</code> or if we let <code>vec_assign()</code> do it, it still happens once per input. But we&rsquo;d like to avoid it entirely!</p>
<p>The solution here wasn&rsquo;t too magical, it just involved a good bit of grunt work. We&rsquo;ve added a path in <code>vec_assign()</code>&rsquo;s <a href="https://github.com/r-lib/vctrs/blob/94cea16b1ed3939aaa59c58dda75eedc75d6d075/src/slice-assign.c#L390-L417" target="_blank" rel="noopener">C code</a>
 that can handle logical indices like <code>x_condition</code> directly, rather than forcing them to be converted to integer locations first.</p>
<p>But this is a huge win, because it means that allocations 1-10, which were all related to <a href="https://rdrr.io/r/base/which.html" target="_blank" rel="noopener"><code>which()</code></a>
, can now be removed. <code>vec_assign()</code> will just handle that optimally for us without any extra allocations.</p>
<p>The nice part about an optimization like this is that any other existing code that is using <code>vec_assign()</code> with a logical index will also benefit from this without having to change a thing!</p>
<h2 id="default-handling"><code>default</code> handling
</h2>
<p>The remaining allocations are 11-12 and 16, which all have to do with the implied <code>default</code>. Allocations 11-12 were about figuring out where to put <code>default</code>, and allocation 16 was about recycling a typed size 1 <code>default</code> to the right size before assigning it into <code>out</code>.</p>
<p>As it turns out, we don&rsquo;t need any of this!</p>
<p>In vctrs, when we initialize any output container, we use <code>vec_init()</code>:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nf'>vctrs</span><span class='nf'>::</span><span class='nf'><a href='https://vctrs.r-lib.org/reference/vec_init.html'>vec_init</a></span><span class='o'>(</span><span class='nf'><a href='https://rdrr.io/r/base/integer.html'>integer</a></span><span class='o'>(</span><span class='o'>)</span>, n <span class='o'>=</span> <span class='m'>5</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; [1] NA NA NA NA NA</span></span>
<span></span><span></span>
<span><span class='nf'>vctrs</span><span class='nf'>::</span><span class='nf'><a href='https://vctrs.r-lib.org/reference/vec_init.html'>vec_init</a></span><span class='o'>(</span><span class='nf'><a href='https://tibble.tidyverse.org/reference/tibble.html'>tibble</a></span><span class='o'>(</span>x <span class='o'>=</span> <span class='nf'><a href='https://rdrr.io/r/base/integer.html'>integer</a></span><span class='o'>(</span><span class='o'>)</span>, y <span class='o'>=</span> <span class='nf'><a href='https://rdrr.io/r/base/character.html'>character</a></span><span class='o'>(</span><span class='o'>)</span><span class='o'>)</span>, n <span class='o'>=</span> <span class='m'>5</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># A tibble: 5 × 2</span></span></span>
<span><span class='c'>#&gt;       x y    </span></span>
<span><span class='c'>#&gt;   <span style='color: #555555; font-style: italic;'>&lt;int&gt;</span> <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>1</span>    <span style='color: #BB0000;'>NA</span> <span style='color: #BB0000;'>NA</span>   </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>2</span>    <span style='color: #BB0000;'>NA</span> <span style='color: #BB0000;'>NA</span>   </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>3</span>    <span style='color: #BB0000;'>NA</span> <span style='color: #BB0000;'>NA</span>   </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>4</span>    <span style='color: #BB0000;'>NA</span> <span style='color: #BB0000;'>NA</span>   </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>5</span>    <span style='color: #BB0000;'>NA</span> <span style='color: #BB0000;'>NA</span></span></span>
<span></span></code></pre>
</div>
<p>This <em>already</em> has the implied <code>default</code> assigned to every location. We then overwrite this with <code>x</code>, <code>y</code>, and <code>z</code> at the appropriate locations, but anything left untouched by those is still set to the <code>default</code>, so we&rsquo;re done!</p>
<p>For cases where the user supplies their own <code>default</code>, things are slightly more complicated. We actually do have to compute a <code>default_loc</code> implied from <code>x_condition</code>, <code>y_condition</code>, and <code>z_condition</code>, but internally we do so using a C vector of <code>bool</code> (even more efficient than R&rsquo;s logical vector type), so the memory footprint is as small as it can be.</p>
<h2 id="the-first-wins-conundrum">The &ldquo;first wins&rdquo; conundrum
</h2>
<p>One thing we&rsquo;ve skipped over is the &ldquo;first wins&rdquo; behavior of <a href="https://dplyr.tidyverse.org/reference/case-and-replace-when.html" target="_blank" rel="noopener"><code>case_when()</code></a>
 mentioned earlier. Now that we&rsquo;ve removed <code>x_loc</code>, <code>y_loc</code>, and <code>z_loc</code>, which is where that was being handled, how do we keep this behavior without slowing things down?</p>
<p>To be explicit, we are talking about this feature of <a href="https://dplyr.tidyverse.org/reference/case-and-replace-when.html" target="_blank" rel="noopener"><code>case_when()</code></a>
 where only the first hit is kept when you have overlapping logical indices:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>x</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://rdrr.io/r/base/c.html'>c</a></span><span class='o'>(</span><span class='s'>"x1"</span>, <span class='s'>"x2"</span>, <span class='s'>"x3"</span><span class='o'>)</span></span>
<span><span class='nv'>y</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://rdrr.io/r/base/c.html'>c</a></span><span class='o'>(</span><span class='s'>"y1"</span>, <span class='s'>"y2"</span>, <span class='s'>"y3"</span><span class='o'>)</span></span>
<span><span class='nv'>z</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://rdrr.io/r/base/c.html'>c</a></span><span class='o'>(</span><span class='s'>"z1"</span>, <span class='s'>"z2"</span>, <span class='s'>"z3"</span><span class='o'>)</span></span>
<span></span>
<span><span class='nv'>x_condition</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://rdrr.io/r/base/c.html'>c</a></span><span class='o'>(</span><span class='kc'>TRUE</span>, <span class='kc'>FALSE</span>, <span class='kc'>TRUE</span><span class='o'>)</span></span>
<span><span class='nv'>y_condition</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://rdrr.io/r/base/c.html'>c</a></span><span class='o'>(</span><span class='kc'>TRUE</span>, <span class='kc'>TRUE</span>, <span class='kc'>FALSE</span><span class='o'>)</span></span>
<span><span class='nv'>z_condition</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://rdrr.io/r/base/c.html'>c</a></span><span class='o'>(</span><span class='kc'>FALSE</span>, <span class='kc'>TRUE</span>, <span class='kc'>TRUE</span><span class='o'>)</span></span>
<span></span>
<span><span class='nf'><a href='https://dplyr.tidyverse.org/reference/case-and-replace-when.html'>case_when</a></span><span class='o'>(</span></span>
<span>  <span class='nv'>x_condition</span> <span class='o'>~</span> <span class='nv'>x</span>,</span>
<span>  <span class='nv'>y_condition</span> <span class='o'>~</span> <span class='nv'>y</span>,</span>
<span>  <span class='nv'>z_condition</span> <span class='o'>~</span> <span class='nv'>z</span></span>
<span><span class='o'>)</span></span>
<span><span class='c'>#&gt; [1] "x1" "y2" "x3"</span></span>
<span></span></code></pre>
</div>
<p>A naive approach doesn&rsquo;t work, as you end up with &ldquo;last wins&rdquo; behavior:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>out</span> <span class='o'>&lt;-</span> <span class='nf'>vctrs</span><span class='nf'>::</span><span class='nf'><a href='https://vctrs.r-lib.org/reference/vec_init.html'>vec_init</a></span><span class='o'>(</span><span class='nf'><a href='https://rdrr.io/r/base/character.html'>character</a></span><span class='o'>(</span><span class='o'>)</span>, n <span class='o'>=</span> <span class='m'>3</span><span class='o'>)</span></span>
<span></span>
<span><span class='nv'>out</span> <span class='o'>&lt;-</span> <span class='nf'>vctrs</span><span class='nf'>::</span><span class='nf'><a href='https://vctrs.r-lib.org/reference/vec_slice.html'>vec_assign</a></span><span class='o'>(</span><span class='nv'>out</span>, <span class='nv'>x_condition</span>, <span class='nv'>x</span>, slice_value <span class='o'>=</span> <span class='kc'>TRUE</span><span class='o'>)</span></span>
<span><span class='nv'>out</span> <span class='o'>&lt;-</span> <span class='nf'>vctrs</span><span class='nf'>::</span><span class='nf'><a href='https://vctrs.r-lib.org/reference/vec_slice.html'>vec_assign</a></span><span class='o'>(</span><span class='nv'>out</span>, <span class='nv'>y_condition</span>, <span class='nv'>y</span>, slice_value <span class='o'>=</span> <span class='kc'>TRUE</span><span class='o'>)</span></span>
<span><span class='nv'>out</span> <span class='o'>&lt;-</span> <span class='nf'>vctrs</span><span class='nf'>::</span><span class='nf'><a href='https://vctrs.r-lib.org/reference/vec_slice.html'>vec_assign</a></span><span class='o'>(</span><span class='nv'>out</span>, <span class='nv'>z_condition</span>, <span class='nv'>z</span>, slice_value <span class='o'>=</span> <span class='kc'>TRUE</span><span class='o'>)</span></span>
<span></span>
<span><span class='c'># This is wrong!</span></span>
<span><span class='nv'>out</span></span>
<span><span class='c'>#&gt; [1] "y1" "z2" "z3"</span></span>
<span></span><span></span>
<span><span class='nf'><a href='https://rdrr.io/r/base/identical.html'>identical</a></span><span class='o'>(</span></span>
<span>  <span class='nv'>out</span>,</span>
<span>  <span class='nf'><a href='https://dplyr.tidyverse.org/reference/case-and-replace-when.html'>case_when</a></span><span class='o'>(</span></span>
<span>    <span class='nv'>x_condition</span> <span class='o'>~</span> <span class='nv'>x</span>,</span>
<span>    <span class='nv'>y_condition</span> <span class='o'>~</span> <span class='nv'>y</span>,</span>
<span>    <span class='nv'>z_condition</span> <span class='o'>~</span> <span class='nv'>z</span></span>
<span>  <span class='o'>)</span></span>
<span><span class='o'>)</span></span>
<span><span class='c'>#&gt; [1] FALSE</span></span>
<span></span></code></pre>
</div>
<p>Instead, <a href="https://dplyr.tidyverse.org/reference/case-and-replace-when.html" target="_blank" rel="noopener"><code>case_when()</code></a>
 just <em>iterates in reverse</em>, assigning <code>z</code>, then <code>y</code>, then <code>x</code>:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>out</span> <span class='o'>&lt;-</span> <span class='nf'>vctrs</span><span class='nf'>::</span><span class='nf'><a href='https://vctrs.r-lib.org/reference/vec_init.html'>vec_init</a></span><span class='o'>(</span><span class='nf'><a href='https://rdrr.io/r/base/character.html'>character</a></span><span class='o'>(</span><span class='o'>)</span>, n <span class='o'>=</span> <span class='m'>3</span><span class='o'>)</span></span>
<span></span>
<span><span class='nv'>out</span> <span class='o'>&lt;-</span> <span class='nf'>vctrs</span><span class='nf'>::</span><span class='nf'><a href='https://vctrs.r-lib.org/reference/vec_slice.html'>vec_assign</a></span><span class='o'>(</span><span class='nv'>out</span>, <span class='nv'>z_condition</span>, <span class='nv'>z</span>, slice_value <span class='o'>=</span> <span class='kc'>TRUE</span><span class='o'>)</span></span>
<span><span class='nv'>out</span> <span class='o'>&lt;-</span> <span class='nf'>vctrs</span><span class='nf'>::</span><span class='nf'><a href='https://vctrs.r-lib.org/reference/vec_slice.html'>vec_assign</a></span><span class='o'>(</span><span class='nv'>out</span>, <span class='nv'>y_condition</span>, <span class='nv'>y</span>, slice_value <span class='o'>=</span> <span class='kc'>TRUE</span><span class='o'>)</span></span>
<span><span class='nv'>out</span> <span class='o'>&lt;-</span> <span class='nf'>vctrs</span><span class='nf'>::</span><span class='nf'><a href='https://vctrs.r-lib.org/reference/vec_slice.html'>vec_assign</a></span><span class='o'>(</span><span class='nv'>out</span>, <span class='nv'>x_condition</span>, <span class='nv'>x</span>, slice_value <span class='o'>=</span> <span class='kc'>TRUE</span><span class='o'>)</span></span>
<span></span>
<span><span class='nf'><a href='https://rdrr.io/r/base/identical.html'>identical</a></span><span class='o'>(</span></span>
<span>  <span class='nv'>out</span>,</span>
<span>  <span class='nf'><a href='https://dplyr.tidyverse.org/reference/case-and-replace-when.html'>case_when</a></span><span class='o'>(</span></span>
<span>    <span class='nv'>x_condition</span> <span class='o'>~</span> <span class='nv'>x</span>,</span>
<span>    <span class='nv'>y_condition</span> <span class='o'>~</span> <span class='nv'>y</span>,</span>
<span>    <span class='nv'>z_condition</span> <span class='o'>~</span> <span class='nv'>z</span></span>
<span>  <span class='o'>)</span></span>
<span><span class='o'>)</span></span>
<span><span class='c'>#&gt; [1] TRUE</span></span>
<span></span></code></pre>
</div>
<p>This diagram demonstrates how that works:</p>
<p><div class="not-prose"><figure>
    <img class="h-auto max-w-full rounded-lg"
      src="https://posit-open-source.netlify.app/blog/tidyverse/dplyr-performance/images/case-when-reverse.png"
      alt="" 
      loading="lazy"
    >
  </figure></div>
</p>
<h2 id="optimizing-speed">Optimizing speed?
</h2>
<p>Now that we&rsquo;ve optimized the memory usage of <a href="https://dplyr.tidyverse.org/reference/case-and-replace-when.html" target="_blank" rel="noopener"><code>case_when()</code></a>
, you might be wondering if we did anything else to specifically optimize its speed. Not really! We have moved everything from R to C, but focusing our efforts on reducing memory also resulted in some pretty performant code, and there wasn&rsquo;t much left to optimize after that.</p>
<h2 id="if_else"><code>if_else()</code>
</h2>
<p><a href="https://dplyr.tidyverse.org/reference/if_else.html" target="_blank" rel="noopener"><code>if_else()</code></a>
 can actually be written as a form of <a href="https://dplyr.tidyverse.org/reference/case-and-replace-when.html" target="_blank" rel="noopener"><code>case_when()</code></a>
:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nf'><a href='https://dplyr.tidyverse.org/reference/if_else.html'>if_else</a></span><span class='o'>(</span><span class='nv'>condition</span>, <span class='nv'>true</span>, <span class='nv'>false</span>, <span class='nv'>missing</span><span class='o'>)</span></span>
<span></span>
<span><span class='nf'><a href='https://dplyr.tidyverse.org/reference/case-and-replace-when.html'>case_when</a></span><span class='o'>(</span></span>
<span>  <span class='nv'>condition</span> <span class='o'>~</span> <span class='nv'>true</span>,</span>
<span>  <span class='o'>!</span><span class='nv'>condition</span> <span class='o'>~</span> <span class='nv'>false</span>,</span>
<span>  <span class='nf'><a href='https://rdrr.io/r/base/NA.html'>is.na</a></span><span class='o'>(</span><span class='nv'>condition</span><span class='o'>)</span> <span class='o'>~</span> <span class='nv'>missing</span></span>
<span><span class='o'>)</span></span></code></pre>
</div>
<p>In our actual C implementation of <a href="https://dplyr.tidyverse.org/reference/if_else.html" target="_blank" rel="noopener"><code>if_else()</code></a>
, for simple types like integer, character, or numeric vectors we have an <a href="https://github.com/r-lib/vctrs/blob/94cea16b1ed3939aaa59c58dda75eedc75d6d075/src/if-else.c#L276-L505" target="_blank" rel="noopener">extremely fast path</a>
 that&rsquo;s even more optimized than this, but for anything with a class we pretty much use this exact <a href="https://dplyr.tidyverse.org/reference/case-and-replace-when.html" target="_blank" rel="noopener"><code>case_when()</code></a>
 approach.</p>
<h2 id="for-package-developers">For package developers
</h2>
<p>If you&rsquo;re a package developer, you&rsquo;ll be happy to know that vctrs itself now exposes low dependency versions of <a href="https://dplyr.tidyverse.org/reference/if_else.html" target="_blank" rel="noopener"><code>if_else()</code></a>
 and <a href="https://dplyr.tidyverse.org/reference/case-and-replace-when.html" target="_blank" rel="noopener"><code>case_when()</code></a>
, here&rsquo;s the full family:</p>
<ul>
<li><code>vec_if_else()</code></li>
<li><code>vec_case_when()</code></li>
<li><code>vec_replace_when()</code></li>
<li><code>vec_recode_values()</code></li>
<li><code>vec_replace_values()</code></li>
</ul>
<p><a href="https://dplyr.tidyverse.org/reference/if_else.html" target="_blank" rel="noopener"><code>dplyr::if_else()</code></a>
 and friends are now just very thin wrappers over these. Feel free to use the vctrs versions in your package if you need the consistency of the tidyverse without the heavy-ish dependency of dplyr.</p>
<h2 id="at-the-deepest-level-list_combine">At the deepest level, <code>list_combine()</code>
</h2>
<p>At the deepest level of all of this is one final new vctrs function, <code>list_combine()</code>. This is a flexible way to combine multiple vectors together at locations specified by <code>indices</code>.</p>
<p><code>list_combine()</code> powers all of <code>vec_case_when()</code>, <code>vec_replace_when()</code>, <code>vec_recode_values()</code>, <code>vec_replace_values()</code>, <code>vec_if_else()</code>, and even <code>vec_c()</code>, the tidyverse version of <a href="https://rdrr.io/r/base/c.html" target="_blank" rel="noopener"><code>c()</code></a>
.</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nf'><a href='https://rdrr.io/r/base/Random.html'>set.seed</a></span><span class='o'>(</span><span class='m'>123</span><span class='o'>)</span></span>
<span></span>
<span><span class='nv'>column</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://rdrr.io/r/base/sample.html'>sample</a></span><span class='o'>(</span><span class='m'>100</span>, size <span class='o'>=</span> <span class='m'>1e7</span>, replace <span class='o'>=</span> <span class='kc'>TRUE</span><span class='o'>)</span></span>
<span></span>
<span><span class='nv'>x_condition</span> <span class='o'>&lt;-</span> <span class='nv'>column</span> <span class='o'>&lt;</span> <span class='m'>20</span></span>
<span><span class='nv'>y_condition</span> <span class='o'>&lt;-</span> <span class='nv'>column</span> <span class='o'>&lt;</span> <span class='m'>50</span></span>
<span><span class='nv'>z_condition</span> <span class='o'>&lt;-</span> <span class='nv'>column</span> <span class='o'>&lt;</span> <span class='m'>80</span></span>
<span></span>
<span><span class='nv'>x</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://rdrr.io/r/base/sample.html'>sample</a></span><span class='o'>(</span><span class='m'>10</span>, size <span class='o'>=</span> <span class='m'>1e7</span>, replace <span class='o'>=</span> <span class='kc'>TRUE</span><span class='o'>)</span></span>
<span><span class='nv'>y</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://rdrr.io/r/base/sample.html'>sample</a></span><span class='o'>(</span><span class='m'>10</span>, size <span class='o'>=</span> <span class='m'>1e7</span>, replace <span class='o'>=</span> <span class='kc'>TRUE</span><span class='o'>)</span></span>
<span><span class='nv'>z</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://rdrr.io/r/base/sample.html'>sample</a></span><span class='o'>(</span><span class='m'>10</span>, size <span class='o'>=</span> <span class='m'>1e7</span>, replace <span class='o'>=</span> <span class='kc'>TRUE</span><span class='o'>)</span></span>
<span></span>
<span><span class='nv'>out</span> <span class='o'>&lt;-</span> <span class='nf'>vctrs</span><span class='nf'>::</span><span class='nf'><a href='https://vctrs.r-lib.org/reference/list_combine.html'>list_combine</a></span><span class='o'>(</span></span>
<span>  x <span class='o'>=</span> <span class='nf'><a href='https://rdrr.io/r/base/list.html'>list</a></span><span class='o'>(</span><span class='nv'>x</span>, <span class='nv'>y</span>, <span class='nv'>z</span><span class='o'>)</span>,</span>
<span></span>
<span>  <span class='c'># `indices` are allowed to be logical and aren't forced to integer</span></span>
<span>  indices <span class='o'>=</span> <span class='nf'><a href='https://rdrr.io/r/base/list.html'>list</a></span><span class='o'>(</span><span class='nv'>x_condition</span>, <span class='nv'>y_condition</span>, <span class='nv'>z_condition</span><span class='o'>)</span>,</span>
<span>  size <span class='o'>=</span> <span class='nf'><a href='https://rdrr.io/r/base/length.html'>length</a></span><span class='o'>(</span><span class='nv'>x_condition</span><span class='o'>)</span>,</span>
<span></span>
<span>  <span class='c'># When there are overlaps, take the "first"</span></span>
<span>  multiple <span class='o'>=</span> <span class='s'>"first"</span>,</span>
<span></span>
<span>  <span class='c'># Same as `slice_value` from `vec_assign()`</span></span>
<span>  slice_x <span class='o'>=</span> <span class='kc'>TRUE</span></span>
<span><span class='o'>)</span></span></code></pre>
</div>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nf'><a href='https://rdrr.io/r/base/identical.html'>identical</a></span><span class='o'>(</span></span>
<span>  <span class='nv'>out</span>,</span>
<span>  <span class='nf'><a href='https://dplyr.tidyverse.org/reference/case-and-replace-when.html'>case_when</a></span><span class='o'>(</span></span>
<span>    <span class='nv'>x_condition</span> <span class='o'>~</span> <span class='nv'>x</span>,</span>
<span>    <span class='nv'>y_condition</span> <span class='o'>~</span> <span class='nv'>y</span>,</span>
<span>    <span class='nv'>z_condition</span> <span class='o'>~</span> <span class='nv'>z</span></span>
<span>  <span class='o'>)</span></span>
<span><span class='o'>)</span></span>
<span><span class='c'>#&gt; [1] TRUE</span></span>
<span></span></code></pre>
</div>
]]></description>
      <enclosure url="https://posit-open-source.netlify.app/blog/tidyverse/dplyr-performance/thumbnail-wd.jpg" length="179655" type="image/jpeg" />
    </item>
    <item>
      <title>dplyr 1.2.0</title>
      <link>https://posit-open-source.netlify.app/blog/tidyverse/dplyr-1-2-0/</link>
      <pubDate>Wed, 04 Feb 2026 00:00:00 +0000</pubDate>
      <guid>https://posit-open-source.netlify.app/blog/tidyverse/dplyr-1-2-0/</guid>
      <dc:creator>Davis Vaughan</dc:creator><description><![CDATA[<p><a href="https://dplyr.tidyverse.org" target="_blank" rel="noopener">dplyr 1.2.0</a>
 is out now! This large release of dplyr comes with two sets of exciting features:</p>
<ul>
<li>
<p><a href="https://dplyr.tidyverse.org/reference/filter.html" target="_blank" rel="noopener"><code>filter_out()</code></a>
, the missing complement to <a href="https://dplyr.tidyverse.org/reference/filter.html" target="_blank" rel="noopener"><code>filter()</code></a>
, and accompanying <a href="https://dplyr.tidyverse.org/reference/when-any-all.html" target="_blank" rel="noopener"><code>when_any()</code></a>
 and <a href="https://dplyr.tidyverse.org/reference/when-any-all.html" target="_blank" rel="noopener"><code>when_all()</code></a>
 helpers.</p>
</li>
<li>
<p><a href="https://dplyr.tidyverse.org/reference/recode-and-replace-values.html" target="_blank" rel="noopener"><code>recode_values()</code></a>
, <a href="https://dplyr.tidyverse.org/reference/recode-and-replace-values.html" target="_blank" rel="noopener"><code>replace_values()</code></a>
, and <a href="https://dplyr.tidyverse.org/reference/case-and-replace-when.html" target="_blank" rel="noopener"><code>replace_when()</code></a>
, three new functions that join <a href="https://dplyr.tidyverse.org/reference/case-and-replace-when.html" target="_blank" rel="noopener"><code>case_when()</code></a>
 to create a cohesive family of powerful tools for recoding and replacing.</p>
</li>
</ul>
<p>Both of these sets of features are backed by successful <em>tidyups</em>, the tidyverse&rsquo;s community facing proposal process (<a href="https://github.com/tidyverse/tidyups/pull/30" target="_blank" rel="noopener">filtering</a>
, <a href="https://github.com/tidyverse/tidyups/pull/29" target="_blank" rel="noopener">recoding</a>
). We really enjoyed having the community weigh in on these features!</p>
<p>You can install dplyr 1.2.0 from CRAN with:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nf'><a href='https://rdrr.io/r/utils/install.packages.html'>install.packages</a></span><span class='o'>(</span><span class='s'>"dplyr"</span><span class='o'>)</span></span></code></pre>
</div>
<p>You can see a full list of changes in the <a href="https://github.com/tidyverse/dplyr/releases/tag/v1.2.0" target="_blank" rel="noopener">release notes</a>
.</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='kr'><a href='https://rdrr.io/r/base/library.html'>library</a></span><span class='o'>(</span><span class='nv'><a href='https://dplyr.tidyverse.org'>dplyr</a></span><span class='o'>)</span></span></code></pre>
</div>
<h2 id="expanding-the-filter-family">Expanding the <code>filter()</code> family
</h2>
<p><a href="https://dplyr.tidyverse.org/reference/filter.html" target="_blank" rel="noopener"><code>filter()</code></a>
 has been a core dplyr verb since the very beginning, but over the years we&rsquo;ve isolated a few key issues with it:</p>
<ul>
<li>
<p>The name <a href="https://dplyr.tidyverse.org/reference/filter.html" target="_blank" rel="noopener"><code>filter()</code></a>
 is ambiguous, are you keeping or dropping rows? i.e., are you filtering <em>for</em> rows or filtering <em>out</em> rows?</p>
</li>
<li>
<p><a href="https://dplyr.tidyverse.org/reference/filter.html" target="_blank" rel="noopener"><code>filter()</code></a>
 is optimized for the case of <em>keeping</em> rows, but you are just as likely to try and use it for <em>dropping</em> rows. Using <a href="https://dplyr.tidyverse.org/reference/filter.html" target="_blank" rel="noopener"><code>filter()</code></a>
 to drop rows quickly forces you to confront complex boolean logic and explicitly handle missing values, which is difficult to teach, error prone to write, and hard to understand when you come back to it in the future.</p>
</li>
<li>
<p><a href="https://dplyr.tidyverse.org/reference/filter.html" target="_blank" rel="noopener"><code>filter()</code></a>
 combines comma separated conditions with <code>&amp;</code> because this covers the majority of the cases. But if you&rsquo;d like to combine conditions with <code>|</code>, then you have to introduce parentheses around your conditions and combine them into one large condition separated by <code>|</code>, reducing readability.</p>
</li>
</ul>
<p>In the next few sections, we&rsquo;ll motivate these issues and discuss how some new features in dplyr can simplify things dramatically!</p>
<h3 id="filteringout">Filtering&hellip;out!
</h3>
<p>Take a look at this <code>patients</code> data. Our task with this data is:</p>
<blockquote>
<p><em>Filter out</em> rows where the patient is deceased <em>and</em> the year was before 2012.</p>
</blockquote>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>patients</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://tibble.tidyverse.org/reference/tibble.html'>tibble</a></span><span class='o'>(</span></span>
<span>  name <span class='o'>=</span> <span class='nf'><a href='https://rdrr.io/r/base/c.html'>c</a></span><span class='o'>(</span><span class='s'>"Anne"</span>, <span class='s'>"Mark"</span>, <span class='s'>"Sarah"</span>, <span class='s'>"Davis"</span>, <span class='s'>"Max"</span>, <span class='s'>"Derek"</span>, <span class='s'>"Tina"</span><span class='o'>)</span>,</span>
<span>  deceased <span class='o'>=</span> <span class='nf'><a href='https://rdrr.io/r/base/c.html'>c</a></span><span class='o'>(</span><span class='kc'>FALSE</span>, <span class='kc'>TRUE</span>, <span class='kc'>NA</span>, <span class='kc'>TRUE</span>, <span class='kc'>NA</span>, <span class='kc'>FALSE</span>, <span class='kc'>TRUE</span><span class='o'>)</span>,</span>
<span>  date <span class='o'>=</span> <span class='nf'><a href='https://rdrr.io/r/base/c.html'>c</a></span><span class='o'>(</span><span class='m'>2005</span>, <span class='m'>2010</span>, <span class='kc'>NA</span>, <span class='m'>2020</span>, <span class='m'>2010</span>, <span class='kc'>NA</span>, <span class='kc'>NA</span><span class='o'>)</span></span>
<span><span class='o'>)</span></span>
<span></span>
<span><span class='nv'>patients</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># A tibble: 7 × 3</span></span></span>
<span><span class='c'>#&gt;   name  deceased  date</span></span>
<span><span class='c'>#&gt;   <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span> <span style='color: #555555; font-style: italic;'>&lt;lgl&gt;</span>    <span style='color: #555555; font-style: italic;'>&lt;dbl&gt;</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>1</span> Anne  FALSE     <span style='text-decoration: underline;'>2</span>005</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>2</span> Mark  TRUE      <span style='text-decoration: underline;'>2</span>010</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>3</span> Sarah <span style='color: #BB0000;'>NA</span>          <span style='color: #BB0000;'>NA</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>4</span> Davis TRUE      <span style='text-decoration: underline;'>2</span>020</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>5</span> Max   <span style='color: #BB0000;'>NA</span>        <span style='text-decoration: underline;'>2</span>010</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>6</span> Derek FALSE       <span style='color: #BB0000;'>NA</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>7</span> Tina  TRUE        <span style='color: #BB0000;'>NA</span></span></span>
<span></span></code></pre>
</div>
<p>With <a href="https://dplyr.tidyverse.org/reference/filter.html" target="_blank" rel="noopener"><code>filter()</code></a>
, you&rsquo;d probably start by translating &ldquo;patient is deceased and the year was before 2012&rdquo; into <code>deceased &amp; date &lt; 2012</code>, and then inverting that with <code>!(&lt;expression&gt;)</code> to drop rows:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>patients</span> <span class='o'>|&gt;</span></span>
<span>  <span class='nf'><a href='https://dplyr.tidyverse.org/reference/filter.html'>filter</a></span><span class='o'>(</span><span class='o'>!</span><span class='o'>(</span><span class='nv'>deceased</span> <span class='o'>&amp;</span> <span class='nv'>date</span> <span class='o'>&lt;</span> <span class='m'>2012</span><span class='o'>)</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># A tibble: 3 × 3</span></span></span>
<span><span class='c'>#&gt;   name  deceased  date</span></span>
<span><span class='c'>#&gt;   <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span> <span style='color: #555555; font-style: italic;'>&lt;lgl&gt;</span>    <span style='color: #555555; font-style: italic;'>&lt;dbl&gt;</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>1</span> Anne  FALSE     <span style='text-decoration: underline;'>2</span>005</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>2</span> Davis TRUE      <span style='text-decoration: underline;'>2</span>020</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>3</span> Derek FALSE       <span style='color: #BB0000;'>NA</span></span></span>
<span></span></code></pre>
</div>
<p>That seems to have worked, let&rsquo;s use an <a href="https://dplyr.tidyverse.org/reference/filter-joins.html" target="_blank" rel="noopener"><code>anti_join()</code></a>
 to check with rows have been dropped from <code>patients</code>:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='c'># These rows were dropped</span></span>
<span><span class='nf'><a href='https://dplyr.tidyverse.org/reference/filter-joins.html'>anti_join</a></span><span class='o'>(</span></span>
<span>  <span class='nv'>patients</span>,</span>
<span>  <span class='nv'>patients</span> <span class='o'>|&gt;</span> <span class='nf'><a href='https://dplyr.tidyverse.org/reference/filter.html'>filter</a></span><span class='o'>(</span><span class='o'>!</span><span class='o'>(</span><span class='nv'>deceased</span> <span class='o'>&amp;</span> <span class='nv'>date</span> <span class='o'>&lt;</span> <span class='m'>2012</span><span class='o'>)</span><span class='o'>)</span>,</span>
<span>  <span class='nf'><a href='https://dplyr.tidyverse.org/reference/join_by.html'>join_by</a></span><span class='o'>(</span><span class='nv'>name</span>, <span class='nv'>deceased</span>, <span class='nv'>date</span><span class='o'>)</span></span>
<span><span class='o'>)</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># A tibble: 4 × 3</span></span></span>
<span><span class='c'>#&gt;   name  deceased  date</span></span>
<span><span class='c'>#&gt;   <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span> <span style='color: #555555; font-style: italic;'>&lt;lgl&gt;</span>    <span style='color: #555555; font-style: italic;'>&lt;dbl&gt;</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>1</span> Mark  TRUE      <span style='text-decoration: underline;'>2</span>010</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>2</span> Sarah <span style='color: #BB0000;'>NA</span>          <span style='color: #BB0000;'>NA</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>3</span> Max   <span style='color: #BB0000;'>NA</span>        <span style='text-decoration: underline;'>2</span>010</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>4</span> Tina  TRUE        <span style='color: #BB0000;'>NA</span></span></span>
<span></span></code></pre>
</div>
<p>This is subtly wrong! We only wanted to drop rows where we <em>know</em> that the patient was deceased before 2012. If a missing value is present, we <em>don&rsquo;t</em> want to drop that row because we aren&rsquo;t sure about the condition. In this case, we were hoping to only drop <code>Mark</code>! It seems like <a href="https://dplyr.tidyverse.org/reference/filter.html" target="_blank" rel="noopener"><code>filter()</code></a>
 has unexpectedly <em>dropped more rows than we expected</em>.</p>
<p>Here&rsquo;s what a technically correct <a href="https://dplyr.tidyverse.org/reference/filter.html" target="_blank" rel="noopener"><code>filter()</code></a>
 call might look like:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>patients</span> <span class='o'>|&gt;</span></span>
<span>  <span class='nf'><a href='https://dplyr.tidyverse.org/reference/filter.html'>filter</a></span><span class='o'>(</span></span>
<span>    <span class='o'>!</span><span class='o'>(</span><span class='o'>(</span><span class='nv'>deceased</span> <span class='o'>&amp;</span> <span class='o'>!</span><span class='nf'><a href='https://rdrr.io/r/base/NA.html'>is.na</a></span><span class='o'>(</span><span class='nv'>deceased</span><span class='o'>)</span><span class='o'>)</span> <span class='o'>&amp;</span></span>
<span>      <span class='o'>(</span><span class='nv'>date</span> <span class='o'>&lt;</span> <span class='m'>2012</span> <span class='o'>&amp;</span> <span class='o'>!</span><span class='nf'><a href='https://rdrr.io/r/base/NA.html'>is.na</a></span><span class='o'>(</span><span class='nv'>date</span><span class='o'>)</span><span class='o'>)</span><span class='o'>)</span></span>
<span>  <span class='o'>)</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># A tibble: 6 × 3</span></span></span>
<span><span class='c'>#&gt;   name  deceased  date</span></span>
<span><span class='c'>#&gt;   <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span> <span style='color: #555555; font-style: italic;'>&lt;lgl&gt;</span>    <span style='color: #555555; font-style: italic;'>&lt;dbl&gt;</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>1</span> Anne  FALSE     <span style='text-decoration: underline;'>2</span>005</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>2</span> Sarah <span style='color: #BB0000;'>NA</span>          <span style='color: #BB0000;'>NA</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>3</span> Davis TRUE      <span style='text-decoration: underline;'>2</span>020</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>4</span> Max   <span style='color: #BB0000;'>NA</span>        <span style='text-decoration: underline;'>2</span>010</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>5</span> Derek FALSE       <span style='color: #BB0000;'>NA</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>6</span> Tina  TRUE        <span style='color: #BB0000;'>NA</span></span></span>
<span></span></code></pre>
</div>
<p>That&rsquo;s horrible! You&rsquo;ll likely look back on this in a year wondering what you were even trying to do here.</p>
<p>This phenomenon is rather confusing, but is due to the fact that <a href="https://dplyr.tidyverse.org/reference/filter.html" target="_blank" rel="noopener"><code>filter()</code></a>
 is designed around the idea that you&rsquo;re going to tell it which rows to <em>keep</em>. With that design in mind, dropping <code>NA</code>s makes sense, i.e. if you don&rsquo;t <em>know</em> that you want to keep that row (because an <code>NA</code> is ambiguous), then you probably don&rsquo;t want to keep it.</p>
<p>This works well until you try to use <a href="https://dplyr.tidyverse.org/reference/filter.html" target="_blank" rel="noopener"><code>filter()</code></a>
 as a way to <em>filter out</em> rows, at which point this behavior works against you. At this point, most people (reasonably!) reach for <code>&amp; !is.na()</code> and you end up with the mess from above.</p>
<p>We took a close look at many examples like this one, and eventually realized that the core issue is:</p>
<ul>
<li><a href="https://dplyr.tidyverse.org/reference/filter.html" target="_blank" rel="noopener"><code>filter()</code></a>
 is designed around supplying which rows to <em>keep</em></li>
<li>We are missing a verb designed around supplying which rows to <em>drop</em></li>
</ul>
<p><a href="https://dplyr.tidyverse.org/reference/filter.html" target="_blank" rel="noopener"><code>filter_out()</code></a>
 fills that gap:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>patients</span> <span class='o'>|&gt;</span></span>
<span>  <span class='nf'><a href='https://dplyr.tidyverse.org/reference/filter.html'>filter_out</a></span><span class='o'>(</span><span class='nv'>deceased</span>, <span class='nv'>date</span> <span class='o'>&lt;</span> <span class='m'>2012</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># A tibble: 6 × 3</span></span></span>
<span><span class='c'>#&gt;   name  deceased  date</span></span>
<span><span class='c'>#&gt;   <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span> <span style='color: #555555; font-style: italic;'>&lt;lgl&gt;</span>    <span style='color: #555555; font-style: italic;'>&lt;dbl&gt;</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>1</span> Anne  FALSE     <span style='text-decoration: underline;'>2</span>005</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>2</span> Sarah <span style='color: #BB0000;'>NA</span>          <span style='color: #BB0000;'>NA</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>3</span> Davis TRUE      <span style='text-decoration: underline;'>2</span>020</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>4</span> Max   <span style='color: #BB0000;'>NA</span>        <span style='text-decoration: underline;'>2</span>010</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>5</span> Derek FALSE       <span style='color: #BB0000;'>NA</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>6</span> Tina  TRUE        <span style='color: #BB0000;'>NA</span></span></span>
<span></span></code></pre>
</div>
<p>Just like with <a href="https://dplyr.tidyverse.org/reference/filter.html" target="_blank" rel="noopener"><code>filter()</code></a>
, <a href="https://dplyr.tidyverse.org/reference/filter.html" target="_blank" rel="noopener"><code>filter_out()</code></a>
 treats <code>NA</code> values as <code>FALSE</code>. The difference is that <a href="https://dplyr.tidyverse.org/reference/filter.html" target="_blank" rel="noopener"><code>filter_out()</code></a>
 expects that you are going to tell it which rows to <em>drop</em> (rather than which rows to keep), so the default behavior of treating <code>NA</code> like <code>FALSE</code> works <em>with you</em> rather than <em>against you</em>. It&rsquo;s also much easier to understand when you look back on it a year from now!</p>
<p>In general, our advice is that if you find yourself using &ldquo;negative&rdquo; operators like <code>!=</code> or <code>!</code> or reaching for the <code>!is.na()</code> pattern to manually handle missing values, try reaching for <a href="https://dplyr.tidyverse.org/reference/filter.html" target="_blank" rel="noopener"><code>filter_out()</code></a>
 instead.</p>
<p>Personally, I&rsquo;ve always been pretty jealous of Stata here because they had both <a href="https://www.stata.com/manuals/ddrop.pdf" target="_blank" rel="noopener"><code>keep if</code> and <code>drop if</code></a>
, allowing them to write <code>drop if deceased &amp; date &lt; 2012</code>. In my first job, I translated a bunch of Stata code over to R and still remember being frustrated by <code>NA</code> handling every time I had to translate a <code>drop if</code> to a <a href="https://dplyr.tidyverse.org/reference/filter.html" target="_blank" rel="noopener"><code>filter()</code></a>
. With <a href="https://dplyr.tidyverse.org/reference/filter.html" target="_blank" rel="noopener"><code>filter_out()</code></a>
, it feels like I can finally let go of a long term grudge I&rsquo;ve held over the past 6 years 🙂.</p>
<h3 id="combining-with-or-rather-than-and">Combining with <code>OR</code> rather than <code>AND</code>
</h3>
<p>So far, we&rsquo;ve talked a lot about <em>dropping</em> rows, but dplyr 1.2.0 also has a new feature to help with <em>keeping</em> rows using conditions combined with <code>|</code> - <a href="https://dplyr.tidyverse.org/reference/when-any-all.html" target="_blank" rel="noopener"><code>when_any()</code></a>
.</p>
<p>Our goal here is:</p>
<blockquote>
<p><em>Filter for</em> rows where &ldquo;US&rdquo; and &ldquo;CA&rdquo; have a score between 200-300, <em>or</em> rows where &ldquo;PR&rdquo; and &ldquo;RU&rdquo; have a score between 100-200.</p>
</blockquote>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>countries</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://tibble.tidyverse.org/reference/tibble.html'>tibble</a></span><span class='o'>(</span></span>
<span>  name <span class='o'>=</span> <span class='nf'><a href='https://rdrr.io/r/base/c.html'>c</a></span><span class='o'>(</span><span class='s'>"US"</span>, <span class='s'>"CA"</span>, <span class='s'>"PR"</span>, <span class='s'>"RU"</span>, <span class='s'>"US"</span>, <span class='kc'>NA</span>, <span class='s'>"CA"</span>, <span class='s'>"PR"</span><span class='o'>)</span>,</span>
<span>  score <span class='o'>=</span> <span class='nf'><a href='https://rdrr.io/r/base/c.html'>c</a></span><span class='o'>(</span><span class='m'>200</span>, <span class='m'>100</span>, <span class='m'>150</span>, <span class='kc'>NA</span>, <span class='m'>50</span>, <span class='m'>100</span>, <span class='m'>300</span>, <span class='m'>250</span><span class='o'>)</span></span>
<span><span class='o'>)</span></span>
<span></span>
<span><span class='nv'>countries</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># A tibble: 8 × 2</span></span></span>
<span><span class='c'>#&gt;   name  score</span></span>
<span><span class='c'>#&gt;   <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span> <span style='color: #555555; font-style: italic;'>&lt;dbl&gt;</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>1</span> US      200</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>2</span> CA      100</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>3</span> PR      150</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>4</span> RU       <span style='color: #BB0000;'>NA</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>5</span> US       50</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>6</span> <span style='color: #BB0000;'>NA</span>      100</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>7</span> CA      300</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>8</span> PR      250</span></span>
<span></span></code></pre>
</div>
<p>Here&rsquo;s a <a href="https://dplyr.tidyverse.org/reference/filter.html" target="_blank" rel="noopener"><code>filter()</code></a>
 solution, note how we lose the ability to specify comma separated conditions, and in the process we&rsquo;ve introduced 3 operators, <code>&amp;</code>, <code>|</code>, and <code>()</code>, decreasing readability and increasing the mental gymnastics required to understand it:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>countries</span> <span class='o'>|&gt;</span></span>
<span>  <span class='nf'><a href='https://dplyr.tidyverse.org/reference/filter.html'>filter</a></span><span class='o'>(</span></span>
<span>    <span class='o'>(</span><span class='nv'>name</span> <span class='o'><a href='https://rdrr.io/r/base/match.html'>%in%</a></span> <span class='nf'><a href='https://rdrr.io/r/base/c.html'>c</a></span><span class='o'>(</span><span class='s'>"US"</span>, <span class='s'>"CA"</span><span class='o'>)</span> <span class='o'>&amp;</span> <span class='nf'><a href='https://dplyr.tidyverse.org/reference/between.html'>between</a></span><span class='o'>(</span><span class='nv'>score</span>, <span class='m'>200</span>, <span class='m'>300</span><span class='o'>)</span><span class='o'>)</span> <span class='o'>|</span></span>
<span>      <span class='o'>(</span><span class='nv'>name</span> <span class='o'><a href='https://rdrr.io/r/base/match.html'>%in%</a></span> <span class='nf'><a href='https://rdrr.io/r/base/c.html'>c</a></span><span class='o'>(</span><span class='s'>"PR"</span>, <span class='s'>"RU"</span><span class='o'>)</span> <span class='o'>&amp;</span> <span class='nf'><a href='https://dplyr.tidyverse.org/reference/between.html'>between</a></span><span class='o'>(</span><span class='nv'>score</span>, <span class='m'>100</span>, <span class='m'>200</span><span class='o'>)</span><span class='o'>)</span></span>
<span>  <span class='o'>)</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># A tibble: 3 × 2</span></span></span>
<span><span class='c'>#&gt;   name  score</span></span>
<span><span class='c'>#&gt;   <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span> <span style='color: #555555; font-style: italic;'>&lt;dbl&gt;</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>1</span> US      200</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>2</span> PR      150</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>3</span> CA      300</span></span>
<span></span></code></pre>
</div>
<p>With <a href="https://dplyr.tidyverse.org/reference/when-any-all.html" target="_blank" rel="noopener"><code>when_any()</code></a>
, you specify comma separated conditions like you&rsquo;re used to, but they get combined with <code>|</code> rather than <code>&amp;</code>. This allows us to reduce the amount of operators introduced down to just <code>&amp;</code>, and it remains very readable:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>countries</span> <span class='o'>|&gt;</span></span>
<span>  <span class='nf'><a href='https://dplyr.tidyverse.org/reference/filter.html'>filter</a></span><span class='o'>(</span><span class='nf'><a href='https://dplyr.tidyverse.org/reference/when-any-all.html'>when_any</a></span><span class='o'>(</span></span>
<span>    <span class='nv'>name</span> <span class='o'><a href='https://rdrr.io/r/base/match.html'>%in%</a></span> <span class='nf'><a href='https://rdrr.io/r/base/c.html'>c</a></span><span class='o'>(</span><span class='s'>"US"</span>, <span class='s'>"CA"</span><span class='o'>)</span> <span class='o'>&amp;</span> <span class='nf'><a href='https://dplyr.tidyverse.org/reference/between.html'>between</a></span><span class='o'>(</span><span class='nv'>score</span>, <span class='m'>200</span>, <span class='m'>300</span><span class='o'>)</span>,</span>
<span>    <span class='nv'>name</span> <span class='o'><a href='https://rdrr.io/r/base/match.html'>%in%</a></span> <span class='nf'><a href='https://rdrr.io/r/base/c.html'>c</a></span><span class='o'>(</span><span class='s'>"PR"</span>, <span class='s'>"RU"</span><span class='o'>)</span> <span class='o'>&amp;</span> <span class='nf'><a href='https://dplyr.tidyverse.org/reference/between.html'>between</a></span><span class='o'>(</span><span class='nv'>score</span>, <span class='m'>100</span>, <span class='m'>200</span><span class='o'>)</span></span>
<span>  <span class='o'>)</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># A tibble: 3 × 2</span></span></span>
<span><span class='c'>#&gt;   name  score</span></span>
<span><span class='c'>#&gt;   <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span> <span style='color: #555555; font-style: italic;'>&lt;dbl&gt;</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>1</span> US      200</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>2</span> PR      150</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>3</span> CA      300</span></span>
<span></span></code></pre>
</div>
<p><a href="https://dplyr.tidyverse.org/reference/when-any-all.html" target="_blank" rel="noopener"><code>when_any()</code></a>
 and its counterpart <a href="https://dplyr.tidyverse.org/reference/when-any-all.html" target="_blank" rel="noopener"><code>when_all()</code></a>
 aren&rsquo;t restricted to <a href="https://dplyr.tidyverse.org/reference/filter.html" target="_blank" rel="noopener"><code>filter()</code></a>
. They are normal vector functions that can be used anywhere. And if you&rsquo;re a package author, you might be interested in <a href="https://vctrs.r-lib.org/reference/parallel-operators.html" target="_blank" rel="noopener"><code>vctrs::vec_pany()</code></a>
 and <a href="https://vctrs.r-lib.org/reference/parallel-operators.html" target="_blank" rel="noopener"><code>vctrs::vec_pall()</code></a>
, the underlying low dependency functions that power the dplyr variants.</p>
<h2 id="reaching-recoding-nirvana">Reaching recoding nirvana
</h2>
<p>Over the years, we&rsquo;ve experimented with various ways of recoding columns and replacing values within them, including:</p>
<ul>
<li><a href="https://rdrr.io/pkg/plyr/man/mapvalues.html" target="_blank" rel="noopener"><code>plyr::mapvalues()</code></a>
</li>
<li><a href="https://rdrr.io/pkg/plyr/man/revalue.html" target="_blank" rel="noopener"><code>plyr::revalue()</code></a>
</li>
<li><a href="https://dplyr.tidyverse.org/reference/recode.html" target="_blank" rel="noopener"><code>dplyr::recode()</code></a>
</li>
<li><a href="https://dplyr.tidyverse.org/reference/case-and-replace-when.html" target="_blank" rel="noopener"><code>dplyr::case_when()</code></a>
</li>
</ul>
<p>Despite all of our improvements, it&rsquo;s felt like there have always been holes in our solutions. Most recently, this came to the forefront in a post about <a href="https://www.linkedin.com/posts/libbyheeren_rstats-activity-7343291858275487744-XlPl?utm_source=share&amp;utm_medium=member_desktop&amp;rcm=ACoAAAy7IywB2qfaREGGoCca5XkthJ2hLjru6ts" target="_blank" rel="noopener">recoding using a lookup table</a>
, which is almost impossible to do with <a href="https://dplyr.tidyverse.org/reference/case-and-replace-when.html" target="_blank" rel="noopener"><code>case_when()</code></a>
, and had people resorting to confusing solutions using the superseded <a href="https://dplyr.tidyverse.org/reference/recode.html" target="_blank" rel="noopener"><code>dplyr::recode()</code></a>
 combined with <code>!!!</code> to splice in a lookup table.</p>
<p>After seeing this, we took a step back and were finally able to isolate the issues with our current solutions. The result of our <a href="https://github.com/tidyverse/tidyups/pull/29" target="_blank" rel="noopener">analysis</a>
 is three new functions that join <a href="https://dplyr.tidyverse.org/reference/case-and-replace-when.html" target="_blank" rel="noopener"><code>case_when()</code></a>
 to form a powerful recoding and replacing family.</p>
<p>It&rsquo;ll be helpful to define exactly what we mean by recoding vs replacing:</p>
<ul>
<li>
<p><em>Recoding</em> a column creates an entirely new column using values from an existing column. The new column may have a different type from the original column.</p>
</li>
<li>
<p><em>Replacing</em> values within a column partially updates an existing column with new values. The result has the same type as the original column.</p>
</li>
</ul>
<p>The family of functions can be summarized by the following table:</p>
<table>
  <thead>
      <tr>
          <th></th>
          <th><strong>Recoding</strong></th>
          <th><strong>Replacing</strong></th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>Match with conditions</strong></td>
          <td><a href="https://dplyr.tidyverse.org/reference/case-and-replace-when.html" target="_blank" rel="noopener"><code>case_when()</code></a>
</td>
          <td><a href="https://dplyr.tidyverse.org/reference/case-and-replace-when.html" target="_blank" rel="noopener"><code>replace_when()</code></a>
</td>
      </tr>
      <tr>
          <td><strong>Match with values</strong></td>
          <td><a href="https://dplyr.tidyverse.org/reference/recode-and-replace-values.html" target="_blank" rel="noopener"><code>recode_values()</code></a>
</td>
          <td><a href="https://dplyr.tidyverse.org/reference/recode-and-replace-values.html" target="_blank" rel="noopener"><code>replace_values()</code></a>
</td>
      </tr>
  </tbody>
</table>
<p>We&rsquo;ve written a <a href="https://dplyr.tidyverse.org/articles/recoding-replacing.html" target="_blank" rel="noopener">new vignette</a>
 that expands on all of these from first principles, and in the next few sections we&rsquo;ll look at some examples.</p>
<h3 id="recode_values"><code>recode_values()</code>
</h3>
<p>The goal of the post from above was to recode a numeric column of <a href="https://en.wikipedia.org/wiki/Likert_scale" target="_blank" rel="noopener">Likert scale</a>
 scores into their string counterparts.</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>likert</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://tibble.tidyverse.org/reference/tibble.html'>tibble</a></span><span class='o'>(</span></span>
<span>  score <span class='o'>=</span> <span class='nf'><a href='https://rdrr.io/r/base/c.html'>c</a></span><span class='o'>(</span><span class='m'>1</span>, <span class='m'>2</span>, <span class='m'>3</span>, <span class='m'>4</span>, <span class='m'>5</span>, <span class='m'>2</span>, <span class='m'>3</span>, <span class='m'>1</span>, <span class='m'>4</span><span class='o'>)</span></span>
<span><span class='o'>)</span></span></code></pre>
</div>
<p>We could certainly try <a href="https://dplyr.tidyverse.org/reference/case-and-replace-when.html" target="_blank" rel="noopener"><code>case_when()</code></a>
:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>likert</span> <span class='o'>|&gt;</span></span>
<span>  <span class='nf'><a href='https://dplyr.tidyverse.org/reference/mutate.html'>mutate</a></span><span class='o'>(</span></span>
<span>    category <span class='o'>=</span> <span class='nf'><a href='https://dplyr.tidyverse.org/reference/case-and-replace-when.html'>case_when</a></span><span class='o'>(</span></span>
<span>      <span class='nv'>score</span> <span class='o'>==</span> <span class='m'>1</span> <span class='o'>~</span> <span class='s'>"Strongly disagree"</span>,</span>
<span>      <span class='nv'>score</span> <span class='o'>==</span> <span class='m'>2</span> <span class='o'>~</span> <span class='s'>"Disagree"</span>,</span>
<span>      <span class='nv'>score</span> <span class='o'>==</span> <span class='m'>3</span> <span class='o'>~</span> <span class='s'>"Neutral"</span>,</span>
<span>      <span class='nv'>score</span> <span class='o'>==</span> <span class='m'>4</span> <span class='o'>~</span> <span class='s'>"Agree"</span>,</span>
<span>      <span class='nv'>score</span> <span class='o'>==</span> <span class='m'>5</span> <span class='o'>~</span> <span class='s'>"Strongly agree"</span></span>
<span>    <span class='o'>)</span></span>
<span>  <span class='o'>)</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># A tibble: 9 × 2</span></span></span>
<span><span class='c'>#&gt;   score category         </span></span>
<span><span class='c'>#&gt;   <span style='color: #555555; font-style: italic;'>&lt;dbl&gt;</span> <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>            </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>1</span>     1 Strongly disagree</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>2</span>     2 Disagree         </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>3</span>     3 Neutral          </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>4</span>     4 Agree            </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>5</span>     5 Strongly agree   </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>6</span>     2 Disagree         </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>7</span>     3 Neutral          </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>8</span>     1 Strongly disagree</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>9</span>     4 Agree</span></span>
<span></span></code></pre>
</div>
<p>But <code>score ==</code> is repeated so many times! When you find yourself using <code>==</code> in this way, recognize that what you&rsquo;re really doing is matching on the <em>values</em> of a single column. In cases like these, you&rsquo;ll want to switch to <a href="https://dplyr.tidyverse.org/reference/recode-and-replace-values.html" target="_blank" rel="noopener"><code>recode_values()</code></a>
. Rather than taking logical vectors, <a href="https://dplyr.tidyverse.org/reference/recode-and-replace-values.html" target="_blank" rel="noopener"><code>recode_values()</code></a>
 takes <em>values</em> on the left-hand side to match against a single input that you&rsquo;ll provide as the first argument.</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>likert</span> <span class='o'>|&gt;</span></span>
<span>  <span class='nf'><a href='https://dplyr.tidyverse.org/reference/mutate.html'>mutate</a></span><span class='o'>(</span></span>
<span>    category <span class='o'>=</span> <span class='nv'>score</span> <span class='o'>|&gt;</span></span>
<span>      <span class='nf'><a href='https://dplyr.tidyverse.org/reference/recode-and-replace-values.html'>recode_values</a></span><span class='o'>(</span></span>
<span>        <span class='m'>1</span> <span class='o'>~</span> <span class='s'>"Strongly disagree"</span>,</span>
<span>        <span class='m'>2</span> <span class='o'>~</span> <span class='s'>"Disagree"</span>,</span>
<span>        <span class='m'>3</span> <span class='o'>~</span> <span class='s'>"Neutral"</span>,</span>
<span>        <span class='m'>4</span> <span class='o'>~</span> <span class='s'>"Agree"</span>,</span>
<span>        <span class='m'>5</span> <span class='o'>~</span> <span class='s'>"Strongly agree"</span></span>
<span>      <span class='o'>)</span></span>
<span>  <span class='o'>)</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># A tibble: 9 × 2</span></span></span>
<span><span class='c'>#&gt;   score category         </span></span>
<span><span class='c'>#&gt;   <span style='color: #555555; font-style: italic;'>&lt;dbl&gt;</span> <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>            </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>1</span>     1 Strongly disagree</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>2</span>     2 Disagree         </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>3</span>     3 Neutral          </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>4</span>     4 Agree            </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>5</span>     5 Strongly agree   </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>6</span>     2 Disagree         </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>7</span>     3 Neutral          </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>8</span>     1 Strongly disagree</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>9</span>     4 Agree</span></span>
<span></span></code></pre>
</div>
<p>This removes all of the repetition, allowing you to focus on the mapping. And it should feel pretty familiar! This is the same formula interface of <a href="https://dplyr.tidyverse.org/reference/case-and-replace-when.html" target="_blank" rel="noopener"><code>case_when()</code></a>
.</p>
<p>If you squint, the mapping should look roughly like a lookup table between the numeric value and the Likert encoding. One of the novel features of <a href="https://dplyr.tidyverse.org/reference/recode-and-replace-values.html" target="_blank" rel="noopener"><code>recode_values()</code></a>
 is that it has an alternate interface that allows you to make this lookup table more explicit. Using a <a href="https://tibble.tidyverse.org/reference/tribble.html" target="_blank" rel="noopener"><code>tribble()</code></a>
, we can extract out the lookup table into its own standalone data frame.</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>lookup</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://tibble.tidyverse.org/reference/tribble.html'>tribble</a></span><span class='o'>(</span></span>
<span>  <span class='o'>~</span><span class='nv'>from</span> , <span class='o'>~</span><span class='nv'>to</span>                 ,</span>
<span>      <span class='m'>1</span> , <span class='s'>"Strongly disagree"</span> ,</span>
<span>      <span class='m'>2</span> , <span class='s'>"Disagree"</span>          ,</span>
<span>      <span class='m'>3</span> , <span class='s'>"Neutral"</span>           ,</span>
<span>      <span class='m'>4</span> , <span class='s'>"Agree"</span>             ,</span>
<span>      <span class='m'>5</span> , <span class='s'>"Strongly agree"</span>    ,</span>
<span><span class='o'>)</span></span></code></pre>
</div>
<p>We can then utilize the alternative <code>from</code> and <code>to</code> arguments of <a href="https://dplyr.tidyverse.org/reference/recode-and-replace-values.html" target="_blank" rel="noopener"><code>recode_values()</code></a>
 rather than supplying formulas to specify how the values should be recoded:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>likert</span> <span class='o'>|&gt;</span></span>
<span>  <span class='nf'><a href='https://dplyr.tidyverse.org/reference/mutate.html'>mutate</a></span><span class='o'>(</span>category <span class='o'>=</span> <span class='nf'><a href='https://dplyr.tidyverse.org/reference/recode-and-replace-values.html'>recode_values</a></span><span class='o'>(</span><span class='nv'>score</span>, from <span class='o'>=</span> <span class='nv'>lookup</span><span class='o'>$</span><span class='nv'>from</span>, to <span class='o'>=</span> <span class='nv'>lookup</span><span class='o'>$</span><span class='nv'>to</span><span class='o'>)</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># A tibble: 9 × 2</span></span></span>
<span><span class='c'>#&gt;   score category         </span></span>
<span><span class='c'>#&gt;   <span style='color: #555555; font-style: italic;'>&lt;dbl&gt;</span> <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>            </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>1</span>     1 Strongly disagree</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>2</span>     2 Disagree         </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>3</span>     3 Neutral          </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>4</span>     4 Agree            </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>5</span>     5 Strongly agree   </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>6</span>     2 Disagree         </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>7</span>     3 Neutral          </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>8</span>     1 Strongly disagree</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>9</span>     4 Agree</span></span>
<span></span></code></pre>
</div>
<p>Lifting the lookup table out to the top of the file is particularly nice when you have a long pipe chain. The details of the mapping get some room to breathe, and in the pipe chain you can focus on the actual data manipulations.</p>
<p>It&rsquo;s also very common for your <code>lookup</code> table to exist in a CSV file that you have to read in separately. In that case, you can replace the <a href="https://tibble.tidyverse.org/reference/tribble.html" target="_blank" rel="noopener"><code>tribble()</code></a>
 call with:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>lookup</span> <span class='o'>&lt;-</span> <span class='nf'>readr</span><span class='nf'>::</span><span class='nf'><a href='https://readr.tidyverse.org/reference/read_delim.html'>read_csv</a></span><span class='o'>(</span><span class='s'>"lookup.csv"</span><span class='o'>)</span></span></code></pre>
</div>
<p>Then everything else works the same.</p>
<h3 id="unmatched-cases">Unmatched cases
</h3>
<p>If you are confident that you&rsquo;ve captured every case during the recoding process, you can now supply <code>unmatched = &quot;error&quot;</code> as an alternative to <code>default</code>. <a href="https://dplyr.tidyverse.org/reference/recode-and-replace-values.html" target="_blank" rel="noopener"><code>recode_values()</code></a>
 will error if that assertion doesn&rsquo;t hold. This is great for defensive programming!</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='c'># Notice the `0` that we don't have a mapping for!</span></span>
<span><span class='nv'>likert</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://tibble.tidyverse.org/reference/tibble.html'>tibble</a></span><span class='o'>(</span></span>
<span>  score <span class='o'>=</span> <span class='nf'><a href='https://rdrr.io/r/base/c.html'>c</a></span><span class='o'>(</span><span class='m'>0</span>, <span class='m'>1</span>, <span class='m'>2</span>, <span class='m'>2</span>, <span class='m'>4</span>, <span class='m'>5</span>, <span class='m'>2</span>, <span class='m'>3</span>, <span class='m'>1</span>, <span class='m'>4</span><span class='o'>)</span></span>
<span><span class='o'>)</span></span>
<span></span>
<span><span class='nv'>likert</span> <span class='o'>|&gt;</span></span>
<span>  <span class='nf'><a href='https://dplyr.tidyverse.org/reference/mutate.html'>mutate</a></span><span class='o'>(</span></span>
<span>    score <span class='o'>=</span> <span class='nv'>score</span> <span class='o'>|&gt;</span></span>
<span>      <span class='nf'><a href='https://dplyr.tidyverse.org/reference/recode-and-replace-values.html'>recode_values</a></span><span class='o'>(</span></span>
<span>        from <span class='o'>=</span> <span class='nv'>lookup</span><span class='o'>$</span><span class='nv'>from</span>,</span>
<span>        to <span class='o'>=</span> <span class='nv'>lookup</span><span class='o'>$</span><span class='nv'>to</span>,</span>
<span>        unmatched <span class='o'>=</span> <span class='s'>"error"</span></span>
<span>      <span class='o'>)</span></span>
<span>  <span class='o'>)</span></span>
<span><span class='c'>#&gt; <span style='color: #BBBB00; font-weight: bold;'>Error</span><span style='font-weight: bold;'> in `mutate()`:</span></span></span>
<span><span class='c'>#&gt; <span style='color: #00BBBB;'>ℹ</span> In argument: `score = recode_values(score, from = lookup$from, to = lookup$to, unmatched = "error")`.</span></span>
<span><span class='c'>#&gt; <span style='font-weight: bold;'>Caused by error in `recode_values()`:</span></span></span>
<span><span class='c'>#&gt; <span style='color: #BBBB00;'>!</span> Each location must be matched.</span></span>
<span><span class='c'>#&gt; <span style='color: #BB0000;'>✖</span> Location 1 is unmatched.</span></span>
<span></span></code></pre>
</div>
<p>Note that missing values must be explicitly handled when setting <code>unmatched = &quot;error&quot;</code>, even if that&rsquo;s just setting <code>NA ~ NA</code>, otherwise they will trigger the unmatched error. This forces you to explicitly opt in to expecting missing values.</p>
<p>Similar to <a href="https://dplyr.tidyverse.org/reference/recode-and-replace-values.html" target="_blank" rel="noopener"><code>recode_values()</code></a>
, <a href="https://dplyr.tidyverse.org/reference/case-and-replace-when.html" target="_blank" rel="noopener"><code>case_when()</code></a>
 has also gained the <code>.unmatched</code> argument.</p>
<h3 id="replace_values"><code>replace_values()</code>
</h3>
<p>Out of all of the new things introduced in dplyr 1.2.0, I think I&rsquo;m most excited about <a href="https://dplyr.tidyverse.org/reference/recode-and-replace-values.html" target="_blank" rel="noopener"><code>replace_values()</code></a>
.</p>
<p>While <a href="https://dplyr.tidyverse.org/reference/recode-and-replace-values.html" target="_blank" rel="noopener"><code>recode_values()</code></a>
 is great for creating an entirely new column (possibly with a new type), if you just need to replace a few rows of an existing column, then <a href="https://dplyr.tidyverse.org/reference/recode-and-replace-values.html" target="_blank" rel="noopener"><code>replace_values()</code></a>
 is the best tool for the job!</p>
<p>Imagine we&rsquo;d like to collapse some, but not all, of these school names into common buckets:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>schools</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://tibble.tidyverse.org/reference/tibble.html'>tibble</a></span><span class='o'>(</span></span>
<span>  name <span class='o'>=</span> <span class='nf'><a href='https://rdrr.io/r/base/c.html'>c</a></span><span class='o'>(</span></span>
<span>    <span class='s'>"UNC"</span>,</span>
<span>    <span class='s'>"Chapel Hill"</span>,</span>
<span>    <span class='kc'>NA</span>,</span>
<span>    <span class='s'>"Duke"</span>,</span>
<span>    <span class='s'>"Duke University"</span>,</span>
<span>    <span class='s'>"UNC"</span>,</span>
<span>    <span class='s'>"NC State"</span>,</span>
<span>    <span class='s'>"ECU"</span></span>
<span>  <span class='o'>)</span></span>
<span><span class='o'>)</span></span></code></pre>
</div>
<p>We could use <a href="https://dplyr.tidyverse.org/reference/case-and-replace-when.html" target="_blank" rel="noopener"><code>case_when()</code></a>
 or <a href="https://dplyr.tidyverse.org/reference/recode-and-replace-values.html" target="_blank" rel="noopener"><code>recode_values()</code></a>
:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>schools</span> <span class='o'>|&gt;</span></span>
<span>  <span class='nf'><a href='https://dplyr.tidyverse.org/reference/mutate.html'>mutate</a></span><span class='o'>(</span></span>
<span>    name <span class='o'>=</span> <span class='nf'><a href='https://dplyr.tidyverse.org/reference/case-and-replace-when.html'>case_when</a></span><span class='o'>(</span></span>
<span>      <span class='nv'>name</span> <span class='o'><a href='https://rdrr.io/r/base/match.html'>%in%</a></span> <span class='nf'><a href='https://rdrr.io/r/base/c.html'>c</a></span><span class='o'>(</span><span class='s'>"UNC"</span>, <span class='s'>"Chapel Hill"</span><span class='o'>)</span> <span class='o'>~</span> <span class='s'>"UNC Chapel Hill"</span>,</span>
<span>      <span class='nv'>name</span> <span class='o'><a href='https://rdrr.io/r/base/match.html'>%in%</a></span> <span class='nf'><a href='https://rdrr.io/r/base/c.html'>c</a></span><span class='o'>(</span><span class='s'>"Duke"</span>, <span class='s'>"Duke University"</span><span class='o'>)</span> <span class='o'>~</span> <span class='s'>"Duke"</span>,</span>
<span>      .default <span class='o'>=</span> <span class='nv'>name</span></span>
<span>    <span class='o'>)</span></span>
<span>  <span class='o'>)</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># A tibble: 8 × 1</span></span></span>
<span><span class='c'>#&gt;   name           </span></span>
<span><span class='c'>#&gt;   <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>          </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>1</span> UNC Chapel Hill</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>2</span> UNC Chapel Hill</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>3</span> <span style='color: #BB0000;'>NA</span>             </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>4</span> Duke           </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>5</span> Duke           </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>6</span> UNC Chapel Hill</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>7</span> NC State       </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>8</span> ECU</span></span>
<span></span><span></span>
<span><span class='nv'>schools</span> <span class='o'>|&gt;</span></span>
<span>  <span class='nf'><a href='https://dplyr.tidyverse.org/reference/mutate.html'>mutate</a></span><span class='o'>(</span></span>
<span>    name <span class='o'>=</span> <span class='nf'><a href='https://dplyr.tidyverse.org/reference/recode-and-replace-values.html'>recode_values</a></span><span class='o'>(</span></span>
<span>      <span class='nv'>name</span>,</span>
<span>      <span class='nf'><a href='https://rdrr.io/r/base/c.html'>c</a></span><span class='o'>(</span><span class='s'>"UNC"</span>, <span class='s'>"Chapel Hill"</span><span class='o'>)</span> <span class='o'>~</span> <span class='s'>"UNC Chapel Hill"</span>,</span>
<span>      <span class='nf'><a href='https://rdrr.io/r/base/c.html'>c</a></span><span class='o'>(</span><span class='s'>"Duke"</span>, <span class='s'>"Duke University"</span><span class='o'>)</span> <span class='o'>~</span> <span class='s'>"Duke"</span>,</span>
<span>      default <span class='o'>=</span> <span class='nv'>name</span></span>
<span>    <span class='o'>)</span></span>
<span>  <span class='o'>)</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># A tibble: 8 × 1</span></span></span>
<span><span class='c'>#&gt;   name           </span></span>
<span><span class='c'>#&gt;   <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>          </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>1</span> UNC Chapel Hill</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>2</span> UNC Chapel Hill</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>3</span> <span style='color: #BB0000;'>NA</span>             </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>4</span> Duke           </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>5</span> Duke           </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>6</span> UNC Chapel Hill</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>7</span> NC State       </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>8</span> ECU</span></span>
<span></span></code></pre>
</div>
<p>But this &ldquo;partial update&rdquo; operation is so common that it really deserves its own name that doesn&rsquo;t require you to specify <code>default</code> and is type stable on the input. For that, we have <a href="https://dplyr.tidyverse.org/reference/recode-and-replace-values.html" target="_blank" rel="noopener"><code>replace_values()</code></a>
:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>schools</span> <span class='o'>|&gt;</span></span>
<span>  <span class='nf'><a href='https://dplyr.tidyverse.org/reference/mutate.html'>mutate</a></span><span class='o'>(</span></span>
<span>    name <span class='o'>=</span> <span class='nv'>name</span> <span class='o'>|&gt;</span></span>
<span>      <span class='nf'><a href='https://dplyr.tidyverse.org/reference/recode-and-replace-values.html'>replace_values</a></span><span class='o'>(</span></span>
<span>        <span class='nf'><a href='https://rdrr.io/r/base/c.html'>c</a></span><span class='o'>(</span><span class='s'>"UNC"</span>, <span class='s'>"Chapel Hill"</span><span class='o'>)</span> <span class='o'>~</span> <span class='s'>"UNC Chapel Hill"</span>,</span>
<span>        <span class='nf'><a href='https://rdrr.io/r/base/c.html'>c</a></span><span class='o'>(</span><span class='s'>"Duke"</span>, <span class='s'>"Duke University"</span><span class='o'>)</span> <span class='o'>~</span> <span class='s'>"Duke"</span></span>
<span>      <span class='o'>)</span></span>
<span>  <span class='o'>)</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># A tibble: 8 × 1</span></span></span>
<span><span class='c'>#&gt;   name           </span></span>
<span><span class='c'>#&gt;   <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>          </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>1</span> UNC Chapel Hill</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>2</span> UNC Chapel Hill</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>3</span> <span style='color: #BB0000;'>NA</span>             </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>4</span> Duke           </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>5</span> Duke           </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>6</span> UNC Chapel Hill</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>7</span> NC State       </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>8</span> ECU</span></span>
<span></span></code></pre>
</div>
<p>Notice how pipe friendly <a href="https://dplyr.tidyverse.org/reference/recode-and-replace-values.html" target="_blank" rel="noopener"><code>replace_values()</code></a>
 is! The first input is your &ldquo;primary&rdquo; input, and you can expect the output to have the same type and size as that input.</p>
<p>Like <a href="https://dplyr.tidyverse.org/reference/recode-and-replace-values.html" target="_blank" rel="noopener"><code>recode_values()</code></a>
, <a href="https://dplyr.tidyverse.org/reference/recode-and-replace-values.html" target="_blank" rel="noopener"><code>replace_values()</code></a>
 has an alternative <code>from</code> and <code>to</code> API that works well with lookup tables and allows you to move your mapping out of the pipe chain:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>lookup</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://tibble.tidyverse.org/reference/tribble.html'>tribble</a></span><span class='o'>(</span></span>
<span>  <span class='o'>~</span><span class='nv'>from</span>             , <span class='o'>~</span><span class='nv'>to</span>               ,</span>
<span>  <span class='s'>"UNC"</span>             , <span class='s'>"UNC Chapel Hill"</span> ,</span>
<span>  <span class='s'>"Chapel Hill"</span>     , <span class='s'>"UNC Chapel Hill"</span> ,</span>
<span>  <span class='s'>"Duke"</span>            , <span class='s'>"Duke"</span>            ,</span>
<span>  <span class='s'>"Duke University"</span> , <span class='s'>"Duke"</span>            ,</span>
<span><span class='o'>)</span></span>
<span></span>
<span><span class='nv'>schools</span> <span class='o'>|&gt;</span></span>
<span>  <span class='nf'><a href='https://dplyr.tidyverse.org/reference/mutate.html'>mutate</a></span><span class='o'>(</span>name <span class='o'>=</span> <span class='nf'><a href='https://dplyr.tidyverse.org/reference/recode-and-replace-values.html'>replace_values</a></span><span class='o'>(</span><span class='nv'>name</span>, from <span class='o'>=</span> <span class='nv'>lookup</span><span class='o'>$</span><span class='nv'>from</span>, to <span class='o'>=</span> <span class='nv'>lookup</span><span class='o'>$</span><span class='nv'>to</span><span class='o'>)</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># A tibble: 8 × 1</span></span></span>
<span><span class='c'>#&gt;   name           </span></span>
<span><span class='c'>#&gt;   <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>          </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>1</span> UNC Chapel Hill</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>2</span> UNC Chapel Hill</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>3</span> <span style='color: #BB0000;'>NA</span>             </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>4</span> Duke           </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>5</span> Duke           </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>6</span> UNC Chapel Hill</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>7</span> NC State       </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>8</span> ECU</span></span>
<span></span></code></pre>
</div>
<p>An extremely neat feature of the <code>from</code> and <code>to</code> API is that they also take <em>lists</em> of vectors that describe the mapping, which has been designed to work elegantly with the fact that <a href="https://tibble.tidyverse.org/reference/tribble.html" target="_blank" rel="noopener"><code>tribble()</code></a>
 can create list columns, allowing you to further collapse this lookup table:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='c'># Condensed lookup table with a `many:1` mapping per row</span></span>
<span><span class='nv'>lookup</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://tibble.tidyverse.org/reference/tribble.html'>tribble</a></span><span class='o'>(</span></span>
<span>  <span class='o'>~</span><span class='nv'>from</span>                        , <span class='o'>~</span><span class='nv'>to</span>               ,</span>
<span>  <span class='nf'><a href='https://rdrr.io/r/base/c.html'>c</a></span><span class='o'>(</span><span class='s'>"UNC"</span>, <span class='s'>"Chapel Hill"</span><span class='o'>)</span>      , <span class='s'>"UNC Chapel Hill"</span> ,</span>
<span>  <span class='nf'><a href='https://rdrr.io/r/base/c.html'>c</a></span><span class='o'>(</span><span class='s'>"Duke"</span>, <span class='s'>"Duke University"</span><span class='o'>)</span> , <span class='s'>"Duke"</span>            ,</span>
<span><span class='o'>)</span></span>
<span></span>
<span><span class='c'># Note that `from` is a list column</span></span>
<span><span class='nv'>lookup</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># A tibble: 2 × 2</span></span></span>
<span><span class='c'>#&gt;   from      to             </span></span>
<span><span class='c'>#&gt;   <span style='color: #555555; font-style: italic;'>&lt;list&gt;</span>    <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>          </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>1</span> <span style='color: #555555;'>&lt;chr [2]&gt;</span> UNC Chapel Hill</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>2</span> <span style='color: #555555;'>&lt;chr [2]&gt;</span> Duke</span></span>
<span></span><span></span>
<span><span class='nv'>lookup</span><span class='o'>$</span><span class='nv'>from</span></span>
<span><span class='c'>#&gt; [[1]]</span></span>
<span><span class='c'>#&gt; [1] "UNC"         "Chapel Hill"</span></span>
<span><span class='c'>#&gt; </span></span>
<span><span class='c'>#&gt; [[2]]</span></span>
<span><span class='c'>#&gt; [1] "Duke"            "Duke University"</span></span>
<span></span><span></span>
<span><span class='c'># Works the same as before</span></span>
<span><span class='nv'>schools</span> <span class='o'>|&gt;</span></span>
<span>  <span class='nf'><a href='https://dplyr.tidyverse.org/reference/mutate.html'>mutate</a></span><span class='o'>(</span>name <span class='o'>=</span> <span class='nf'><a href='https://dplyr.tidyverse.org/reference/recode-and-replace-values.html'>replace_values</a></span><span class='o'>(</span><span class='nv'>name</span>, from <span class='o'>=</span> <span class='nv'>lookup</span><span class='o'>$</span><span class='nv'>from</span>, to <span class='o'>=</span> <span class='nv'>lookup</span><span class='o'>$</span><span class='nv'>to</span><span class='o'>)</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># A tibble: 8 × 1</span></span></span>
<span><span class='c'>#&gt;   name           </span></span>
<span><span class='c'>#&gt;   <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>          </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>1</span> UNC Chapel Hill</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>2</span> UNC Chapel Hill</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>3</span> <span style='color: #BB0000;'>NA</span>             </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>4</span> Duke           </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>5</span> Duke           </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>6</span> UNC Chapel Hill</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>7</span> NC State       </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>8</span> ECU</span></span>
<span></span></code></pre>
</div>
<p>The formula interface of <a href="https://dplyr.tidyverse.org/reference/recode-and-replace-values.html" target="_blank" rel="noopener"><code>replace_values()</code></a>
 is a bit of a Swiss Army knife for all manner of scenarios where you might have previously reached for <a href="https://dplyr.tidyverse.org/reference/coalesce.html" target="_blank" rel="noopener"><code>dplyr::coalesce()</code></a>
, <a href="https://dplyr.tidyverse.org/reference/na_if.html" target="_blank" rel="noopener"><code>dplyr::na_if()</code></a>
, or <a href="https://tidyr.tidyverse.org/reference/replace_na.html" target="_blank" rel="noopener"><code>tidyr::replace_na()</code></a>
:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>state</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://rdrr.io/r/base/c.html'>c</a></span><span class='o'>(</span><span class='s'>"NC"</span>, <span class='s'>"NY"</span>, <span class='s'>"CA"</span>, <span class='kc'>NA</span>, <span class='s'>"NY"</span>, <span class='s'>"Unknown"</span>, <span class='kc'>NA</span><span class='o'>)</span></span>
<span></span>
<span><span class='c'># Replace missing values with a constant</span></span>
<span><span class='nf'><a href='https://dplyr.tidyverse.org/reference/recode-and-replace-values.html'>replace_values</a></span><span class='o'>(</span><span class='nv'>state</span>, <span class='kc'>NA</span> <span class='o'>~</span> <span class='s'>"Unknown"</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; [1] "NC"      "NY"      "CA"      "Unknown" "NY"      "Unknown" "Unknown"</span></span>
<span></span><span></span>
<span><span class='c'># Replace missing values with the corresponding value from another column</span></span>
<span><span class='nv'>region</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://rdrr.io/r/base/c.html'>c</a></span><span class='o'>(</span><span class='s'>"South"</span>, <span class='s'>"North"</span>, <span class='s'>"West"</span>, <span class='s'>"East"</span>, <span class='s'>"North"</span>, <span class='s'>"Unknown"</span>, <span class='s'>"West"</span><span class='o'>)</span></span>
<span><span class='nf'><a href='https://dplyr.tidyverse.org/reference/recode-and-replace-values.html'>replace_values</a></span><span class='o'>(</span><span class='nv'>state</span>, <span class='kc'>NA</span> <span class='o'>~</span> <span class='nv'>region</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; [1] "NC"      "NY"      "CA"      "East"    "NY"      "Unknown" "West"</span></span>
<span></span><span></span>
<span><span class='c'># Replace problematic values with a missing value</span></span>
<span><span class='nf'><a href='https://dplyr.tidyverse.org/reference/recode-and-replace-values.html'>replace_values</a></span><span class='o'>(</span><span class='nv'>state</span>, <span class='s'>"Unknown"</span> <span class='o'>~</span> <span class='kc'>NA</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; [1] "NC" "NY" "CA" NA   "NY" NA   NA</span></span>
<span></span><span></span>
<span><span class='c'># Standardize multiple issues at once</span></span>
<span><span class='nf'><a href='https://dplyr.tidyverse.org/reference/recode-and-replace-values.html'>replace_values</a></span><span class='o'>(</span><span class='nv'>state</span>, <span class='nf'><a href='https://rdrr.io/r/base/c.html'>c</a></span><span class='o'>(</span><span class='kc'>NA</span>, <span class='s'>"Unknown"</span><span class='o'>)</span> <span class='o'>~</span> <span class='s'>"&lt;missing&gt;"</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; [1] "NC"        "NY"        "CA"        "&lt;missing&gt;" "NY"        "&lt;missing&gt;"</span></span>
<span><span class='c'>#&gt; [7] "&lt;missing&gt;"</span></span>
<span></span></code></pre>
</div>
<p>We also think it better expresses intent than <a href="https://dplyr.tidyverse.org/reference/if_else.html" target="_blank" rel="noopener"><code>if_else()</code></a>
 or <a href="https://dplyr.tidyverse.org/reference/case-and-replace-when.html" target="_blank" rel="noopener"><code>case_when()</code></a>
 when performing a partial update:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='c'># - Type stable on `x`</span></span>
<span><span class='c'># - Intent of "partially updating" `state` is clear</span></span>
<span><span class='c'># - Pipe friendly</span></span>
<span><span class='nv'>state</span> <span class='o'>|&gt;</span> <span class='nf'><a href='https://dplyr.tidyverse.org/reference/recode-and-replace-values.html'>replace_values</a></span><span class='o'>(</span><span class='kc'>NA</span> <span class='o'>~</span> <span class='s'>"Unknown"</span><span class='o'>)</span></span>
<span></span>
<span><span class='c'># Historically this has been "the way" to do a partial update,</span></span>
<span><span class='c'># but it's odd that the "primary" input is at the end!</span></span>
<span><span class='nf'><a href='https://dplyr.tidyverse.org/reference/if_else.html'>if_else</a></span><span class='o'>(</span><span class='nf'><a href='https://rdrr.io/r/base/NA.html'>is.na</a></span><span class='o'>(</span><span class='nv'>state</span><span class='o'>)</span>, <span class='s'>"Unknown"</span>, <span class='nv'>state</span><span class='o'>)</span></span>
<span><span class='nf'><a href='https://dplyr.tidyverse.org/reference/case-and-replace-when.html'>case_when</a></span><span class='o'>(</span><span class='nf'><a href='https://rdrr.io/r/base/NA.html'>is.na</a></span><span class='o'>(</span><span class='nv'>state</span><span class='o'>)</span> <span class='o'>~</span> <span class='s'>"Unknown"</span>, .default <span class='o'>=</span> <span class='nv'>state</span><span class='o'>)</span></span></code></pre>
</div>
<p>If you&rsquo;re a package author, you&rsquo;ll probably also be interested in <a href="https://vctrs.r-lib.org/reference/vec-recode-and-replace.html" target="_blank" rel="noopener"><code>vctrs::vec_recode_values()</code></a>
 and <a href="https://vctrs.r-lib.org/reference/vec-recode-and-replace.html" target="_blank" rel="noopener"><code>vctrs::vec_replace_values()</code></a>
, which are low dependency functions that power the dplyr variants.</p>
<h3 id="what-about-case_match">What about <code>case_match()</code>?
</h3>
<p>We&rsquo;ve soft-deprecated <a href="https://dplyr.tidyverse.org/reference/case_match.html" target="_blank" rel="noopener"><code>case_match()</code></a>
 in favor of <a href="https://dplyr.tidyverse.org/reference/recode-and-replace-values.html" target="_blank" rel="noopener"><code>recode_values()</code></a>
, which is a drop in replacement.</p>
<p><a href="https://dplyr.tidyverse.org/reference/case_match.html" target="_blank" rel="noopener"><code>case_match()</code></a>
 was an incremental step towards this recoding family, but:</p>
<ul>
<li>It has a pretty confusing name compared with <a href="https://dplyr.tidyverse.org/reference/recode-and-replace-values.html" target="_blank" rel="noopener"><code>recode_values()</code></a>
.</li>
<li>It lacked a way to work with lookup tables, like <code>from</code> and <code>to</code>.</li>
<li>It lacks a replacement variant, like <a href="https://dplyr.tidyverse.org/reference/recode-and-replace-values.html" target="_blank" rel="noopener"><code>replace_values()</code></a>
.</li>
</ul>
<p>Rather than keeping <a href="https://dplyr.tidyverse.org/reference/case_match.html" target="_blank" rel="noopener"><code>case_match()</code></a>
 around indefinitely, we&rsquo;ve decided to initiate the process of its removal since it was only introduced in dplyr 1.1.0.</p>
<h2 id="deprecations">Deprecations
</h2>
<p>dplyr 1.2.0 advances the lifecycle stage of many deprecated functions. These deprecations have been in the works for many years now, due to our slow and very deliberate deprecation process via the <a href="https://lifecycle.r-lib.org/" target="_blank" rel="noopener">lifecycle package</a>
. We&rsquo;ll cover the highlights, and you can find the full list <a href="https://github.com/tidyverse/dplyr/releases/tag/v1.2.0" target="_blank" rel="noopener">here</a>
.</p>
<p>For any packages that we broke via these deprecations, we provided a pull request (or at least an issue, for complex cases) and some advance warning. We semi-automated some of this process using Claude Code, which you can read about <a href="https://blog.davisvaughan.com/posts/2026-01-09-claude-200-pull-requests/" target="_blank" rel="noopener">here</a>
.</p>
<ul>
<li>
<p>All underscored verbs have moved from deprecated to defunct, such as <a href="https://dplyr.tidyverse.org/reference/defunct-lazyeval.html" target="_blank" rel="noopener"><code>mutate_()</code></a>
 and <a href="https://dplyr.tidyverse.org/reference/defunct-lazyeval.html" target="_blank" rel="noopener"><code>arrange_()</code></a>
. These have been deprecated since dplyr 0.7.0 back in 2017 (yes, 2017!!). Use the non-underscored versions, see <a href="https://dplyr.tidyverse.org/articles/programming.html" target="_blank" rel="noopener"><code>vignette(&quot;programming&quot;)</code></a>
 for details.</p>
</li>
<li>
<p><a href="https://dplyr.tidyverse.org/reference/defunct-each.html" target="_blank" rel="noopener"><code>mutate_each()</code></a>
 and <a href="https://dplyr.tidyverse.org/reference/defunct-each.html" target="_blank" rel="noopener"><code>summarise_each()</code></a>
 have moved from deprecated to defunct. These were also deprecated in dplyr 0.7.0. Use <a href="https://dplyr.tidyverse.org/reference/mutate.html" target="_blank" rel="noopener"><code>mutate()</code></a>
 and <a href="https://dplyr.tidyverse.org/reference/summarise.html" target="_blank" rel="noopener"><code>summarise()</code></a>
 with <a href="https://dplyr.tidyverse.org/reference/across.html" target="_blank" rel="noopener"><code>across()</code></a>
 instead.</p>
</li>
<li>
<p>Returning more or less than 1 row per group in <a href="https://dplyr.tidyverse.org/reference/summarise.html" target="_blank" rel="noopener"><code>summarise()</code></a>
 has moved from deprecated to defunct. This was deprecated in dplyr 1.1.0 in 2023 after we realized that this was an unsafe feature for <a href="https://dplyr.tidyverse.org/reference/summarise.html" target="_blank" rel="noopener"><code>summarise()</code></a>
, which you should always expect to return exactly 1 row per group. <a href="https://dplyr.tidyverse.org/reference/reframe.html" target="_blank" rel="noopener"><code>reframe()</code></a>
 is a drop in replacement when you need this.</p>
</li>
<li>
<p>In <a href="https://dplyr.tidyverse.org/reference/case-and-replace-when.html" target="_blank" rel="noopener"><code>case_when()</code></a>
, supplying all size 1 LHS inputs along with a size &gt;1 RHS input is now soft-deprecated. This is an improper usage of <a href="https://dplyr.tidyverse.org/reference/case-and-replace-when.html" target="_blank" rel="noopener"><code>case_when()</code></a>
 that should instead be a series of if statements, like:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="c1"># Scalars!</span>
</span></span><span class="line"><span class="cl"><span class="n">code</span> <span class="o">&lt;-</span> <span class="m">1L</span>
</span></span><span class="line"><span class="cl"><span class="n">flavor</span> <span class="o">&lt;-</span> <span class="s">&#34;vanilla&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Improper usage:</span>
</span></span><span class="line"><span class="cl"><span class="nf">case_when</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">  <span class="n">code</span> <span class="o">==</span> <span class="m">1L</span> <span class="o">&amp;&amp;</span> <span class="n">flavor</span> <span class="o">==</span> <span class="s">&#34;chocolate&#34;</span> <span class="o">~</span> <span class="n">x</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="n">code</span> <span class="o">==</span> <span class="m">1L</span> <span class="o">&amp;&amp;</span> <span class="n">flavor</span> <span class="o">==</span> <span class="s">&#34;vanilla&#34;</span> <span class="o">~</span> <span class="n">y</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="n">code</span> <span class="o">==</span> <span class="m">2L</span> <span class="o">&amp;&amp;</span> <span class="n">flavor</span> <span class="o">==</span> <span class="s">&#34;vanilla&#34;</span> <span class="o">~</span> <span class="n">z</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="n">.default</span> <span class="o">=</span> <span class="n">default</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Recommended:</span>
</span></span><span class="line"><span class="cl"><span class="kr">if</span> <span class="p">(</span><span class="n">code</span> <span class="o">==</span> <span class="m">1L</span> <span class="o">&amp;&amp;</span> <span class="n">flavor</span> <span class="o">==</span> <span class="s">&#34;chocolate&#34;</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="n">x</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span> <span class="kr">else</span> <span class="kr">if</span> <span class="p">(</span><span class="n">code</span> <span class="o">==</span> <span class="m">1L</span> <span class="o">&amp;&amp;</span> <span class="n">flavor</span> <span class="o">==</span> <span class="s">&#34;vanilla&#34;</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="n">y</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span> <span class="kr">else</span> <span class="kr">if</span> <span class="p">(</span><span class="n">code</span> <span class="o">==</span> <span class="m">2L</span> <span class="o">&amp;&amp;</span> <span class="n">flavor</span> <span class="o">==</span> <span class="s">&#34;vanilla&#34;</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="n">z</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span> <span class="kr">else</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="n">default</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>The recycling behavior that allows this style of <a href="https://dplyr.tidyverse.org/reference/case-and-replace-when.html" target="_blank" rel="noopener"><code>case_when()</code></a>
 to work is unsafe, and can result in silent bugs that we&rsquo;d like to guard against with an error in the future. See <a href="https://github.com/tidyverse/dplyr/issues/7082" target="_blank" rel="noopener">this issue</a>
 for context.</p>
</li>
<li>
<p>The <code>dplyr.legacy_locale</code> global option is soft-deprecated. If you used this to affect the ordering of <a href="https://dplyr.tidyverse.org/reference/arrange.html" target="_blank" rel="noopener"><code>arrange()</code></a>
, use <code>arrange(.locale =)</code> instead. If you used this to affect the ordering of <code>group_by() |&gt; summarise()</code>, follow up with an additional call to <code>arrange(.locale =)</code> instead.</p>
</li>
<li>
<p><a href="https://dplyr.tidyverse.org/reference/if_else.html" target="_blank" rel="noopener"><code>if_else()</code></a>
 no longer allows <code>condition</code> to be a logical array. It must be a logical vector with no <code>dim</code> attribute.</p>
</li>
<li>
<p>We&rsquo;ve removed a number of previously defunct functions, shrinking the footprint of dplyr&rsquo;s API:</p>
<ul>
<li><code>id()</code></li>
<li><code>failwith()</code></li>
<li><code>select_vars()</code> and <code>select_vars_()</code></li>
<li><code>rename_vars()</code> and <code>rename_vars_()</code></li>
<li><code>select_var()</code></li>
<li><code>current_vars()</code></li>
<li><code>bench_tbls()</code>, <code>compare_tbls()</code>, <code>compare_tbls2()</code>, <code>eval_tbls()</code>, and <code>eval_tbls2()</code></li>
<li><code>location()</code> and <code>changes()</code></li>
</ul>
</li>
</ul>
<h2 id="acknowledgements">Acknowledgements
</h2>
<p>We&rsquo;d like to thank all 177 contributors who help in someway, whether it was filing issues or contributing code and documentation: <a href="https://github.com/abalter" target="_blank" rel="noopener">@abalter</a>
, <a href="https://github.com/abichat" target="_blank" rel="noopener">@abichat</a>
, <a href="https://github.com/adupaix" target="_blank" rel="noopener">@adupaix</a>
, <a href="https://github.com/AlexBainton" target="_blank" rel="noopener">@AlexBainton</a>
, <a href="https://github.com/alexmcsw" target="_blank" rel="noopener">@alexmcsw</a>
, <a href="https://github.com/AltfunsMA" target="_blank" rel="noopener">@AltfunsMA</a>
, <a href="https://github.com/AmeliaMN" target="_blank" rel="noopener">@AmeliaMN</a>
, <a href="https://github.com/antdurrant" target="_blank" rel="noopener">@antdurrant</a>
, <a href="https://github.com/AnthonyEbert" target="_blank" rel="noopener">@AnthonyEbert</a>
, <a href="https://github.com/apalacio9502" target="_blank" rel="noopener">@apalacio9502</a>
, <a href="https://github.com/apeterson91" target="_blank" rel="noopener">@apeterson91</a>
, <a href="https://github.com/arnaudgallou" target="_blank" rel="noopener">@arnaudgallou</a>
, <a href="https://github.com/awpsoras" target="_blank" rel="noopener">@awpsoras</a>
, <a href="https://github.com/bakaburg1" target="_blank" rel="noopener">@bakaburg1</a>
, <a href="https://github.com/barnabasharris" target="_blank" rel="noopener">@barnabasharris</a>
, <a href="https://github.com/BHII-KSC" target="_blank" rel="noopener">@BHII-KSC</a>
, <a href="https://github.com/bholtemeyer" target="_blank" rel="noopener">@bholtemeyer</a>
, <a href="https://github.com/billdenney" target="_blank" rel="noopener">@billdenney</a>
, <a href="https://github.com/bounlu" target="_blank" rel="noopener">@bounlu</a>
, <a href="https://github.com/brendensm" target="_blank" rel="noopener">@brendensm</a>
, <a href="https://github.com/bridroberts1" target="_blank" rel="noopener">@bridroberts1</a>
, <a href="https://github.com/brookslogan" target="_blank" rel="noopener">@brookslogan</a>
, <a href="https://github.com/catalamarti" target="_blank" rel="noopener">@catalamarti</a>
, <a href="https://github.com/cboettig" target="_blank" rel="noopener">@cboettig</a>
, <a href="https://github.com/cbrnr" target="_blank" rel="noopener">@cbrnr</a>
, <a href="https://github.com/ccani007" target="_blank" rel="noopener">@ccani007</a>
, <a href="https://github.com/charliejhadley" target="_blank" rel="noopener">@charliejhadley</a>
, <a href="https://github.com/ChrisHIV" target="_blank" rel="noopener">@ChrisHIV</a>
, <a href="https://github.com/ChristianRohde" target="_blank" rel="noopener">@ChristianRohde</a>
, <a href="https://github.com/cobac" target="_blank" rel="noopener">@cobac</a>
, <a href="https://github.com/conig" target="_blank" rel="noopener">@conig</a>
, <a href="https://github.com/const-ae" target="_blank" rel="noopener">@const-ae</a>
, <a href="https://github.com/Copilot" target="_blank" rel="noopener">@Copilot</a>
, <a href="https://github.com/d-morrison" target="_blank" rel="noopener">@d-morrison</a>
, <a href="https://github.com/DanChaltiel" target="_blank" rel="noopener">@DanChaltiel</a>
, <a href="https://github.com/daniel-simeone" target="_blank" rel="noopener">@daniel-simeone</a>
, <a href="https://github.com/DanielBraddock" target="_blank" rel="noopener">@DanielBraddock</a>
, <a href="https://github.com/david-romano" target="_blank" rel="noopener">@david-romano</a>
, <a href="https://github.com/davidrsch" target="_blank" rel="noopener">@davidrsch</a>
, <a href="https://github.com/davidss101" target="_blank" rel="noopener">@davidss101</a>
, <a href="https://github.com/DavisVaughan" target="_blank" rel="noopener">@DavisVaughan</a>
, <a href="https://github.com/dcaud" target="_blank" rel="noopener">@dcaud</a>
, <a href="https://github.com/deschen1" target="_blank" rel="noopener">@deschen1</a>
, <a href="https://github.com/DesiQuintans" target="_blank" rel="noopener">@DesiQuintans</a>
, <a href="https://github.com/devster31" target="_blank" rel="noopener">@devster31</a>
, <a href="https://github.com/dkutner" target="_blank" rel="noopener">@dkutner</a>
, <a href="https://github.com/dmuenz" target="_blank" rel="noopener">@dmuenz</a>
, <a href="https://github.com/ds-jim" target="_blank" rel="noopener">@ds-jim</a>
, <a href="https://github.com/eitsupi" target="_blank" rel="noopener">@eitsupi</a>
, <a href="https://github.com/EmilHvitfeldt" target="_blank" rel="noopener">@EmilHvitfeldt</a>
, <a href="https://github.com/etiennebacher" target="_blank" rel="noopener">@etiennebacher</a>
, <a href="https://github.com/eutwt" target="_blank" rel="noopener">@eutwt</a>
, <a href="https://github.com/EvertonTLima" target="_blank" rel="noopener">@EvertonTLima</a>
, <a href="https://github.com/ferreirafm" target="_blank" rel="noopener">@ferreirafm</a>
, <a href="https://github.com/gaborcsardi" target="_blank" rel="noopener">@gaborcsardi</a>
, <a href="https://github.com/GabryS3" target="_blank" rel="noopener">@GabryS3</a>
, <a href="https://github.com/Gastonia02" target="_blank" rel="noopener">@Gastonia02</a>
, <a href="https://github.com/GBarnsley" target="_blank" rel="noopener">@GBarnsley</a>
, <a href="https://github.com/gevro" target="_blank" rel="noopener">@gevro</a>
, <a href="https://github.com/ggrothendieck" target="_blank" rel="noopener">@ggrothendieck</a>
, <a href="https://github.com/GischD" target="_blank" rel="noopener">@GischD</a>
, <a href="https://github.com/gks281263" target="_blank" rel="noopener">@gks281263</a>
, <a href="https://github.com/gracehartley" target="_blank" rel="noopener">@gracehartley</a>
, <a href="https://github.com/graphdr" target="_blank" rel="noopener">@graphdr</a>
, <a href="https://github.com/hadley" target="_blank" rel="noopener">@hadley</a>
, <a href="https://github.com/heliconone" target="_blank" rel="noopener">@heliconone</a>
, <a href="https://github.com/Hzanib" target="_blank" rel="noopener">@Hzanib</a>
, <a href="https://github.com/ilovemane" target="_blank" rel="noopener">@ilovemane</a>
, <a href="https://github.com/ja-ortiz-uniandes" target="_blank" rel="noopener">@ja-ortiz-uniandes</a>
, <a href="https://github.com/jack-davison" target="_blank" rel="noopener">@jack-davison</a>
, <a href="https://github.com/james-kilgour" target="_blank" rel="noopener">@james-kilgour</a>
, <a href="https://github.com/JamesHWade" target="_blank" rel="noopener">@JamesHWade</a>
, <a href="https://github.com/jaymicro" target="_blank" rel="noopener">@jaymicro</a>
, <a href="https://github.com/JBrandenburg02" target="_blank" rel="noopener">@JBrandenburg02</a>
, <a href="https://github.com/jc-usda" target="_blank" rel="noopener">@jc-usda</a>
, <a href="https://github.com/jennybc" target="_blank" rel="noopener">@jennybc</a>
, <a href="https://github.com/jeroenjanssens" target="_blank" rel="noopener">@jeroenjanssens</a>
, <a href="https://github.com/jestover" target="_blank" rel="noopener">@jestover</a>
, <a href="https://github.com/jl5000" target="_blank" rel="noopener">@jl5000</a>
, <a href="https://github.com/jmbarbone" target="_blank" rel="noopener">@jmbarbone</a>
, <a href="https://github.com/john-b-edwards" target="_blank" rel="noopener">@john-b-edwards</a>
, <a href="https://github.com/jordanmross" target="_blank" rel="noopener">@jordanmross</a>
, <a href="https://github.com/joshua-theisen" target="_blank" rel="noopener">@joshua-theisen</a>
, <a href="https://github.com/jrwinget" target="_blank" rel="noopener">@jrwinget</a>
, <a href="https://github.com/juliaapolonio" target="_blank" rel="noopener">@juliaapolonio</a>
, <a href="https://github.com/jxu" target="_blank" rel="noopener">@jxu</a>
, <a href="https://github.com/KaiAragaki" target="_blank" rel="noopener">@KaiAragaki</a>
, <a href="https://github.com/kiki830621" target="_blank" rel="noopener">@kiki830621</a>
, <a href="https://github.com/KittJonathan" target="_blank" rel="noopener">@KittJonathan</a>
, <a href="https://github.com/kleinerChemiker" target="_blank" rel="noopener">@kleinerChemiker</a>
, <a href="https://github.com/kletts" target="_blank" rel="noopener">@kletts</a>
, <a href="https://github.com/krlmlr" target="_blank" rel="noopener">@krlmlr</a>
, <a href="https://github.com/ks8997" target="_blank" rel="noopener">@ks8997</a>
, <a href="https://github.com/kylebutts" target="_blank" rel="noopener">@kylebutts</a>
, <a href="https://github.com/larsentom" target="_blank" rel="noopener">@larsentom</a>
, <a href="https://github.com/latot" target="_blank" rel="noopener">@latot</a>
, <a href="https://github.com/lboller-pwbm" target="_blank" rel="noopener">@lboller-pwbm</a>
, <a href="https://github.com/lionel-" target="_blank" rel="noopener">@lionel-</a>
, <a href="https://github.com/Longfei2" target="_blank" rel="noopener">@Longfei2</a>
, <a href="https://github.com/lschneiderbauer" target="_blank" rel="noopener">@lschneiderbauer</a>
, <a href="https://github.com/LukasTang" target="_blank" rel="noopener">@LukasTang</a>
, <a href="https://github.com/lukebandy" target="_blank" rel="noopener">@lukebandy</a>
, <a href="https://github.com/maciekbanas" target="_blank" rel="noopener">@maciekbanas</a>
, <a href="https://github.com/maelle" target="_blank" rel="noopener">@maelle</a>
, <a href="https://github.com/marcuslehr" target="_blank" rel="noopener">@marcuslehr</a>
, <a href="https://github.com/Mark-AP" target="_blank" rel="noopener">@Mark-AP</a>
, <a href="https://github.com/markwestcott34" target="_blank" rel="noopener">@markwestcott34</a>
, <a href="https://github.com/maskegger" target="_blank" rel="noopener">@maskegger</a>
, <a href="https://github.com/matiasandina" target="_blank" rel="noopener">@matiasandina</a>
, <a href="https://github.com/matthewjnield" target="_blank" rel="noopener">@matthewjnield</a>
, <a href="https://github.com/mbcann01" target="_blank" rel="noopener">@mbcann01</a>
, <a href="https://github.com/Meghansaha" target="_blank" rel="noopener">@Meghansaha</a>
, <a href="https://github.com/metanoid" target="_blank" rel="noopener">@metanoid</a>
, <a href="https://github.com/MichaelChirico" target="_blank" rel="noopener">@MichaelChirico</a>
, <a href="https://github.com/MikeJohnPage" target="_blank" rel="noopener">@MikeJohnPage</a>
, <a href="https://github.com/MilesMcBain" target="_blank" rel="noopener">@MilesMcBain</a>
, <a href="https://github.com/mine-cetinkaya-rundel" target="_blank" rel="noopener">@mine-cetinkaya-rundel</a>
, <a href="https://github.com/MohsenSoltanifar" target="_blank" rel="noopener">@MohsenSoltanifar</a>
, <a href="https://github.com/moodymudskipper" target="_blank" rel="noopener">@moodymudskipper</a>
, <a href="https://github.com/Moohan" target="_blank" rel="noopener">@Moohan</a>
, <a href="https://github.com/mp8" target="_blank" rel="noopener">@mp8</a>
, <a href="https://github.com/mpsturbo" target="_blank" rel="noopener">@mpsturbo</a>
, <a href="https://github.com/mr-c" target="_blank" rel="noopener">@mr-c</a>
, <a href="https://github.com/muschellij2" target="_blank" rel="noopener">@muschellij2</a>
, <a href="https://github.com/musvaage" target="_blank" rel="noopener">@musvaage</a>
, <a href="https://github.com/Mzhuk7" target="_blank" rel="noopener">@Mzhuk7</a>
, <a href="https://github.com/nalimilan" target="_blank" rel="noopener">@nalimilan</a>
, <a href="https://github.com/nathanhaigh" target="_blank" rel="noopener">@nathanhaigh</a>
, <a href="https://github.com/nirguk" target="_blank" rel="noopener">@nirguk</a>
, <a href="https://github.com/nmercadeb" target="_blank" rel="noopener">@nmercadeb</a>
, <a href="https://github.com/olivermagnanimous" target="_blank" rel="noopener">@olivermagnanimous</a>
, <a href="https://github.com/olivroy" target="_blank" rel="noopener">@olivroy</a>
, <a href="https://github.com/orgadish" target="_blank" rel="noopener">@orgadish</a>
, <a href="https://github.com/pangchaoran" target="_blank" rel="noopener">@pangchaoran</a>
, <a href="https://github.com/paschatz" target="_blank" rel="noopener">@paschatz</a>
, <a href="https://github.com/prubin73" target="_blank" rel="noopener">@prubin73</a>
, <a href="https://github.com/PStaus" target="_blank" rel="noopener">@PStaus</a>
, <a href="https://github.com/psychelzh" target="_blank" rel="noopener">@psychelzh</a>
, <a href="https://github.com/py9mrg" target="_blank" rel="noopener">@py9mrg</a>
, <a href="https://github.com/Raesu" target="_blank" rel="noopener">@Raesu</a>
, <a href="https://github.com/randyzwitch" target="_blank" rel="noopener">@randyzwitch</a>
, <a href="https://github.com/Raoul-Kima" target="_blank" rel="noopener">@Raoul-Kima</a>
, <a href="https://github.com/ReedMerrill" target="_blank" rel="noopener">@ReedMerrill</a>
, <a href="https://github.com/RodDalBen" target="_blank" rel="noopener">@RodDalBen</a>
, <a href="https://github.com/RodrigoZepeda" target="_blank" rel="noopener">@RodrigoZepeda</a>
, <a href="https://github.com/rossholmberg" target="_blank" rel="noopener">@rossholmberg</a>
, <a href="https://github.com/RoyalTS" target="_blank" rel="noopener">@RoyalTS</a>
, <a href="https://github.com/ryandward" target="_blank" rel="noopener">@ryandward</a>
, <a href="https://github.com/sbanville-delfi" target="_blank" rel="noopener">@sbanville-delfi</a>
, <a href="https://github.com/ScientiaFelis" target="_blank" rel="noopener">@ScientiaFelis</a>
, <a href="https://github.com/shirdekel" target="_blank" rel="noopener">@shirdekel</a>
, <a href="https://github.com/slager" target="_blank" rel="noopener">@slager</a>
, <a href="https://github.com/sschooler" target="_blank" rel="noopener">@sschooler</a>
, <a href="https://github.com/steffen-stell" target="_blank" rel="noopener">@steffen-stell</a>
, <a href="https://github.com/szimmer" target="_blank" rel="noopener">@szimmer</a>
, <a href="https://github.com/TheClownBongo" target="_blank" rel="noopener">@TheClownBongo</a>
, <a href="https://github.com/thomasjwood" target="_blank" rel="noopener">@thomasjwood</a>
, <a href="https://github.com/TimTaylor" target="_blank" rel="noopener">@TimTaylor</a>
, <a href="https://github.com/tlyons253" target="_blank" rel="noopener">@tlyons253</a>
, <a href="https://github.com/tomalrussell" target="_blank" rel="noopener">@tomalrussell</a>
, <a href="https://github.com/tomwagstaff-opml" target="_blank" rel="noopener">@tomwagstaff-opml</a>
, <a href="https://github.com/torfason" target="_blank" rel="noopener">@torfason</a>
, <a href="https://github.com/Tyrrx" target="_blank" rel="noopener">@Tyrrx</a>
, <a href="https://github.com/Unaimend" target="_blank" rel="noopener">@Unaimend</a>
, <a href="https://github.com/VisruthSK" target="_blank" rel="noopener">@VisruthSK</a>
, <a href="https://github.com/vorpalvorpal" target="_blank" rel="noopener">@vorpalvorpal</a>
, <a href="https://github.com/walkerjameschris" target="_blank" rel="noopener">@walkerjameschris</a>
, <a href="https://github.com/wbvguo" target="_blank" rel="noopener">@wbvguo</a>
, <a href="https://github.com/wbzyl" target="_blank" rel="noopener">@wbzyl</a>
, <a href="https://github.com/wkumler" target="_blank" rel="noopener">@wkumler</a>
, <a href="https://github.com/yaboody" target="_blank" rel="noopener">@yaboody</a>
, <a href="https://github.com/yjunechoe" target="_blank" rel="noopener">@yjunechoe</a>
, <a href="https://github.com/ynsec37" target="_blank" rel="noopener">@ynsec37</a>
, <a href="https://github.com/ywhcuhk" target="_blank" rel="noopener">@ywhcuhk</a>
, <a href="https://github.com/ZHBHSMILE" target="_blank" rel="noopener">@ZHBHSMILE</a>
, <a href="https://github.com/zhjx19" target="_blank" rel="noopener">@zhjx19</a>
, and <a href="https://github.com/ZIBOWANGKANGYU" target="_blank" rel="noopener">@ZIBOWANGKANGYU</a>
.</p>
]]></description>
      <enclosure url="https://posit-open-source.netlify.app/blog/tidyverse/dplyr-1-2-0/thumbnail-wd.jpg" length="338917" type="image/jpeg" />
    </item>
    <item>
      <title>purrr 1.2.0</title>
      <link>https://posit-open-source.netlify.app/blog/tidyverse/2025/purrr-1-2-0/</link>
      <pubDate>Tue, 04 Nov 2025 00:00:00 +0000</pubDate>
      <guid>https://posit-open-source.netlify.app/blog/tidyverse/2025/purrr-1-2-0/</guid>
      <dc:creator>Hadley Wickham</dc:creator><description><![CDATA[<!--
TODO:
* [x] Look over / edit the post's title in the yaml
* [x] Edit (or delete) the description; note this appears in the Twitter card
* [x] Pick category and tags (see existing with [`hugodown::tidy_show_meta()`](https://rdrr.io/pkg/hugodown/man/use_tidy_post.html))
* [x] Find photo & update yaml metadata
* [x] Create `thumbnail-sq.jpg`; height and width should be equal
* [x] Create `thumbnail-wd.jpg`; width should be >5x height
* [x] [`hugodown::use_tidy_thumbnails()`](https://rdrr.io/pkg/hugodown/man/use_tidy_post.html)
* [x] Add intro sentence, e.g. the standard tagline for the package
* [ ] [`usethis::use_tidy_thanks()`](https://usethis.r-lib.org/reference/use_tidy_thanks.html)
-->
<p>We&rsquo;re thrilled to announce the release of purrr 1.2.0! purrr enhances R&rsquo;s functional programming toolkit with a complete and consistent set of tools for working with functions and vectors.</p>
<p>You can install it from CRAN with:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nf'><a href='https://rdrr.io/r/utils/install.packages.html'>install.packages</a></span><span class='o'>(</span><span class='s'>"purrr"</span><span class='o'>)</span></span></code></pre>
</div>
<p>Overall, this is a pretty unexciting release since it primarily focuses on removing long-deprecated functions. It does, however, include a couple of small performance improvements to predicate functions and a brand new getting started vignette. We also require a newer version of the carrier package for <a href="https://purrr.tidyverse.org/reference/in_parallel.html" target="_blank" rel="noopener"><code>in_parallel()</code></a>
 so that it&rsquo;s easier to use. You can see a full list of changes in the <a href="https://github.com/tidyverse/purrr/releases/tag/v1.2.0" target="_blank" rel="noopener">release notes</a>
.</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='kr'><a href='https://rdrr.io/r/base/library.html'>library</a></span><span class='o'>(</span><span class='nv'><a href='https://purrr.tidyverse.org/'>purrr</a></span><span class='o'>)</span></span></code></pre>
</div>
<h2 id="lifecycle-changes">Lifecycle changes
</h2>
<ul>
<li>
<p>All functions and arguments that were deprecated in purrr 0.3.0 have now been removed after being deprecated for over 5 years. These include:</p>
<ul>
<li><code>%@%</code></li>
<li><code>accumulate_right()</code></li>
<li><code>at_depth()</code></li>
<li><code>cross_d()</code></li>
<li><code>cross_n()</code></li>
<li><code>reduce2_right()</code></li>
<li><code>reduce_right()</code></li>
</ul>
</li>
<li>
<p>All functions that were soft-deprecated in purrr 1.0.0 are now fully deprecated. They will continue to work but will generate a deprecation warning, and will be removed in a future release. This includes:</p>
<ul>
<li><code>invoke_*()</code> functions</li>
<li><code>lift_*()</code> functions</li>
<li><code>cross*()</code> functions (use <a href="https://tidyr.tidyverse.org/reference/expand_grid.html" target="_blank" rel="noopener"><code>tidyr::expand_grid()</code></a>
 instead)</li>
<li><a href="https://purrr.tidyverse.org/reference/prepend.html" target="_blank" rel="noopener"><code>prepend()</code></a>
</li>
<li><code>splice()</code></li>
<li><a href="https://purrr.tidyverse.org/reference/rbernoulli.html" target="_blank" rel="noopener"><code>rbernoulli()</code></a>
</li>
<li><a href="https://purrr.tidyverse.org/reference/rdunif.html" target="_blank" rel="noopener"><code>rdunif()</code></a>
</li>
<li><a href="https://purrr.tidyverse.org/reference/when.html" target="_blank" rel="noopener"><code>when()</code></a>
</li>
<li><a href="https://purrr.tidyverse.org/reference/update_list.html" target="_blank" rel="noopener"><code>update_list()</code></a>
</li>
<li><code>*_raw()</code> functions</li>
<li><a href="https://purrr.tidyverse.org/reference/pluck_depth.html" target="_blank" rel="noopener"><code>vec_depth()</code></a>
</li>
</ul>
<p>These deprecations help keep purrr focused on its core purpose: facilitating functional programming in R.</p>
</li>
<li>
<p><a href="https://purrr.tidyverse.org/reference/map.html" target="_blank" rel="noopener"><code>map_chr()</code></a>
 no longer automatically coerces logical, integer, or double values to strings. Previously, this coercion happened silently, which could mask bugs in your code. Of the four CRAN packages that required fixes due to this change, two of them (50%) were bugs.</p>
</li>
<li>
<p>The predicate functions <a href="https://purrr.tidyverse.org/reference/every.html" target="_blank" rel="noopener"><code>every()</code></a>
, <a href="https://purrr.tidyverse.org/reference/every.html" target="_blank" rel="noopener"><code>some()</code></a>
, and <a href="https://purrr.tidyverse.org/reference/every.html" target="_blank" rel="noopener"><code>none()</code></a>
 now require that the predicate function <code>.p</code> returns a logical scalar: <code>TRUE</code>, <code>FALSE</code>, or <code>NA</code>. Previously, <code>NA</code> values of other types (like <code>NA_integer_</code> or <code>NA_character_</code>) were allowed.</p>
</li>
</ul>
<h2 id="minor-improvements">Minor improvements
</h2>
<p>Apart from all the breaking changes, there were a couple of small improvements:</p>
<ul>
<li>
<p><a href="https://purrr.tidyverse.org/reference/every.html" target="_blank" rel="noopener"><code>every()</code></a>
, <a href="https://purrr.tidyverse.org/reference/every.html" target="_blank" rel="noopener"><code>some()</code></a>
, and <a href="https://purrr.tidyverse.org/reference/every.html" target="_blank" rel="noopener"><code>none()</code></a>
 have been optimized and are now significantly faster. They&rsquo;re now as fast as or faster than the equivalent <code>any(map_lgl())</code> or <code>all(map_lgl())</code> calls, making them the preferred choice for checking predicates across lists.</p>
</li>
<li>
<p>purrr (finally) has a &ldquo;getting started&rdquo; vignette at <code>vignette(&quot;purrr&quot;)</code>.</p>
</li>
</ul>
<h2 id="easier-in_parallel">Easier <code>in_parallel()</code>
</h2>
<p>In purrr 1.1.0, we introduced <a href="https://purrr.tidyverse.org/reference/in_parallel.html" target="_blank" rel="noopener"><code>in_parallel()</code></a>
 for <a href="https://tidyverse.org/blog/2025/07/purrr-1-1-0-parallel" target="_blank" rel="noopener">parallel processing</a>
 and we&rsquo;ve had great feedback from the community so far. But it was clear that we hadn&rsquo;t made it easy enough to include helper functions or other variables required by your map functions. We&rsquo;ve updated this behaviour in carrier 0.3.0, which is now required by purrr. Now the following (in your global environment) will work as you expect:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>fn</span> <span class='o'>&lt;-</span> <span class='kr'>function</span><span class='o'>(</span><span class='nv'>x</span><span class='o'>)</span> <span class='nf'>helper_fn</span><span class='o'>(</span><span class='nv'>x</span><span class='o'>)</span> <span class='o'>*</span> <span class='m'>2</span></span>
<span><span class='nv'>helper_fn</span> <span class='o'>&lt;-</span> <span class='kr'>function</span><span class='o'>(</span><span class='nv'>x</span><span class='o'>)</span> <span class='nv'>x</span> <span class='o'>+</span> <span class='m'>1</span></span>
<span><span class='m'>1</span><span class='o'>:</span><span class='m'>5</span> <span class='o'>|&gt;</span> <span class='nf'><a href='https://purrr.tidyverse.org/reference/map.html'>map</a></span><span class='o'>(</span><span class='nf'><a href='https://purrr.tidyverse.org/reference/in_parallel.html'>in_parallel</a></span><span class='o'>(</span>\<span class='o'>(</span><span class='nv'>x</span><span class='o'>)</span> <span class='nf'>fn</span><span class='o'>(</span><span class='nv'>x</span><span class='o'>)</span>, fn <span class='o'>=</span> <span class='nv'>fn</span>, helper_fn <span class='o'>=</span> <span class='nv'>helper_fn</span><span class='o'>)</span><span class='o'>)</span></span></code></pre>
</div>
<p>Whereas previously, <code>fn()</code> would have been unable to find <code>helper_fn()</code>, this is solved by all functions passed to <a href="https://purrr.tidyverse.org/reference/in_parallel.html" target="_blank" rel="noopener"><code>in_parallel()</code></a>
 now sharing the same environment.</p>
<h2 id="acknowledgements">Acknowledgements
</h2>
<p>We&rsquo;d like to thank everyone who contributed to this release by filing issues and submitting pull requests. Your feedback and contributions help make purrr better for everyone! <a href="https://github.com/feinleib" target="_blank" rel="noopener">@feinleib</a>
, <a href="https://github.com/filipemsc" target="_blank" rel="noopener">@filipemsc</a>
, <a href="https://github.com/fwimp" target="_blank" rel="noopener">@fwimp</a>
, <a href="https://github.com/hadley" target="_blank" rel="noopener">@hadley</a>
, <a href="https://github.com/its-gazza" target="_blank" rel="noopener">@its-gazza</a>
, <a href="https://github.com/jcolt45" target="_blank" rel="noopener">@jcolt45</a>
, <a href="https://github.com/jeroenjanssens" target="_blank" rel="noopener">@jeroenjanssens</a>
, <a href="https://github.com/jrwinget" target="_blank" rel="noopener">@jrwinget</a>
, <a href="https://github.com/khusmann" target="_blank" rel="noopener">@khusmann</a>
, <a href="https://github.com/luisDVA" target="_blank" rel="noopener">@luisDVA</a>
, <a href="https://github.com/MarkPaulin" target="_blank" rel="noopener">@MarkPaulin</a>
, <a href="https://github.com/Meghansaha" target="_blank" rel="noopener">@Meghansaha</a>
, <a href="https://github.com/mtcarsalot" target="_blank" rel="noopener">@mtcarsalot</a>
, <a href="https://github.com/og2293" target="_blank" rel="noopener">@og2293</a>
, <a href="https://github.com/padpadpadpad" target="_blank" rel="noopener">@padpadpadpad</a>
, <a href="https://github.com/PMassicotte" target="_blank" rel="noopener">@PMassicotte</a>
, <a href="https://github.com/shikokuchuo" target="_blank" rel="noopener">@shikokuchuo</a>
, <a href="https://github.com/steffen-stell" target="_blank" rel="noopener">@steffen-stell</a>
, and <a href="https://github.com/wahalulu" target="_blank" rel="noopener">@wahalulu</a>
.</p>
]]></description>
      <enclosure url="https://posit-open-source.netlify.app/blog/tidyverse/2025/purrr-1-2-0/thumbnail-wd.jpg" length="256333" type="image/jpeg" />
    </item>
    <item>
      <title>stringr 1.6.0</title>
      <link>https://posit-open-source.netlify.app/blog/tidyverse/2025/stringr-1-6-0/</link>
      <pubDate>Tue, 04 Nov 2025 00:00:00 +0000</pubDate>
      <guid>https://posit-open-source.netlify.app/blog/tidyverse/2025/stringr-1-6-0/</guid>
      <dc:creator>Hadley Wickham</dc:creator><description><![CDATA[<!--
TODO:
* [x] Look over / edit the post's title in the yaml
* [x] Edit (or delete) the description; note this appears in the Twitter card
* [x] Pick category and tags (see existing with [`hugodown::tidy_show_meta()`](https://rdrr.io/pkg/hugodown/man/use_tidy_post.html))
* [x] Find photo & update yaml metadata
* [x] Create `thumbnail-sq.jpg`; height and width should be equal
* [x] Create `thumbnail-wd.jpg`; width should be >5x height
* [x] [`hugodown::use_tidy_thumbnails()`](https://rdrr.io/pkg/hugodown/man/use_tidy_post.html)
* [x] Add intro sentence, e.g. the standard tagline for the package
* [ ] [`usethis::use_tidy_thanks()`](https://usethis.r-lib.org/reference/use_tidy_thanks.html)
-->
<p>We&rsquo;re delighted to announce the release of stringr 1.6.0! stringr provides a cohesive set of functions designed to make working with strings as easy as possible. You can install it from CRAN with:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nf'><a href='https://rdrr.io/r/utils/install.packages.html'>install.packages</a></span><span class='o'>(</span><span class='s'>"stringr"</span><span class='o'>)</span></span></code></pre>
</div>
<p>This release includes some lifecycle changes, improvements to <code>sql_like()</code>/<code>sql_ilike()</code>, and a handful of other useful features. You can see a full list of changes in the <a href="https://github.com/tidyverse/stringr/releases/tag/v1.6.0" target="_blank" rel="noopener">release notes</a>
.</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='kr'><a href='https://rdrr.io/r/base/library.html'>library</a></span><span class='o'>(</span><span class='nv'><a href='https://stringr.tidyverse.org'>stringr</a></span><span class='o'>)</span></span></code></pre>
</div>
<h2 id="lifecycle-changes">Lifecycle changes
</h2>
<p>This release includes two lifecycle changes that may affect existing code.</p>
<p>First, the <code>ignore_case</code> argument to <a href="https://stringr.tidyverse.org/reference/str_like.html" target="_blank" rel="noopener"><code>str_like()</code></a>
 is now deprecated. Previously, it defaulted to <code>ignore_case = TRUE</code>. This was a mistake because it doesn&rsquo;t align with the conventions of the SQL <code>LIKE</code> operator, which is always case sensitive. Going forward, <a href="https://stringr.tidyverse.org/reference/str_like.html" target="_blank" rel="noopener"><code>str_like()</code></a>
 will always be case sensitive, so if you need case-insensitive matching, use the new <a href="https://stringr.tidyverse.org/reference/str_like.html" target="_blank" rel="noopener"><code>str_ilike()</code></a>
 function.</p>
<p>Second, if you use <a href="https://stringr.tidyverse.org/reference/str_replace.html" target="_blank" rel="noopener"><code>str_replace_all()</code></a>
 with a function for the <code>replacement</code> argument, that function now receives all values in a single character vector instead of being called once for each individual string. This change dramatically improves performance, so I decided it was worth it despite its impact on existing code. It shouldn&rsquo;t affect too much existing code in the wild, and it only broke 11 of the 2,381 CRAN packages that use stringr (which I fixed via PR). If you haven&rsquo;t used this functionality before, it&rsquo;s pretty cool, because it allows you to supply a function that can transform matches in any way you can imagine. For example, this code replaces color names with their corresponding hex values:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>colours</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://stringr.tidyverse.org/reference/str_c.html'>str_c</a></span><span class='o'>(</span><span class='s'>"\\b"</span>, <span class='nf'><a href='https://rdrr.io/r/grDevices/colors.html'>colors</a></span><span class='o'>(</span><span class='o'>)</span>, <span class='s'>"\\b"</span>, collapse <span class='o'>=</span> <span class='s'>"|"</span><span class='o'>)</span></span>
<span><span class='nv'>col2hex</span> <span class='o'>&lt;-</span> <span class='kr'>function</span><span class='o'>(</span><span class='nv'>col</span><span class='o'>)</span> <span class='o'>&#123;</span></span>
<span>  <span class='nv'>rgb</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://rdrr.io/r/grDevices/col2rgb.html'>col2rgb</a></span><span class='o'>(</span><span class='nv'>col</span><span class='o'>)</span></span>
<span>  <span class='nf'><a href='https://rdrr.io/r/grDevices/rgb.html'>rgb</a></span><span class='o'>(</span><span class='nv'>rgb</span><span class='o'>[</span><span class='s'>"red"</span>, <span class='o'>]</span>, <span class='nv'>rgb</span><span class='o'>[</span><span class='s'>"green"</span>, <span class='o'>]</span>, <span class='nv'>rgb</span><span class='o'>[</span><span class='s'>"blue"</span>, <span class='o'>]</span>, maxColorValue <span class='o'>=</span> <span class='m'>255</span><span class='o'>)</span></span>
<span><span class='o'>&#125;</span></span>
<span></span>
<span><span class='c'># by Claude Code</span></span>
<span><span class='nv'>poem</span> <span class='o'>&lt;-</span> <span class='s'>"Azure skies meet honeydew light,</span></span>
<span><span class='s'>While coral blooms kiss morning's face.</span></span>
<span><span class='s'>Gold spills across the wheat-field bright,</span></span>
<span><span class='s'>As lavender shadows lose their place.</span></span>
<span><span class='s'>Turquoise waters catch the sun,</span></span>
<span><span class='s'>Where salmon leap through chartreuse streams.</span></span>
<span><span class='s'>Orchid petals, one by one,</span></span>
<span><span class='s'>Fall like plum-soft summer dreams.</span></span>
<span><span class='s'>"</span></span>
<span><span class='nf'><a href='https://rdrr.io/r/base/cat.html'>cat</a></span><span class='o'>(</span><span class='nf'><a href='https://stringr.tidyverse.org/reference/str_replace.html'>str_replace_all</a></span><span class='o'>(</span><span class='nv'>poem</span>, <span class='nf'><a href='https://stringr.tidyverse.org/reference/modifiers.html'>regex</a></span><span class='o'>(</span><span class='nv'>colours</span>, ignore_case <span class='o'>=</span> <span class='kc'>TRUE</span><span class='o'>)</span>, <span class='nv'>col2hex</span><span class='o'>)</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; #F0FFFF skies meet #F0FFF0 light,</span></span>
<span><span class='c'>#&gt; While #FF7F50 blooms kiss morning's face.</span></span>
<span><span class='c'>#&gt; #FFD700 spills across the #F5DEB3-field bright,</span></span>
<span><span class='c'>#&gt; As #E6E6FA shadows lose their place.</span></span>
<span><span class='c'>#&gt; #40E0D0 waters catch the sun,</span></span>
<span><span class='c'>#&gt; Where #FA8072 leap through #7FFF00 streams.</span></span>
<span><span class='c'>#&gt; #DA70D6 petals, one by one,</span></span>
<span><span class='c'>#&gt; Fall like #DDA0DD-soft summer dreams.</span></span>
<span></span></code></pre>
</div>
<p>Which version do you think is catchier? 🤣</p>
<h2 id="other-improvements">Other improvements
</h2>
<p>This release includes several other useful enhancements:</p>
<ul>
<li>
<p>Three new functions make it easy to convert between different programming case conventions:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>x</span> <span class='o'>&lt;-</span> <span class='s'>"quick brown fox"</span></span>
<span></span>
<span><span class='nf'><a href='https://stringr.tidyverse.org/reference/str_to_camel.html'>str_to_camel</a></span><span class='o'>(</span><span class='nv'>x</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; [1] "quickBrownFox"</span></span>
<span></span><span><span class='nf'><a href='https://stringr.tidyverse.org/reference/str_to_camel.html'>str_to_camel</a></span><span class='o'>(</span><span class='nv'>x</span>, first_upper <span class='o'>=</span> <span class='kc'>TRUE</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; [1] "QuickBrownFox"</span></span>
<span></span><span><span class='nf'><a href='https://stringr.tidyverse.org/reference/str_to_camel.html'>str_to_snake</a></span><span class='o'>(</span><span class='nv'>x</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; [1] "quick_brown_fox"</span></span>
<span></span><span><span class='nf'><a href='https://stringr.tidyverse.org/reference/str_to_camel.html'>str_to_kebab</a></span><span class='o'>(</span><span class='nv'>x</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; [1] "quick-brown-fox"</span></span>
<span></span></code></pre>
</div>
</li>
<li>
<p>All relevant stringr functions now preserve names. This means if your input vector has names, those names will be preserved in the output:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>x</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://rdrr.io/r/base/c.html'>c</a></span><span class='o'>(</span>first <span class='o'>=</span> <span class='s'>"apple"</span>, second <span class='o'>=</span> <span class='s'>"banana"</span><span class='o'>)</span></span>
<span><span class='nf'><a href='https://stringr.tidyverse.org/reference/case.html'>str_to_upper</a></span><span class='o'>(</span><span class='nv'>x</span><span class='o'>)</span></span>
<span><span class='c'>#&gt;    first   second </span></span>
<span><span class='c'>#&gt;  "APPLE" "BANANA"</span></span>
<span></span><span><span class='nf'><a href='https://stringr.tidyverse.org/reference/str_detect.html'>str_detect</a></span><span class='o'>(</span><span class='nv'>x</span>, <span class='s'>"b"</span><span class='o'>)</span></span>
<span><span class='c'>#&gt;  first second </span></span>
<span><span class='c'>#&gt;  FALSE   TRUE</span></span>
<span></span></code></pre>
</div>
</li>
<li>
<p>A new <code>vignette(&quot;locale-sensitive&quot;)</code> provides detailed information about locale-sensitive functions in stringr, helping you understand how different locales affect string operations like sorting and case conversion.</p>
</li>
</ul>
<h2 id="acknowledgements">Acknowledgements
</h2>
<p>A big thank you to everyone who contributed to this release! <a href="https://github.com/alexanderbeatson" target="_blank" rel="noopener">@alexanderbeatson</a>
, <a href="https://github.com/allenbaron" target="_blank" rel="noopener">@allenbaron</a>
, <a href="https://github.com/Anaherasm" target="_blank" rel="noopener">@Anaherasm</a>
, <a href="https://github.com/arnaudgallou" target="_blank" rel="noopener">@arnaudgallou</a>
, <a href="https://github.com/AustinFournierKL" target="_blank" rel="noopener">@AustinFournierKL</a>
, <a href="https://github.com/brownj31" target="_blank" rel="noopener">@brownj31</a>
, <a href="https://github.com/ChristelSwift" target="_blank" rel="noopener">@ChristelSwift</a>
, <a href="https://github.com/DanChaltiel" target="_blank" rel="noopener">@DanChaltiel</a>
, <a href="https://github.com/davidciani" target="_blank" rel="noopener">@davidciani</a>
, <a href="https://github.com/davidhodge931" target="_blank" rel="noopener">@davidhodge931</a>
, <a href="https://github.com/Edgar-Zamora" target="_blank" rel="noopener">@Edgar-Zamora</a>
, <a href="https://github.com/edward-burn" target="_blank" rel="noopener">@edward-burn</a>
, <a href="https://github.com/gaborcsardi" target="_blank" rel="noopener">@gaborcsardi</a>
, <a href="https://github.com/hadley" target="_blank" rel="noopener">@hadley</a>
, <a href="https://github.com/jack-davison" target="_blank" rel="noopener">@jack-davison</a>
, <a href="https://github.com/jdonland" target="_blank" rel="noopener">@jdonland</a>
, <a href="https://github.com/jeroenjanssens" target="_blank" rel="noopener">@jeroenjanssens</a>
, <a href="https://github.com/JFormoso" target="_blank" rel="noopener">@JFormoso</a>
, <a href="https://github.com/jonovik" target="_blank" rel="noopener">@jonovik</a>
, <a href="https://github.com/KimLopezGuell" target="_blank" rel="noopener">@KimLopezGuell</a>
, <a href="https://github.com/krlmlr" target="_blank" rel="noopener">@krlmlr</a>
, <a href="https://github.com/kylieainslie" target="_blank" rel="noopener">@kylieainslie</a>
, <a href="https://github.com/librill" target="_blank" rel="noopener">@librill</a>
, <a href="https://github.com/Longfei2" target="_blank" rel="noopener">@Longfei2</a>
, <a href="https://github.com/LouisMPenrod" target="_blank" rel="noopener">@LouisMPenrod</a>
, <a href="https://github.com/mararva" target="_blank" rel="noopener">@mararva</a>
, <a href="https://github.com/mgacc0" target="_blank" rel="noopener">@mgacc0</a>
, <a href="https://github.com/MiguelCos" target="_blank" rel="noopener">@MiguelCos</a>
, <a href="https://github.com/nash-delcamp-slp" target="_blank" rel="noopener">@nash-delcamp-slp</a>
, <a href="https://github.com/ning-y" target="_blank" rel="noopener">@ning-y</a>
, <a href="https://github.com/Rekyt" target="_blank" rel="noopener">@Rekyt</a>
, <a href="https://github.com/salim-b" target="_blank" rel="noopener">@salim-b</a>
, <a href="https://github.com/shaggycamel" target="_blank" rel="noopener">@shaggycamel</a>
, <a href="https://github.com/SoyAndrea" target="_blank" rel="noopener">@SoyAndrea</a>
, <a href="https://github.com/tamimart" target="_blank" rel="noopener">@tamimart</a>
, <a href="https://github.com/tvedebrink" target="_blank" rel="noopener">@tvedebrink</a>
, <a href="https://github.com/VisruthSK" target="_blank" rel="noopener">@VisruthSK</a>
, <a href="https://github.com/warnes" target="_blank" rel="noopener">@warnes</a>
, and <a href="https://github.com/wright13" target="_blank" rel="noopener">@wright13</a>
.</p>
]]></description>
      <enclosure url="https://posit-open-source.netlify.app/blog/tidyverse/2025/stringr-1-6-0/thumbnail-wd.jpg" length="148495" type="image/jpeg" />
    </item>
    <item>
      <title>httr2 1.2.0</title>
      <link>https://posit-open-source.netlify.app/blog/tidyverse/2025/httr2-1-2-0/</link>
      <pubDate>Mon, 14 Jul 2025 00:00:00 +0000</pubDate>
      <guid>https://posit-open-source.netlify.app/blog/tidyverse/2025/httr2-1-2-0/</guid>
      <dc:creator>Hadley Wickham</dc:creator><description><![CDATA[<!--
TODO:
* [x] Look over / edit the post's title in the yaml
* [x] Edit (or delete) the description; note this appears in the Twitter card
* [x] Pick category and tags (see existing with [`hugodown::tidy_show_meta()`](https://rdrr.io/pkg/hugodown/man/use_tidy_post.html))
* [x] Find photo & update yaml metadata
* [x] Create `thumbnail-sq.jpg`; height and width should be equal
* [x] Create `thumbnail-wd.jpg`; width should be >5x height
* [x] [`hugodown::use_tidy_thumbnails()`](https://rdrr.io/pkg/hugodown/man/use_tidy_post.html)
* [x] Add intro sentence, e.g. the standard tagline for the package
* [x] [`usethis::use_tidy_thanks()`](https://usethis.r-lib.org/reference/use_tidy_thanks.html)
-->
<h1 id="httr2-120">httr2 1.2.0
</h1>
<p>We&rsquo;re delighted to announce the release of httr2 1.2.0! httr2 (pronounced &ldquo;hitter2&rdquo;) is a comprehensive HTTP client that provides a modern, pipeable API for working with web APIs. It builds on top of {curl} to provide features like explicit request objects, built-in rate limiting &amp; retry tooling, comprehensive OAuth support, and secure handling of secrets and credentials.</p>
<p>You can install it from CRAN with:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="nf">install.packages</span><span class="p">(</span><span class="s">&#34;httr2&#34;</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>This blog post will walk you through the most important changes in 1.2.0: lifecycle updates, improved security for redacted headers, URL handling improvements, improved debugging tools, and a handful of other quality of life improvements. You can see a full list of changes in the <a href="https://github.com/r-lib/httr2/releases/tag/v1.2.0" target="_blank" rel="noopener">release notes</a>
</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='kr'><a href='https://rdrr.io/r/base/library.html'>library</a></span><span class='o'>(</span><span class='nv'><a href='https://httr2.r-lib.org'>httr2</a></span><span class='o'>)</span></span></code></pre>
</div>
<h2 id="lifecycle-changes">Lifecycle changes
</h2>
<p>Part of httr2&rsquo;s continued evolution is phasing out features that we now believe were mistakes. In this release:</p>
<ul>
<li>
<p><a href="https://httr2.r-lib.org/reference/req_perform_stream.html" target="_blank" rel="noopener"><code>req_perform_stream()</code></a>
 has been soft deprecated (not just superseded) in favour of <a href="https://httr2.r-lib.org/reference/req_perform_connection.html" target="_blank" rel="noopener"><code>req_perform_connection()</code></a>
.</p>
</li>
<li>
<p>Deprecated functions <code>multi_req_perform()</code>, <code>req_stream()</code>, <code>with_mock()</code>, and <code>local_mock()</code> have now been removed. Please use their modern replacements, <a href="https://httr2.r-lib.org/reference/req_perform_parallel.html" target="_blank" rel="noopener"><code>req_perform_parallel()</code></a>
, <a href="https://httr2.r-lib.org/reference/req_perform_stream.html" target="_blank" rel="noopener"><code>req_perform_stream()</code></a>
, <a href="https://httr2.r-lib.org/reference/with_mocked_responses.html" target="_blank" rel="noopener"><code>with_mocked_responses()</code></a>
, and <a href="https://httr2.r-lib.org/reference/with_mocked_responses.html" target="_blank" rel="noopener"><code>local_mocked_responses()</code></a>
, instead.</p>
</li>
<li>
<p>Deprecated arguments <code>req_perform_parallel(pool)</code>, <code>req_oauth_auth_code(host_name, host_ip, port)</code>, and <code>oauth_flow_auth_code(host_name, host_ip, port)</code> have been removed. Please use <code>req_perform_parallel(max_active)</code> and <code>req_oauth_auth_code(redirect_url)</code>/ <code>oauth_flow_auth_code(redirect_url)</code> instead.</p>
</li>
</ul>
<h2 id="enhanced-security-for-redacted-headers">Enhanced security for redacted headers
</h2>
<p>One of the most important improvements in this release improves the security of redacted headers. Redacted headers are used to conceal secrets, like API keys or passwords, that you don&rsquo;t want to accidentally reveal. For a long time, httr2 has automatically hidden these headers when you <a href="https://rdrr.io/r/base/print.html" target="_blank" rel="noopener"><code>print()</code></a>
 or <a href="https://rdrr.io/r/utils/str.html" target="_blank" rel="noopener"><code>str()</code></a>
 them, ensuring that they don&rsquo;t accidentally end up in log files. You can see this in action with the <code>Authorization</code> header, which httr2 now automatically redacts:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>req</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://httr2.r-lib.org/reference/request.html'>request</a></span><span class='o'>(</span><span class='s'>"http://example.com"</span><span class='o'>)</span> <span class='o'>|&gt;</span></span>
<span>  <span class='nf'><a href='https://httr2.r-lib.org/reference/req_auth_basic.html'>req_auth_basic</a></span><span class='o'>(</span><span class='s'>"username"</span>, <span class='s'>"password"</span><span class='o'>)</span></span>
<span></span>
<span><span class='nv'>req</span></span>
<span><span class='c'>#&gt; <span style='color: #0000BB;'>&lt;httr2_request&gt;</span></span></span>
<span><span class='c'>#&gt; <span style='font-weight: bold;'>GET</span> http://example.com</span></span>
<span><span class='c'>#&gt; <span style='font-weight: bold;'>Headers:</span></span></span>
<span><span class='c'>#&gt; * <span style='color: #00BB00;'>Authorization</span>: <span style='color: #555555;'>&lt;REDACTED&gt;</span></span></span>
<span><span class='c'>#&gt; <span style='font-weight: bold;'>Body</span>: empty</span></span>
<span></span><span><span class='nf'><a href='https://rdrr.io/r/utils/str.html'>str</a></span><span class='o'>(</span><span class='nv'>req</span><span class='o'>$</span><span class='nv'>headers</span><span class='o'>)</span></span>
<span><span class='c'>#&gt;  &lt;httr2_headers&gt;</span></span>
<span><span class='c'>#&gt;  $ Authorization: <span style='color: #555555;'>&lt;REDACTED&gt;</span></span></span>
<span></span><span><span class='nv'>req</span> <span class='o'>|&gt;</span> <span class='nf'><a href='https://httr2.r-lib.org/reference/req_dry_run.html'>req_dry_run</a></span><span class='o'>(</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; GET / HTTP/1.1</span></span>
<span><span class='c'>#&gt; <span style='font-weight: bold;'>accept</span>: */*</span></span>
<span><span class='c'>#&gt; <span style='font-weight: bold;'>accept-encoding</span>: deflate, gzip</span></span>
<span><span class='c'>#&gt; <span style='font-weight: bold;'>authorization</span>: <span style='color: #555555;'>&lt;REDACTED&gt;</span></span></span>
<span><span class='c'>#&gt; <span style='font-weight: bold;'>host</span>: example.com</span></span>
<span><span class='c'>#&gt; <span style='font-weight: bold;'>user-agent</span>: httr2/1.2.0 r-curl/6.4.0 libcurl/8.14.1</span></span>
<span></span></code></pre>
</div>
<p>(If for you do really need to see the redacted values you can get with a bit of extra effort: call the new <a href="https://httr2.r-lib.org/reference/req_get_headers.html" target="_blank" rel="noopener"><code>req_get_headers()</code></a>
 function with <code>redacted = &quot;reveal&quot;</code>.)</p>
<p>In httr2 1.2.0, we&rsquo;ve gone one step further, and prevented redacted headers from being saved to disk. Now if you save and reload a request, you&rsquo;ll notice that the redacted headers are no longer present:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>path</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://rdrr.io/r/base/tempfile.html'>tempfile</a></span><span class='o'>(</span><span class='o'>)</span></span>
<span><span class='nf'><a href='https://rdrr.io/r/base/readRDS.html'>saveRDS</a></span><span class='o'>(</span><span class='nv'>req</span>, <span class='nv'>path</span><span class='o'>)</span></span>
<span></span>
<span><span class='nv'>req2</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://rdrr.io/r/base/readRDS.html'>readRDS</a></span><span class='o'>(</span><span class='nv'>path</span><span class='o'>)</span></span>
<span><span class='nv'>req2</span> <span class='o'>|&gt;</span> <span class='nf'><a href='https://httr2.r-lib.org/reference/req_dry_run.html'>req_dry_run</a></span><span class='o'>(</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; GET / HTTP/1.1</span></span>
<span><span class='c'>#&gt; <span style='font-weight: bold;'>accept</span>: */*</span></span>
<span><span class='c'>#&gt; <span style='font-weight: bold;'>accept-encoding</span>: deflate, gzip</span></span>
<span><span class='c'>#&gt; <span style='font-weight: bold;'>host</span>: example.com</span></span>
<span><span class='c'>#&gt; <span style='font-weight: bold;'>user-agent</span>: httr2/1.2.0 r-curl/6.4.0 libcurl/8.14.1</span></span>
<span></span></code></pre>
</div>
<p>This protects you from accidentally revealing your credentials if you save a request to disk. This is easier to do than you might expect because httr2 includes the request object in every response (since this makes debugging much easier). That means if you&rsquo;re caching a slow response, it&rsquo;s very easy to accidentally store a secret, potentially leaking secure values. (Don&rsquo;t ask me how I discovered this!)</p>
<h2 id="url-handling-improvements">URL handling improvements
</h2>
<p>URL construction is now powered by <a href="https://jeroen.r-universe.dev/curl/reference/curl_parse_url.html" target="_blank" rel="noopener"><code>curl::curl_modify_url()</code></a>
, which correctly escapes the path component:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>req</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://httr2.r-lib.org/reference/request.html'>request</a></span><span class='o'>(</span><span class='s'>"https://api.example.com"</span><span class='o'>)</span></span>
<span><span class='nv'>req</span> <span class='o'>|&gt;</span> <span class='nf'><a href='https://httr2.r-lib.org/reference/req_url.html'>req_url_path</a></span><span class='o'>(</span><span class='s'>"/users/john doe/profile"</span><span class='o'>)</span> <span class='o'>|&gt;</span> <span class='nf'><a href='https://httr2.r-lib.org/reference/req_get_url.html'>req_get_url</a></span><span class='o'>(</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; [1] "https://api.example.com/users/john%20doe/profile"</span></span>
<span></span></code></pre>
</div>
<p>This means that <a href="https://httr2.r-lib.org/reference/req_url.html" target="_blank" rel="noopener"><code>req_url_path()</code></a>
 can now only affect the path component of the URL, not the query parameters. If you previously relied on this behaviour, you&rsquo;ll need to switch to <a href="https://httr2.r-lib.org/reference/req_url.html" target="_blank" rel="noopener"><code>req_url_query()</code></a>
:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='c'># won't work any more:</span></span>
<span><span class='nv'>req</span> <span class='o'>|&gt;</span> </span>
<span>  <span class='nf'><a href='https://httr2.r-lib.org/reference/req_url.html'>req_url_path</a></span><span class='o'>(</span><span class='s'>"/users?name=john-doe"</span><span class='o'>)</span> <span class='o'>|&gt;</span> </span>
<span>  <span class='nf'><a href='https://httr2.r-lib.org/reference/req_get_url.html'>req_get_url</a></span><span class='o'>(</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; [1] "https://api.example.com/users%3Fname%3Djohn-doe"</span></span>
<span></span><span><span class='c'># so now do this:</span></span>
<span><span class='nv'>req</span> <span class='o'>|&gt;</span> </span>
<span>  <span class='nf'><a href='https://httr2.r-lib.org/reference/req_url.html'>req_url_path</a></span><span class='o'>(</span><span class='s'>"/users"</span><span class='o'>)</span> <span class='o'>|&gt;</span> </span>
<span>  <span class='nf'><a href='https://httr2.r-lib.org/reference/req_url.html'>req_url_query</a></span><span class='o'>(</span>name <span class='o'>=</span> <span class='s'>"john-doe"</span><span class='o'>)</span> <span class='o'>|&gt;</span> </span>
<span>  <span class='nf'><a href='https://httr2.r-lib.org/reference/req_get_url.html'>req_get_url</a></span><span class='o'>(</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; [1] "https://api.example.com/users?name=john-doe"</span></span>
<span></span></code></pre>
</div>
<h2 id="improved-debugging-tools">Improved debugging tools
</h2>
<p>The vast majority of modern APIs use JSON, so httr2 now includes a few features to make debugging those APIs a little easier:</p>
<ul>
<li><a href="https://httr2.r-lib.org/reference/last_response.html" target="_blank" rel="noopener"><code>last_request()</code></a>
 and <a href="https://httr2.r-lib.org/reference/last_response.html" target="_blank" rel="noopener"><code>last_response()</code></a>
 are now paired with <a href="https://httr2.r-lib.org/reference/last_response.html" target="_blank" rel="noopener"><code>last_request_json()</code></a>
 and <a href="https://httr2.r-lib.org/reference/last_response.html" target="_blank" rel="noopener"><code>last_response_json()</code></a>
 which pretty-print the JSON bodies of the last request and response.</li>
<li><a href="https://httr2.r-lib.org/reference/req_dry_run.html" target="_blank" rel="noopener"><code>req_dry_run()</code></a>
 and <a href="https://httr2.r-lib.org/reference/req_verbose.html" target="_blank" rel="noopener"><code>req_verbose()</code></a>
 automatically pretty print JSON bodies (turn this off by setting <code>options(httr2_pretty_json = FALSE)</code>).</li>
</ul>
<p>We&rsquo;ve also included a few general tools to make it easier to control httr2&rsquo;s default verbosity. You can now control the default via the <code>HTTR2_VERBOSITY</code> environment variable and there&rsquo;s a new <a href="https://httr2.r-lib.org/reference/with_verbosity.html" target="_blank" rel="noopener"><code>local_verbosity()</code></a>
 function to match the existing <a href="https://httr2.r-lib.org/reference/with_verbosity.html" target="_blank" rel="noopener"><code>with_verbosity()</code></a>
.</p>
<h2 id="quality-of-life-improvements">Quality of life improvements
</h2>
<p>This release also includes a bunch of few smaller quality of life improvements:</p>
<ul>
<li>
<p><a href="https://httr2.r-lib.org/reference/req_perform_parallel.html" target="_blank" rel="noopener"><code>req_perform_parallel()</code></a>
 now lifts many of its restrictions. It now supports simplified versions of <a href="https://httr2.r-lib.org/reference/req_throttle.html" target="_blank" rel="noopener"><code>req_throttle()</code></a>
 and <a href="https://httr2.r-lib.org/reference/req_retry.html" target="_blank" rel="noopener"><code>req_retry()</code></a>
, it can refresh OAuth tokens, and it checks the cache before each request.</p>
</li>
<li>
<p><a href="https://httr2.r-lib.org/reference/req_get_url.html" target="_blank" rel="noopener"><code>req_get_url()</code></a>
, <a href="https://httr2.r-lib.org/reference/req_get_method.html" target="_blank" rel="noopener"><code>req_get_method()</code></a>
, <a href="https://httr2.r-lib.org/reference/req_get_headers.html" target="_blank" rel="noopener"><code>req_get_headers()</code></a>
, <code>req_body_get_type()</code>, and <a href="https://httr2.r-lib.org/reference/req_get_body_type.html" target="_blank" rel="noopener"><code>req_get_body()</code></a>
 allow you to introspect request objects.</p>
</li>
<li>
<p><a href="https://httr2.r-lib.org/reference/req_throttle.html" target="_blank" rel="noopener"><code>req_throttle()</code></a>
 now uses a &ldquo;<a href="https://en.wikipedia.org/wiki/Leaky_bucket" target="_blank" rel="noopener">leaky bucket</a>
&rdquo;. This maintains the same average rate limit as before, while allowing bursts of higher rates.</p>
</li>
<li>
<p><a href="https://httr2.r-lib.org/reference/resp_timing.html" target="_blank" rel="noopener"><code>resp_timing()</code></a>
 exposes detailed timing information for a response.</p>
</li>
</ul>
<h2 id="acknowledgements">Acknowledgements
</h2>
<p>A big thanks to everyone who contributed to this release through issues, pull requests, and discussions on GitHub: <a href="https://github.com/Aariq" target="_blank" rel="noopener">@Aariq</a>
, <a href="https://github.com/annalena13" target="_blank" rel="noopener">@annalena13</a>
, <a href="https://github.com/apsteinmetz" target="_blank" rel="noopener">@apsteinmetz</a>
, <a href="https://github.com/arcresu" target="_blank" rel="noopener">@arcresu</a>
, <a href="https://github.com/arnaudgallou" target="_blank" rel="noopener">@arnaudgallou</a>
, <a href="https://github.com/atheriel" target="_blank" rel="noopener">@atheriel</a>
, <a href="https://github.com/DavidRLovell" target="_blank" rel="noopener">@DavidRLovell</a>
, <a href="https://github.com/dfalbel" target="_blank" rel="noopener">@dfalbel</a>
, <a href="https://github.com/Eli-Berkow" target="_blank" rel="noopener">@Eli-Berkow</a>
, <a href="https://github.com/fwimp" target="_blank" rel="noopener">@fwimp</a>
, <a href="https://github.com/hadley" target="_blank" rel="noopener">@hadley</a>
, <a href="https://github.com/jansim" target="_blank" rel="noopener">@jansim</a>
, <a href="https://github.com/jcheng5" target="_blank" rel="noopener">@jcheng5</a>
, <a href="https://github.com/jeffreyzuber" target="_blank" rel="noopener">@jeffreyzuber</a>
, <a href="https://github.com/jjesusfilho" target="_blank" rel="noopener">@jjesusfilho</a>
, <a href="https://github.com/jonthegeek" target="_blank" rel="noopener">@jonthegeek</a>
, <a href="https://github.com/Kevanness" target="_blank" rel="noopener">@Kevanness</a>
, <a href="https://github.com/m-muecke" target="_blank" rel="noopener">@m-muecke</a>
, <a href="https://github.com/maelle" target="_blank" rel="noopener">@maelle</a>
, <a href="https://github.com/mayeulk" target="_blank" rel="noopener">@mayeulk</a>
, <a href="https://github.com/mdsumner" target="_blank" rel="noopener">@mdsumner</a>
, <a href="https://github.com/noamross" target="_blank" rel="noopener">@noamross</a>
, <a href="https://github.com/omuelle" target="_blank" rel="noopener">@omuelle</a>
, <a href="https://github.com/pedrobtz" target="_blank" rel="noopener">@pedrobtz</a>
, <a href="https://github.com/plietar" target="_blank" rel="noopener">@plietar</a>
, <a href="https://github.com/ramiromagno" target="_blank" rel="noopener">@ramiromagno</a>
, <a href="https://github.com/salim-b" target="_blank" rel="noopener">@salim-b</a>
, <a href="https://github.com/sckott" target="_blank" rel="noopener">@sckott</a>
, <a href="https://github.com/shikokuchuo" target="_blank" rel="noopener">@shikokuchuo</a>
, <a href="https://github.com/vibalre" target="_blank" rel="noopener">@vibalre</a>
, <a href="https://github.com/vladimirobucina" target="_blank" rel="noopener">@vladimirobucina</a>
, and <a href="https://github.com/ZheFrench" target="_blank" rel="noopener">@ZheFrench</a>
.</p>
]]></description>
      <enclosure url="https://posit-open-source.netlify.app/blog/tidyverse/2025/httr2-1-2-0/thumbnail-wd.jpg" length="36992" type="image/jpeg" />
    </item>
    <item>
      <title>Parallel processing in purrr 1.1.0</title>
      <link>https://posit-open-source.netlify.app/blog/tidyverse/2025/purrr-1-1-0-parallel/</link>
      <pubDate>Thu, 10 Jul 2025 00:00:00 +0000</pubDate>
      <guid>https://posit-open-source.netlify.app/blog/tidyverse/2025/purrr-1-1-0-parallel/</guid>
      <dc:creator>Charlie Gao</dc:creator>
      <dc:creator>Hadley Wickham</dc:creator>
      <dc:creator>Davis Vaughan</dc:creator>
      <dc:creator>Lionel Henry</dc:creator><description><![CDATA[<!--
TODO:
* [x] Look over / edit the post's title in the yaml
* [x] Edit (or delete) the description; note this appears in the Twitter card
* [x] Pick category and tags (see existing with [`hugodown::tidy_show_meta()`](https://rdrr.io/pkg/hugodown/man/use_tidy_post.html))
* [x] Find photo & update yaml metadata
* [x] Create `thumbnail-sq.jpg`; height and width should be equal
* [x] Create `thumbnail-wd.jpg`; width should be >5x height
* [x] [`hugodown::use_tidy_thumbnails()`](https://rdrr.io/pkg/hugodown/man/use_tidy_post.html)
* [x] Add intro sentence, e.g. the standard tagline for the package
* [x] [`usethis::use_tidy_thanks()`](https://usethis.r-lib.org/reference/use_tidy_thanks.html)
-->
<p>We&rsquo;re thrilled to announce the release of <a href="https://purrr.tidyverse.org" target="_blank" rel="noopener">purrr</a>
 1.1.0, bringing a game-changing feature to this cornerstone of the tidyverse: <strong>parallel processing</strong>.</p>
<p>For the first time in purrr&rsquo;s history, you can now scale your <code>map()</code> operations across multiple cores and even distributed systems, all while maintaining the elegant, functional programming style you know and love.</p>
<p>This milestone represents more than just a performance boost&mdash;it&rsquo;s a fundamental shift that makes purrr suitable for production-scale data processing tasks without sacrificing the clarity and composability that make it such a joy to use.</p>
<p>Get started by installing purrr 1.1.0 today:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="nf">install.packages</span><span class="p">(</span><span class="s">&#34;purrr&#34;</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>The parallel processing functionality requires the mirai and carrier packages. You will be prompted to install them when you first call <code>in_parallel()</code>.</p>
<p>Ready to supercharge your functional programming workflows? Parallel purrr is here, and it&rsquo;s remarkably simple to use.</p>
<h2 id="the-power-of-in_parallel">The power of <code>in_parallel()</code>
</h2>
<p>The magic happens through a shiny new function: <code>in_parallel()</code>. This purrr adverb wraps your functions to signal that they should run in parallel, powered by the venerable <a href="https://mirai.r-lib.org/" target="_blank" rel="noopener">mirai</a>
 package.</p>
<p>Here&rsquo;s how simple it is to transform your sequential operations:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="nf">library</span><span class="p">(</span><span class="n">purrr</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nf">library</span><span class="p">(</span><span class="n">mirai</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Set up parallel processing (6 background processes)</span>
</span></span><span class="line"><span class="cl"><span class="nf">daemons</span><span class="p">(</span><span class="m">6</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Sequential version</span>
</span></span><span class="line"><span class="cl"><span class="n">mtcars</span> <span class="o">|&gt;</span> <span class="nf">map_dbl</span><span class="p">(</span><span class="nf">\</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="nf">mean</span><span class="p">(</span><span class="n">x</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt;    mpg    cyl   disp     hp   drat     wt   qsec     vs     am   gear   carb </span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt;  20.09   6.19 230.72 146.69   3.60   3.22  17.85   0.44   0.41   3.69   2.81</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Parallel version - just wrap your function with in_parallel()</span>
</span></span><span class="line"><span class="cl"><span class="n">mtcars</span> <span class="o">|&gt;</span> <span class="nf">map_dbl</span><span class="p">(</span><span class="nf">in_parallel</span><span class="p">(</span><span class="nf">\</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="nf">mean</span><span class="p">(</span><span class="n">x</span><span class="p">)))</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt;    mpg    cyl   disp     hp   drat     wt   qsec     vs     am   gear   carb </span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt;  20.09   6.19 230.72 146.69   3.60   3.22  17.85   0.44   0.41   3.69   2.81</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Don&#39;t forget to clean up when done</span>
</span></span><span class="line"><span class="cl"><span class="nf">daemons</span><span class="p">(</span><span class="m">0</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>The results are identical, but the second version distributes the work across multiple CPU cores. For computationally intensive tasks, the performance gains can be dramatic.</p>
<p>The beauty of using an adverb is that <code>in_parallel()</code> works not just with <code>map()</code>, but across the entire purrr ecosystem:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="nf">daemons</span><span class="p">(</span><span class="m">6</span><span class="p">,</span> <span class="n">output</span> <span class="o">=</span> <span class="kc">TRUE</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Works with all map variants</span>
</span></span><span class="line"><span class="cl"><span class="m">1</span><span class="o">:</span><span class="m">4</span> <span class="o">|&gt;</span> <span class="nf">map_int</span><span class="p">(</span><span class="nf">in_parallel</span><span class="p">(</span><span class="nf">\</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="n">x^2</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="m">1</span><span class="o">:</span><span class="m">4</span> <span class="o">|&gt;</span> <span class="nf">map_chr</span><span class="p">(</span><span class="nf">in_parallel</span><span class="p">(</span><span class="nf">\</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="nf">paste</span><span class="p">(</span><span class="s">&#34;Number&#34;</span><span class="p">,</span> <span class="n">x</span><span class="p">)))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Works with map2 and pmap</span>
</span></span><span class="line"><span class="cl"><span class="nf">map2_dbl</span><span class="p">(</span><span class="m">1</span><span class="o">:</span><span class="m">3</span><span class="p">,</span> <span class="m">4</span><span class="o">:</span><span class="m">6</span><span class="p">,</span> <span class="nf">in_parallel</span><span class="p">(</span><span class="nf">\</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">)</span> <span class="n">x</span> <span class="o">+</span> <span class="n">y</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nf">list</span><span class="p">(</span><span class="n">a</span> <span class="o">=</span> <span class="m">1</span><span class="o">:</span><span class="m">3</span><span class="p">,</span> <span class="n">b</span> <span class="o">=</span> <span class="m">4</span><span class="o">:</span><span class="m">6</span><span class="p">,</span> <span class="n">c</span> <span class="o">=</span> <span class="m">7</span><span class="o">:</span><span class="m">9</span><span class="p">)</span> <span class="o">|&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nf">pmap_dbl</span><span class="p">(</span><span class="nf">in_parallel</span><span class="p">(</span><span class="nf">\</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">c</span><span class="p">)</span> <span class="nf">mean</span><span class="p">(</span><span class="nf">c</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">c</span><span class="p">))))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Even works with walk for side effects</span>
</span></span><span class="line"><span class="cl"><span class="m">1</span><span class="o">:</span><span class="m">3</span> <span class="o">|&gt;</span> <span class="nf">walk</span><span class="p">(</span><span class="nf">in_parallel</span><span class="p">(</span><span class="nf">\</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="nf">cat</span><span class="p">(</span><span class="s">&#34;Processing&#34;</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="s">&#34;\n&#34;</span><span class="p">)))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nf">daemons</span><span class="p">(</span><span class="m">0</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>If you use <code>in_parallel()</code> but don&rsquo;t set <code>daemons()</code>, then the map will just proceed sequentially, so you don&rsquo;t need to worry about having two separate code paths for parallel vs non-parallel execution.</p>
<h2 id="real-world-example-parallel-model-fitting">Real-world example: parallel model fitting
</h2>
<p>Let&rsquo;s look at a more realistic scenario where parallel processing truly shines&mdash;fitting multiple models:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="nf">library</span><span class="p">(</span><span class="n">purrr</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nf">library</span><span class="p">(</span><span class="n">mirai</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Set up 4 parallel processes</span>
</span></span><span class="line"><span class="cl"><span class="nf">daemons</span><span class="p">(</span><span class="m">4</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Define a slow model fitting function</span>
</span></span><span class="line"><span class="cl"><span class="n">slow_lm</span> <span class="o">&lt;-</span> <span class="kr">function</span><span class="p">(</span><span class="n">formula</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nf">Sys.sleep</span><span class="p">(</span><span class="m">0.1</span><span class="p">)</span>  <span class="c1"># Simulate computational complexity</span>
</span></span><span class="line"><span class="cl">  <span class="nf">lm</span><span class="p">(</span><span class="n">formula</span><span class="p">,</span> <span class="n">data</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Fit models to different subsets of data in parallel</span>
</span></span><span class="line"><span class="cl"><span class="n">models</span> <span class="o">&lt;-</span> <span class="n">mtcars</span> <span class="o">|&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nf">split</span><span class="p">(</span><span class="n">mtcars</span><span class="o">$</span><span class="n">cyl</span><span class="p">)</span> <span class="o">|&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nf">map</span><span class="p">(</span><span class="nf">in_parallel</span><span class="p">(</span><span class="nf">\</span><span class="p">(</span><span class="n">df</span><span class="p">)</span> <span class="nf">slow_lm</span><span class="p">(</span><span class="n">mpg</span> <span class="o">~</span> <span class="n">wt</span> <span class="o">+</span> <span class="n">hp</span><span class="p">,</span> <span class="n">data</span> <span class="o">=</span> <span class="n">df</span><span class="p">),</span> <span class="n">slow_lm</span> <span class="o">=</span> <span class="n">slow_lm</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Extract R-squared values</span>
</span></span><span class="line"><span class="cl"><span class="n">models</span> <span class="o">|&gt;</span> 
</span></span><span class="line"><span class="cl">  <span class="nf">map</span><span class="p">(</span><span class="n">summary</span><span class="p">)</span> <span class="o">|&gt;</span> 
</span></span><span class="line"><span class="cl">  <span class="nf">map_dbl</span><span class="p">(</span><span class="s">&#34;r.squared&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt;         4         6         8 </span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; 0.6807065 0.5889239 0.4970692</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nf">daemons</span><span class="p">(</span><span class="m">0</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>Notice how we pass the <code>slow_lm</code> function as an argument to <code>in_parallel()</code>&mdash;this ensures our custom function is available in the parallel processes.</p>
<h2 id="production-ready-with-mirai">Production-ready with mirai
</h2>
<p>The choice of <a href="https://mirai.r-lib.org" target="_blank" rel="noopener">mirai</a>
 as the parallel backend wasn&rsquo;t arbitrary. <a href="https://mirai.r-lib.org" target="_blank" rel="noopener">mirai</a>
 is a production-grade async evaluation framework that brings several key advantages:</p>
<ul>
<li><strong>Minimal overhead</strong>: Built on modern networking and concurrency principles</li>
<li><strong>Reliable scheduling</strong>: Leveraging fast inter-process communications locally</li>
<li><strong>Scalable architecture</strong>: From multi-process to distributed computing on HPC clusters</li>
<li><strong>Security</strong>: Offers zero-configuration TLS over TCP for additional assurance</li>
</ul>
<p>This means your parallel purrr code isn&rsquo;t just fast&mdash;it&rsquo;s production-ready.</p>
<p>Compared to the <a href="https://furrr.futureverse.org" target="_blank" rel="noopener">furrr</a>
 package:</p>
<ul>
<li>Much lower overhead means you can get a performance boost even for relatively fast functions</li>
<li>More linear scaling means you get the same benefits whether you&rsquo;re running on 2 or 200 cores</li>
</ul>
<p>We&rsquo;ve learned a lot from our work on furrr, and from <a href="https://github.com/henrikbengtsson" target="_blank" rel="noopener">Henrik Bengtsson</a>
&rsquo;s excellent work on the <a href="https://github.com/futureverse" target="_blank" rel="noopener">futureverse</a>
 ecosystem. purrr doesn&rsquo;t use future as the underlying engine for parallelism because we&rsquo;ve made some design decisions that differ at a fundamental level, but Henrik&rsquo;s entire ecosystem deserves credit for pushing the boundaries of parallelism in R farther than many thought possible.</p>
<h2 id="creating-self-contained-functions">Creating self-contained functions
</h2>
<p>One of the key concepts when using <code>in_parallel()</code> is creating self-contained functions. Since your function gets serialized and sent to parallel processes, it needs to be completely standalone:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="c1"># ❌ This won&#39;t work - external dependencies not declared</span>
</span></span><span class="line"><span class="cl"><span class="n">my_data</span> <span class="o">&lt;-</span> <span class="nf">c</span><span class="p">(</span><span class="m">1</span><span class="p">,</span> <span class="m">2</span><span class="p">,</span> <span class="m">3</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nf">map</span><span class="p">(</span><span class="m">1</span><span class="o">:</span><span class="m">3</span><span class="p">,</span> <span class="nf">in_parallel</span><span class="p">(</span><span class="nf">\</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="nf">mean</span><span class="p">(</span><span class="n">my_data</span><span class="p">)))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># ✅ This works - dependencies explicitly provided</span>
</span></span><span class="line"><span class="cl"><span class="n">my_data</span> <span class="o">&lt;-</span> <span class="nf">c</span><span class="p">(</span><span class="m">1</span><span class="p">,</span> <span class="m">2</span><span class="p">,</span> <span class="m">3</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nf">map</span><span class="p">(</span><span class="m">1</span><span class="o">:</span><span class="m">3</span><span class="p">,</span> <span class="nf">in_parallel</span><span class="p">(</span><span class="nf">\</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="nf">mean</span><span class="p">(</span><span class="n">my_data</span><span class="p">),</span> <span class="n">my_data</span> <span class="o">=</span> <span class="n">my_data</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># ✅ Package functions need explicit namespacing</span>
</span></span><span class="line"><span class="cl"><span class="nf">map</span><span class="p">(</span><span class="m">1</span><span class="o">:</span><span class="m">3</span><span class="p">,</span> <span class="nf">in_parallel</span><span class="p">(</span><span class="nf">\</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="n">vctrs</span><span class="o">::</span><span class="nf">vec_init</span><span class="p">(</span><span class="nf">integer</span><span class="p">(),</span> <span class="n">x</span><span class="p">)))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># ✅ Or load packages within the function</span>
</span></span><span class="line"><span class="cl"><span class="nf">map</span><span class="p">(</span><span class="m">1</span><span class="o">:</span><span class="m">3</span><span class="p">,</span> <span class="nf">in_parallel</span><span class="p">(</span><span class="nf">\</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nf">library</span><span class="p">(</span><span class="n">vctrs</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="nf">vec_init</span><span class="p">(</span><span class="nf">integer</span><span class="p">(),</span> <span class="n">x</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">}))</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>This explicit dependency management might seem verbose, but it ensures your parallel code is reliable and predictable&mdash;crucial for production environments.</p>
<p>It also removes the danger of accidentally shipping large objects to parallel processes&mdash;often a source of performance degradation.</p>
<h2 id="when-to-use-parallel-processing">When to use parallel processing
</h2>
<p>Not every <code>map()</code> operation benefits from parallelization. The overhead of setting up parallel tasks and communicating between processes can outweigh the benefits for simple operations. As a rule of thumb, consider parallel processing when:</p>
<ul>
<li>Each iteration takes at least 100 microseconds to 1 millisecond</li>
<li>You&rsquo;re performing CPU-intensive computations</li>
<li>You&rsquo;re working with I/O-bound operations that can benefit from concurrency</li>
<li>The data being passed between processes isn&rsquo;t excessively large</li>
</ul>
<p>For quick operations like simple arithmetic, sequential processing will often be faster.</p>
<p>If you&rsquo;re a package developer, use <code>in_parallel()</code> where you see fit, but please be mindful not to call <code>daemons()</code> within your package code. How to set mirai daemons should be always be for the end user to decide.</p>
<h2 id="distributed-computing-made-simple">Distributed computing made simple
</h2>
<p>Want to scale beyond your local machine? mirai&rsquo;s networking capabilities make distributed computing surprisingly straightforward:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="nf">library</span><span class="p">(</span><span class="n">mirai</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Set up remote daemons on a Slurm HPC cluster</span>
</span></span><span class="line"><span class="cl"><span class="nf">daemons</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">  <span class="n">n</span> <span class="o">=</span> <span class="m">100</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="n">url</span> <span class="o">=</span> <span class="nf">host_url</span><span class="p">(),</span>
</span></span><span class="line"><span class="cl">  <span class="n">remote</span> <span class="o">=</span> <span class="nf">cluster_config</span><span class="p">(</span><span class="n">command</span> <span class="o">=</span> <span class="s">&#34;sbatch&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Your purrr code remains exactly the same!</span>
</span></span><span class="line"><span class="cl"><span class="n">results</span> <span class="o">&lt;-</span> <span class="n">big_dataset</span> <span class="o">|&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nf">split</span><span class="p">(</span><span class="n">big_dataset</span><span class="o">$</span><span class="n">group</span><span class="p">)</span> <span class="o">|&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nf">map</span><span class="p">(</span><span class="nf">in_parallel</span><span class="p">(</span><span class="nf">\</span><span class="p">(</span><span class="n">df</span><span class="p">)</span> <span class="nf">complex_analysis</span><span class="p">(</span><span class="n">df</span><span class="p">),</span> <span class="n">complex_analysis</span> <span class="o">=</span> <span class="n">complex_analysis</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nf">daemons</span><span class="p">(</span><span class="m">0</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>The same <code>in_parallel()</code> syntax that works locally scales seamlessly to distributed systems.</p>
<p>Please refer to the mirai documentation on <a href="https://mirai.r-lib.org/articles/mirai.html#remote-daemons" target="_blank" rel="noopener">remote daemons</a>
 and <a href="https://mirai.r-lib.org/articles/mirai.html#launching-remote-daemons" target="_blank" rel="noopener">launching remote daemons</a>
 for more details. This <a href="https://shikokuchuo.net/posts/27-mirai-240/" target="_blank" rel="noopener">mirai blog post</a>
 will also be useful if you&rsquo;re working with High-Performance Computing (HPC) clusters.</p>
<h2 id="looking-forward">Looking forward
</h2>
<p>The addition of parallel processing to purrr 1.1.0 represents a significant evolution in the package&rsquo;s capabilities. It maintains purrr&rsquo;s core philosophy of functional programming while opening doors to high-performance computing scenarios that were previously challenging to achieve with such clean, readable code.</p>
<p>This feature is currently marked as experimental as we gather feedback from the community, but the underlying mirai infrastructure is production-proven and battle-tested. We encourage you to try it out and let us know about your experiences.</p>
<p>Whether you&rsquo;re processing large datasets, fitting complex models, or running simulations, purrr 1.1.0&rsquo;s parallel processing capabilities can help you scale your R workflows without sacrificing code clarity or reliability.</p>
<h2 id="acknowledgements">Acknowledgements
</h2>
<p>A big thanks to all those who posted issues and contributed PRs since our last release! <a href="https://github.com/ar-puuk" target="_blank" rel="noopener">@ar-puuk</a>
, <a href="https://github.com/DanChaltiel" target="_blank" rel="noopener">@DanChaltiel</a>
, <a href="https://github.com/davidrsch" target="_blank" rel="noopener">@davidrsch</a>
, <a href="https://github.com/ErdaradunGaztea" target="_blank" rel="noopener">@ErdaradunGaztea</a>
, <a href="https://github.com/h-a-graham" target="_blank" rel="noopener">@h-a-graham</a>
, <a href="https://github.com/hadley" target="_blank" rel="noopener">@hadley</a>
, <a href="https://github.com/HenningLorenzen-ext-bayer" target="_blank" rel="noopener">@HenningLorenzen-ext-bayer</a>
, <a href="https://github.com/krivit" target="_blank" rel="noopener">@krivit</a>
, <a href="https://github.com/MarceloRTonon" target="_blank" rel="noopener">@MarceloRTonon</a>
, <a href="https://github.com/MarkPaulin" target="_blank" rel="noopener">@MarkPaulin</a>
, <a href="https://github.com/salim-b" target="_blank" rel="noopener">@salim-b</a>
, <a href="https://github.com/ScientiaFelis" target="_blank" rel="noopener">@ScientiaFelis</a>
, <a href="https://github.com/shikokuchuo" target="_blank" rel="noopener">@shikokuchuo</a>
, and <a href="https://github.com/sierrajohnson" target="_blank" rel="noopener">@sierrajohnson</a>
.</p>
]]></description>
      <enclosure url="https://posit-open-source.netlify.app/blog/tidyverse/2025/purrr-1-1-0-parallel/thumbnail-wd.jpg" length="499574" type="image/jpeg" />
    </item>
    <item>
      <title>duckplyr fully joins the tidyverse!</title>
      <link>https://posit-open-source.netlify.app/blog/tidyverse/2025/duckplyr-1-1-0/</link>
      <pubDate>Thu, 19 Jun 2025 00:00:00 +0000</pubDate>
      <guid>https://posit-open-source.netlify.app/blog/tidyverse/2025/duckplyr-1-1-0/</guid>
      <dc:creator>Kirill Müller</dc:creator>
      <dc:creator>Maëlle Salmon</dc:creator><description><![CDATA[<p>We&rsquo;re well chuffed to announce the release of <a href="https://duckplyr.tidyverse.org" target="_blank" rel="noopener">duckplyr</a>
 1.1.0. This is a dplyr backend powered by <a href="https://duckdb.org/" target="_blank" rel="noopener">DuckDB</a>
, a fast in-memory analytical database system<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>. duckplyr uses the power of DuckDB for impressive performance where it can, and seemlessly falls back to R where it can&rsquo;t. You can install it from CRAN with:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nf'><a href='https://rdrr.io/r/utils/install.packages.html'>install.packages</a></span><span class='o'>(</span><span class='s'>"duckplyr"</span><span class='o'>)</span></span></code></pre>
</div>
<p>This article shows how duckplyr can be used instead of dplyr, explain how you can help improve the package, and share a selection of further resources.</p>
<h2 id="a-drop-in-replacement-for-dplyr">A drop-in replacement for dplyr
</h2>
<p>Imagine you have to wrangle a huge dataset, like this one from the <a href="https://duckdb.org/2024/04/02/duckplyr.html#benchmark-tpc-h-q1" target="_blank" rel="noopener">TPC-H benchmark</a>
, a famous database benchmarking dataset.</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>lineitem_tbl</span> <span class='o'>&lt;-</span> <span class='nf'>duckdb</span><span class='nf'>:::</span><span class='nf'>sql</span><span class='o'>(</span><span class='s'>"INSTALL tpch; LOAD tpch; CALL dbgen(sf=1); FROM lineitem;"</span><span class='o'>)</span></span>
<span><span class='nv'>lineitem_tbl</span> <span class='o'>&lt;-</span> <span class='nf'>tibble</span><span class='nf'>::</span><span class='nf'><a href='https://tibble.tidyverse.org/reference/as_tibble.html'>as_tibble</a></span><span class='o'>(</span><span class='nv'>lineitem_tbl</span><span class='o'>)</span></span>
<span><span class='nf'>dplyr</span><span class='nf'>::</span><span class='nf'><a href='https://pillar.r-lib.org/reference/glimpse.html'>glimpse</a></span><span class='o'>(</span><span class='nv'>lineitem_tbl</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; Rows: 6,001,215</span></span>
<span><span class='c'>#&gt; Columns: 16</span></span>
<span><span class='c'>#&gt; $ <span style='font-weight: bold;'>l_orderkey     </span> <span style='color: #555555; font-style: italic;'>&lt;dbl&gt;</span> 1<span style='color: #555555;'>, </span>1<span style='color: #555555;'>, </span>1<span style='color: #555555;'>, </span>1<span style='color: #555555;'>, </span>1<span style='color: #555555;'>, </span>1<span style='color: #555555;'>, </span>2<span style='color: #555555;'>, </span>3<span style='color: #555555;'>, </span>3<span style='color: #555555;'>, </span>3<span style='color: #555555;'>, </span>3<span style='color: #555555;'>, </span>3<span style='color: #555555;'>, </span>3<span style='color: #555555;'>, </span>4<span style='color: #555555;'>, </span>5<span style='color: #555555;'>, </span>5<span style='color: #555555;'>, </span>5<span style='color: #555555;'>, </span>6<span style='color: #555555;'>, </span>…</span></span>
<span><span class='c'>#&gt; $ <span style='font-weight: bold;'>l_partkey      </span> <span style='color: #555555; font-style: italic;'>&lt;dbl&gt;</span> 155190<span style='color: #555555;'>, </span>67310<span style='color: #555555;'>, </span>63700<span style='color: #555555;'>, </span>2132<span style='color: #555555;'>, </span>24027<span style='color: #555555;'>, </span>15635<span style='color: #555555;'>, </span>106170<span style='color: #555555;'>, </span>4297…</span></span>
<span><span class='c'>#&gt; $ <span style='font-weight: bold;'>l_suppkey      </span> <span style='color: #555555; font-style: italic;'>&lt;dbl&gt;</span> 7706<span style='color: #555555;'>, </span>7311<span style='color: #555555;'>, </span>3701<span style='color: #555555;'>, </span>4633<span style='color: #555555;'>, </span>1534<span style='color: #555555;'>, </span>638<span style='color: #555555;'>, </span>1191<span style='color: #555555;'>, </span>1798<span style='color: #555555;'>, </span>6540<span style='color: #555555;'>, </span>3…</span></span>
<span><span class='c'>#&gt; $ <span style='font-weight: bold;'>l_linenumber   </span> <span style='color: #555555; font-style: italic;'>&lt;dbl&gt;</span> 1<span style='color: #555555;'>, </span>2<span style='color: #555555;'>, </span>3<span style='color: #555555;'>, </span>4<span style='color: #555555;'>, </span>5<span style='color: #555555;'>, </span>6<span style='color: #555555;'>, </span>1<span style='color: #555555;'>, </span>1<span style='color: #555555;'>, </span>2<span style='color: #555555;'>, </span>3<span style='color: #555555;'>, </span>4<span style='color: #555555;'>, </span>5<span style='color: #555555;'>, </span>6<span style='color: #555555;'>, </span>1<span style='color: #555555;'>, </span>1<span style='color: #555555;'>, </span>2<span style='color: #555555;'>, </span>3<span style='color: #555555;'>, </span>1<span style='color: #555555;'>, </span>…</span></span>
<span><span class='c'>#&gt; $ <span style='font-weight: bold;'>l_quantity     </span> <span style='color: #555555; font-style: italic;'>&lt;dbl&gt;</span> 17<span style='color: #555555;'>, </span>36<span style='color: #555555;'>, </span>8<span style='color: #555555;'>, </span>28<span style='color: #555555;'>, </span>24<span style='color: #555555;'>, </span>32<span style='color: #555555;'>, </span>38<span style='color: #555555;'>, </span>45<span style='color: #555555;'>, </span>49<span style='color: #555555;'>, </span>27<span style='color: #555555;'>, </span>2<span style='color: #555555;'>, </span>28<span style='color: #555555;'>, </span>26<span style='color: #555555;'>, </span>30<span style='color: #555555;'>, </span>…</span></span>
<span><span class='c'>#&gt; $ <span style='font-weight: bold;'>l_extendedprice</span> <span style='color: #555555; font-style: italic;'>&lt;dbl&gt;</span> 21168.23<span style='color: #555555;'>, </span>45983.16<span style='color: #555555;'>, </span>13309.60<span style='color: #555555;'>, </span>28955.64<span style='color: #555555;'>, </span>22824.48<span style='color: #555555;'>, </span>4962…</span></span>
<span><span class='c'>#&gt; $ <span style='font-weight: bold;'>l_discount     </span> <span style='color: #555555; font-style: italic;'>&lt;dbl&gt;</span> 0.04<span style='color: #555555;'>, </span>0.09<span style='color: #555555;'>, </span>0.10<span style='color: #555555;'>, </span>0.09<span style='color: #555555;'>, </span>0.10<span style='color: #555555;'>, </span>0.07<span style='color: #555555;'>, </span>0.00<span style='color: #555555;'>, </span>0.06<span style='color: #555555;'>, </span>0.10<span style='color: #555555;'>, </span>…</span></span>
<span><span class='c'>#&gt; $ <span style='font-weight: bold;'>l_tax          </span> <span style='color: #555555; font-style: italic;'>&lt;dbl&gt;</span> 0.02<span style='color: #555555;'>, </span>0.06<span style='color: #555555;'>, </span>0.02<span style='color: #555555;'>, </span>0.06<span style='color: #555555;'>, </span>0.04<span style='color: #555555;'>, </span>0.02<span style='color: #555555;'>, </span>0.05<span style='color: #555555;'>, </span>0.00<span style='color: #555555;'>, </span>0.00<span style='color: #555555;'>, </span>…</span></span>
<span><span class='c'>#&gt; $ <span style='font-weight: bold;'>l_returnflag   </span> <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span> "N"<span style='color: #555555;'>, </span>"N"<span style='color: #555555;'>, </span>"N"<span style='color: #555555;'>, </span>"N"<span style='color: #555555;'>, </span>"N"<span style='color: #555555;'>, </span>"N"<span style='color: #555555;'>, </span>"N"<span style='color: #555555;'>, </span>"R"<span style='color: #555555;'>, </span>"R"<span style='color: #555555;'>, </span>"A"<span style='color: #555555;'>, </span>"A"<span style='color: #555555;'>,</span>…</span></span>
<span><span class='c'>#&gt; $ <span style='font-weight: bold;'>l_linestatus   </span> <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span> "O"<span style='color: #555555;'>, </span>"O"<span style='color: #555555;'>, </span>"O"<span style='color: #555555;'>, </span>"O"<span style='color: #555555;'>, </span>"O"<span style='color: #555555;'>, </span>"O"<span style='color: #555555;'>, </span>"O"<span style='color: #555555;'>, </span>"F"<span style='color: #555555;'>, </span>"F"<span style='color: #555555;'>, </span>"F"<span style='color: #555555;'>, </span>"F"<span style='color: #555555;'>,</span>…</span></span>
<span><span class='c'>#&gt; $ <span style='font-weight: bold;'>l_shipdate     </span> <span style='color: #555555; font-style: italic;'>&lt;date&gt;</span> 1996-03-13<span style='color: #555555;'>, </span>1996-04-12<span style='color: #555555;'>, </span>1996-01-29<span style='color: #555555;'>, </span>1996-04-21<span style='color: #555555;'>, </span>1996-…</span></span>
<span><span class='c'>#&gt; $ <span style='font-weight: bold;'>l_commitdate   </span> <span style='color: #555555; font-style: italic;'>&lt;date&gt;</span> 1996-02-12<span style='color: #555555;'>, </span>1996-02-28<span style='color: #555555;'>, </span>1996-03-05<span style='color: #555555;'>, </span>1996-03-30<span style='color: #555555;'>, </span>1996-…</span></span>
<span><span class='c'>#&gt; $ <span style='font-weight: bold;'>l_receiptdate  </span> <span style='color: #555555; font-style: italic;'>&lt;date&gt;</span> 1996-03-22<span style='color: #555555;'>, </span>1996-04-20<span style='color: #555555;'>, </span>1996-01-31<span style='color: #555555;'>, </span>1996-05-16<span style='color: #555555;'>, </span>1996-…</span></span>
<span><span class='c'>#&gt; $ <span style='font-weight: bold;'>l_shipinstruct </span> <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span> "DELIVER IN PERSON"<span style='color: #555555;'>, </span>"TAKE BACK RETURN"<span style='color: #555555;'>, </span>"TAKE BACK RE…</span></span>
<span><span class='c'>#&gt; $ <span style='font-weight: bold;'>l_shipmode     </span> <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span> "TRUCK"<span style='color: #555555;'>, </span>"MAIL"<span style='color: #555555;'>, </span>"REG AIR"<span style='color: #555555;'>, </span>"AIR"<span style='color: #555555;'>, </span>"FOB"<span style='color: #555555;'>, </span>"MAIL"<span style='color: #555555;'>, </span>"RAI…</span></span>
<span><span class='c'>#&gt; $ <span style='font-weight: bold;'>l_comment      </span> <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span> "to beans x-ray carefull"<span style='color: #555555;'>, </span>" according to the final fo…</span></span>
<span></span></code></pre>
</div>
<p>To work with this in duckplyr instead of dplyr, all you need to do is load duckplyr:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='kr'><a href='https://rdrr.io/r/base/library.html'>library</a></span><span class='o'>(</span><span class='nv'><a href='https://duckplyr.tidyverse.org'>duckplyr</a></span><span class='o'>)</span></span>
<span><span class='c'>#&gt; Loading required package: dplyr</span></span>
<span></span><span><span class='c'>#&gt; The <span style='color: #0000BB;'>duckplyr</span> package is configured to fall back to <span style='color: #0000BB;'>dplyr</span> when it encounters an incompatibility.</span></span>
<span><span class='c'>#&gt; Fallback events can be collected and uploaded for analysis to guide future development. By</span></span>
<span><span class='c'>#&gt; default, data will be collected but no data will be uploaded.</span></span>
<span><span class='c'>#&gt; <span style='color: #00BBBB;'>ℹ</span> Automatic fallback uploading is not controlled and therefore disabled, see</span></span>
<span><span class='c'>#&gt;   `?duckplyr::fallback()`.</span></span>
<span><span class='c'>#&gt; <span style='color: #00BB00;'>✔</span> Number of reports ready for upload: <span style='font-weight: bold;'>4</span>.</span></span>
<span><span class='c'>#&gt; → Review with `duckplyr::fallback_review()`, upload with `duckplyr::fallback_upload()`.</span></span>
<span><span class='c'>#&gt; <span style='color: #00BBBB;'>ℹ</span> <span style='color: #555555;'>Configure automatic uploading with `duckplyr::fallback_config()`.</span></span></span>
<span></span><span><span class='c'>#&gt; <span style='color: #00BB00;'>✔</span> Overwriting <span style='color: #0000BB;'>dplyr</span> methods with <span style='color: #0000BB;'>duckplyr</span> methods.</span></span>
<span><span class='c'>#&gt; <span style='color: #00BBBB;'>ℹ</span> Turn off with `duckplyr::methods_restore()`.</span></span>
<span></span></code></pre>
</div>
<p>Now we can express the well-known (at least in the database community!) &ldquo;TPC-H benchmark query 1&rdquo; in dplyr syntax and execute it in DuckDB via duckplyr.</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>tpch_dplyr</span> <span class='o'>&lt;-</span> <span class='kr'>function</span><span class='o'>(</span><span class='nv'>lineitem</span><span class='o'>)</span> <span class='o'>&#123;</span></span>
<span>  <span class='nv'>lineitem</span> <span class='o'>|&gt;</span></span>
<span>    <span class='nf'><a href='https://dplyr.tidyverse.org/reference/filter.html'>filter</a></span><span class='o'>(</span><span class='nv'>l_shipdate</span> <span class='o'>&lt;=</span> <span class='o'>!</span><span class='o'>!</span><span class='nf'><a href='https://rdrr.io/r/base/as.Date.html'>as.Date</a></span><span class='o'>(</span><span class='s'>"1998-09-02"</span><span class='o'>)</span><span class='o'>)</span> <span class='o'>|&gt;</span></span>
<span>    <span class='nf'><a href='https://dplyr.tidyverse.org/reference/summarise.html'>summarise</a></span><span class='o'>(</span></span>
<span>      sum_qty <span class='o'>=</span> <span class='nf'><a href='https://rdrr.io/r/base/sum.html'>sum</a></span><span class='o'>(</span><span class='nv'>l_quantity</span><span class='o'>)</span>,</span>
<span>      sum_base_price <span class='o'>=</span> <span class='nf'><a href='https://rdrr.io/r/base/sum.html'>sum</a></span><span class='o'>(</span><span class='nv'>l_extendedprice</span><span class='o'>)</span>,</span>
<span>      sum_disc_price <span class='o'>=</span> <span class='nf'><a href='https://rdrr.io/r/base/sum.html'>sum</a></span><span class='o'>(</span><span class='nv'>l_extendedprice</span> <span class='o'>*</span> <span class='o'>(</span><span class='m'>1</span> <span class='o'>-</span> <span class='nv'>l_discount</span><span class='o'>)</span><span class='o'>)</span>,</span>
<span>      sum_charge <span class='o'>=</span> <span class='nf'><a href='https://rdrr.io/r/base/sum.html'>sum</a></span><span class='o'>(</span><span class='nv'>l_extendedprice</span> <span class='o'>*</span> <span class='o'>(</span><span class='m'>1</span> <span class='o'>-</span> <span class='nv'>l_discount</span><span class='o'>)</span> <span class='o'>*</span> <span class='o'>(</span><span class='m'>1</span> <span class='o'>+</span> <span class='nv'>l_tax</span><span class='o'>)</span><span class='o'>)</span>,</span>
<span>      avg_qty <span class='o'>=</span> <span class='nf'><a href='https://rdrr.io/r/base/mean.html'>mean</a></span><span class='o'>(</span><span class='nv'>l_quantity</span><span class='o'>)</span>,</span>
<span>      avg_price <span class='o'>=</span> <span class='nf'><a href='https://rdrr.io/r/base/mean.html'>mean</a></span><span class='o'>(</span><span class='nv'>l_extendedprice</span><span class='o'>)</span>,</span>
<span>      avg_disc <span class='o'>=</span> <span class='nf'><a href='https://rdrr.io/r/base/mean.html'>mean</a></span><span class='o'>(</span><span class='nv'>l_discount</span><span class='o'>)</span>,</span>
<span>      count_order <span class='o'>=</span> <span class='nf'><a href='https://dplyr.tidyverse.org/reference/context.html'>n</a></span><span class='o'>(</span><span class='o'>)</span>,</span>
<span>      .by <span class='o'>=</span> <span class='nf'><a href='https://rdrr.io/r/base/c.html'>c</a></span><span class='o'>(</span><span class='nv'>l_returnflag</span>, <span class='nv'>l_linestatus</span><span class='o'>)</span></span>
<span>    <span class='o'>)</span> <span class='o'>|&gt;</span></span>
<span>    <span class='nf'><a href='https://dplyr.tidyverse.org/reference/arrange.html'>arrange</a></span><span class='o'>(</span><span class='nv'>l_returnflag</span>, <span class='nv'>l_linestatus</span><span class='o'>)</span></span>
<span><span class='o'>&#125;</span></span>
<span></span>
<span><span class='nf'>tpch_dplyr</span><span class='o'>(</span><span class='nv'>lineitem_tbl</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># A tibble: 4 × 10</span></span></span>
<span><span class='c'>#&gt;   <span style='font-weight: bold;'>l_returnflag</span> <span style='font-weight: bold;'>l_linestatus</span>  <span style='font-weight: bold;'>sum_qty</span> <span style='font-weight: bold;'>sum_base_price</span> <span style='font-weight: bold;'>sum_disc_price</span>    <span style='font-weight: bold;'>sum_charge</span></span></span>
<span><span class='c'>#&gt;   <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>        <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>           <span style='color: #555555; font-style: italic;'>&lt;dbl&gt;</span>          <span style='color: #555555; font-style: italic;'>&lt;dbl&gt;</span>          <span style='color: #555555; font-style: italic;'>&lt;dbl&gt;</span>         <span style='color: #555555; font-style: italic;'>&lt;dbl&gt;</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>1</span> A            F            37<span style='text-decoration: underline;'>734</span>107   <span style='text-decoration: underline;'>56</span>586<span style='text-decoration: underline;'>554</span>401.   <span style='text-decoration: underline;'>53</span>758<span style='text-decoration: underline;'>257</span>135.  <span style='text-decoration: underline;'>55</span>909<span style='text-decoration: underline;'>065</span>223.</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>2</span> N            F              <span style='text-decoration: underline;'>991</span>417    <span style='text-decoration: underline;'>1</span>487<span style='text-decoration: underline;'>504</span>710.    <span style='text-decoration: underline;'>1</span>413<span style='text-decoration: underline;'>082</span>168.   <span style='text-decoration: underline;'>1</span>469<span style='text-decoration: underline;'>649</span>223.</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>3</span> N            O            74<span style='text-decoration: underline;'>476</span>040  <span style='text-decoration: underline;'>111</span>701<span style='text-decoration: underline;'>729</span>698.  <span style='text-decoration: underline;'>106</span>118<span style='text-decoration: underline;'>230</span>308. <span style='text-decoration: underline;'>110</span>367<span style='text-decoration: underline;'>043</span>872.</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>4</span> R            F            37<span style='text-decoration: underline;'>719</span>753   <span style='text-decoration: underline;'>56</span>568<span style='text-decoration: underline;'>041</span>381.   <span style='text-decoration: underline;'>53</span>741<span style='text-decoration: underline;'>292</span>685.  <span style='text-decoration: underline;'>55</span>889<span style='text-decoration: underline;'>619</span>120.</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># ℹ 4 more variables: </span><span style='color: #555555; font-weight: bold;'>avg_qty</span><span style='color: #555555;'> &lt;dbl&gt;, </span><span style='color: #555555; font-weight: bold;'>avg_price</span><span style='color: #555555;'> &lt;dbl&gt;, </span><span style='color: #555555; font-weight: bold;'>avg_disc</span><span style='color: #555555;'> &lt;dbl&gt;,</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>#   </span><span style='color: #555555; font-weight: bold;'>count_order</span><span style='color: #555555;'> &lt;int&gt;</span></span></span>
<span></span></code></pre>
</div>
<p>Like other dplyr backends such as dtplyr and dbplyr, duckplyr gives you higher performance without learning a different syntax. Unlike other dplyr backends, duckplyr does not require you to change existing code or learn specific idiosyncrasies. Not only is the syntax the same, the semantics are too! If an operation cannot be carried out with DuckDB, it is automatically outsourced to dplyr. Over time, we expect fewer and fewer fallbacks to dplyr to be needed.</p>
<h2 id="how-to-use-duckplyr">How to use duckplyr
</h2>
<p>There are two ways to use duckplyr:</p>
<ul>
<li>
<p>As above, you can <a href="https://duckplyr.tidyverse.org" target="_blank" rel="noopener"><code>library(duckplyr)</code></a>
, and replace all existing dplyr methods. This is safe because duckplyr is guaranteed to give the exactly same the results as dplyr, unlike other backends.</p>
</li>
<li>
<p>Create individual &ldquo;duck frames&rdquo; using <em>conversion functions</em> like <code>duckdplyr::duckdb_tibble()</code> or <code>duckdplyr::as_duckdb_tibble()</code>, or <em>ingestion functions</em> like <code>duckdplyr::read_csv_duckdb()</code>.</p>
</li>
</ul>
<p>Here&rsquo;s an example of the second form:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>out</span> <span class='o'>&lt;-</span> <span class='nv'>lineitem_tbl</span> <span class='o'>|&gt;</span></span>
<span>  <span class='nf'>duckplyr</span><span class='nf'>::</span><span class='nf'><a href='https://duckplyr.tidyverse.org/reference/duckdb_tibble.html'>as_duckdb_tibble</a></span><span class='o'>(</span><span class='o'>)</span> <span class='o'>|&gt;</span></span>
<span>  <span class='nf'>tpch_dplyr</span><span class='o'>(</span><span class='o'>)</span></span>
<span></span>
<span><span class='nv'>out</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># A duckplyr data frame: 10 variables</span></span></span>
<span><span class='c'>#&gt;   <span style='font-weight: bold;'>l_returnflag</span> <span style='font-weight: bold;'>l_linestatus</span>  <span style='font-weight: bold;'>sum_qty</span> <span style='font-weight: bold;'>sum_base_price</span> <span style='font-weight: bold;'>sum_disc_price</span>    <span style='font-weight: bold;'>sum_charge</span></span></span>
<span><span class='c'>#&gt;   <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>        <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>           <span style='color: #555555; font-style: italic;'>&lt;dbl&gt;</span>          <span style='color: #555555; font-style: italic;'>&lt;dbl&gt;</span>          <span style='color: #555555; font-style: italic;'>&lt;dbl&gt;</span>         <span style='color: #555555; font-style: italic;'>&lt;dbl&gt;</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>1</span> A            F            37<span style='text-decoration: underline;'>734</span>107   <span style='text-decoration: underline;'>56</span>586<span style='text-decoration: underline;'>554</span>401.   <span style='text-decoration: underline;'>53</span>758<span style='text-decoration: underline;'>257</span>135.  <span style='text-decoration: underline;'>55</span>909<span style='text-decoration: underline;'>065</span>223.</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>2</span> N            F              <span style='text-decoration: underline;'>991</span>417    <span style='text-decoration: underline;'>1</span>487<span style='text-decoration: underline;'>504</span>710.    <span style='text-decoration: underline;'>1</span>413<span style='text-decoration: underline;'>082</span>168.   <span style='text-decoration: underline;'>1</span>469<span style='text-decoration: underline;'>649</span>223.</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>3</span> N            O            74<span style='text-decoration: underline;'>476</span>040  <span style='text-decoration: underline;'>111</span>701<span style='text-decoration: underline;'>729</span>698.  <span style='text-decoration: underline;'>106</span>118<span style='text-decoration: underline;'>230</span>308. <span style='text-decoration: underline;'>110</span>367<span style='text-decoration: underline;'>043</span>872.</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>4</span> R            F            37<span style='text-decoration: underline;'>719</span>753   <span style='text-decoration: underline;'>56</span>568<span style='text-decoration: underline;'>041</span>381.   <span style='text-decoration: underline;'>53</span>741<span style='text-decoration: underline;'>292</span>685.  <span style='text-decoration: underline;'>55</span>889<span style='text-decoration: underline;'>619</span>120.</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># ℹ 4 more variables: </span><span style='color: #555555; font-weight: bold;'>avg_qty</span><span style='color: #555555;'> &lt;dbl&gt;, </span><span style='color: #555555; font-weight: bold;'>avg_price</span><span style='color: #555555;'> &lt;dbl&gt;, </span><span style='color: #555555; font-weight: bold;'>avg_disc</span><span style='color: #555555;'> &lt;dbl&gt;,</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>#   </span><span style='color: #555555; font-weight: bold;'>count_order</span><span style='color: #555555;'> &lt;int&gt;</span></span></span>
<span></span></code></pre>
</div>
<p>Note that the resulting object is indistinguishable from a regular tibble, except for the additional class.</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nf'><a href='https://rdrr.io/r/base/typeof.html'>typeof</a></span><span class='o'>(</span><span class='nv'>out</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; [1] "list"</span></span>
<span></span><span><span class='nf'><a href='https://rdrr.io/r/base/class.html'>class</a></span><span class='o'>(</span><span class='nv'>out</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; [1] "duckplyr_df" "tbl_df"      "tbl"         "data.frame"</span></span>
<span></span><span><span class='nv'>out</span><span class='o'>$</span><span class='nv'>count_order</span></span>
<span><span class='c'>#&gt; [1] 1478493   38854 2920374 1478870</span></span>
<span></span></code></pre>
</div>
<p>Operations not yet supported by duckplyr are automatically outsourced to dplyr. For instance, filtering on grouped data is not supported, but it still works thanks to the fallback mechanism. By default, the fallback is silent, but you can make it visible by setting an environment variable. This is useful if you want to better understanding what&rsquo;s making your code slow.</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nf'><a href='https://rdrr.io/r/base/Sys.setenv.html'>Sys.setenv</a></span><span class='o'>(</span>DUCKPLYR_FALLBACK_INFO <span class='o'>=</span> <span class='kc'>TRUE</span><span class='o'>)</span></span>
<span></span>
<span><span class='nv'>lineitem_tbl</span> <span class='o'>|&gt;</span></span>
<span>  <span class='nf'>duckplyr</span><span class='nf'>::</span><span class='nf'><a href='https://duckplyr.tidyverse.org/reference/duckdb_tibble.html'>as_duckdb_tibble</a></span><span class='o'>(</span><span class='o'>)</span> <span class='o'>|&gt;</span></span>
<span>  <span class='nf'><a href='https://dplyr.tidyverse.org/reference/filter.html'>filter</a></span><span class='o'>(</span><span class='nv'>l_quantity</span> <span class='o'>==</span> <span class='nf'><a href='https://rdrr.io/r/base/Extremes.html'>max</a></span><span class='o'>(</span><span class='nv'>l_quantity</span><span class='o'>)</span>, .by <span class='o'>=</span> <span class='nf'><a href='https://rdrr.io/r/base/c.html'>c</a></span><span class='o'>(</span><span class='nv'>l_returnflag</span>, <span class='nv'>l_linestatus</span><span class='o'>)</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; Cannot process duckplyr query with DuckDB, falling back to dplyr.</span></span>
<span><span class='c'>#&gt; <span style='color: #0000BB;'>ℹ</span> `filter(.by = ...)` not implemented, try `mutate(.by = ...)` followed by a simple `filter()`.</span></span>
<span></span><span><span class='c'>#&gt; <span style='color: #555555;'># A duckplyr data frame: 16 variables</span></span></span>
<span><span class='c'>#&gt;    <span style='font-weight: bold;'>l_orderkey</span> <span style='font-weight: bold;'>l_partkey</span> <span style='font-weight: bold;'>l_suppkey</span> <span style='font-weight: bold;'>l_linenumber</span> <span style='font-weight: bold;'>l_quantity</span> <span style='font-weight: bold;'>l_extendedprice</span></span></span>
<span><span class='c'>#&gt;         <span style='color: #555555; font-style: italic;'>&lt;dbl&gt;</span>     <span style='color: #555555; font-style: italic;'>&lt;dbl&gt;</span>     <span style='color: #555555; font-style: italic;'>&lt;dbl&gt;</span>        <span style='color: #555555; font-style: italic;'>&lt;dbl&gt;</span>      <span style='color: #555555; font-style: italic;'>&lt;dbl&gt;</span>           <span style='color: #555555; font-style: italic;'>&lt;dbl&gt;</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 1</span>          5     <span style='text-decoration: underline;'>37</span>531        35            3         50          <span style='text-decoration: underline;'>73</span>426.</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 2</span>        131     <span style='text-decoration: underline;'>44</span>255      <span style='text-decoration: underline;'>9</span>264            2         50          <span style='text-decoration: underline;'>59</span>962.</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 3</span>        199    <span style='text-decoration: underline;'>132</span>072      <span style='text-decoration: underline;'>9</span>612            1         50          <span style='text-decoration: underline;'>55</span>204.</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 4</span>        231    <span style='text-decoration: underline;'>198</span>124       644            3         50          <span style='text-decoration: underline;'>61</span>106 </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 5</span>        260    <span style='text-decoration: underline;'>155</span>887      <span style='text-decoration: underline;'>5</span>888            1         50          <span style='text-decoration: underline;'>97</span>144 </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 6</span>        263    <span style='text-decoration: underline;'>142</span>891       434            3         50          <span style='text-decoration: underline;'>96</span>694.</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 7</span>        323    <span style='text-decoration: underline;'>163</span>628      <span style='text-decoration: underline;'>1</span>177            1         50          <span style='text-decoration: underline;'>84</span>581 </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 8</span>        354     <span style='text-decoration: underline;'>58</span>125      <span style='text-decoration: underline;'>8</span>126            3         50          <span style='text-decoration: underline;'>54</span>156 </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 9</span>        484    <span style='text-decoration: underline;'>183</span>351      <span style='text-decoration: underline;'>5</span>870            3         50          <span style='text-decoration: underline;'>71</span>718.</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>10</span>        485    <span style='text-decoration: underline;'>149</span>523      <span style='text-decoration: underline;'>9</span>524            1         50          <span style='text-decoration: underline;'>78</span>626 </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># ℹ more rows</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># ℹ 10 more variables: </span><span style='color: #555555; font-weight: bold;'>l_discount</span><span style='color: #555555;'> &lt;dbl&gt;, </span><span style='color: #555555; font-weight: bold;'>l_tax</span><span style='color: #555555;'> &lt;dbl&gt;, </span><span style='color: #555555; font-weight: bold;'>l_returnflag</span><span style='color: #555555;'> &lt;chr&gt;,</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>#   </span><span style='color: #555555; font-weight: bold;'>l_linestatus</span><span style='color: #555555;'> &lt;chr&gt;, </span><span style='color: #555555; font-weight: bold;'>l_shipdate</span><span style='color: #555555;'> &lt;date&gt;, </span><span style='color: #555555; font-weight: bold;'>l_commitdate</span><span style='color: #555555;'> &lt;date&gt;,</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>#   </span><span style='color: #555555; font-weight: bold;'>l_receiptdate</span><span style='color: #555555;'> &lt;date&gt;, </span><span style='color: #555555; font-weight: bold;'>l_shipinstruct</span><span style='color: #555555;'> &lt;chr&gt;, </span><span style='color: #555555; font-weight: bold;'>l_shipmode</span><span style='color: #555555;'> &lt;chr&gt;,</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>#   </span><span style='color: #555555; font-weight: bold;'>l_comment</span><span style='color: #555555;'> &lt;chr&gt;</span></span></span>
<span></span></code></pre>
</div>
<p>You can also directly use DuckDB functions with the <code>dd$</code> qualifier. Functions with this prefix will not be translated at all and passed through directly to DuckDB. For example, the following code uses DuckDB&rsquo;s internal implementation of <a href="https://duckdb.org/docs/stable/sql/functions/text.html#editdist3s1-s2" target="_blank" rel="noopener">Levenstein distance</a>
:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nf'><a href='https://tibble.tidyverse.org/reference/tibble.html'>tibble</a></span><span class='o'>(</span>a <span class='o'>=</span> <span class='s'>"dbplyr"</span>, b <span class='o'>=</span> <span class='s'>"duckplyr"</span><span class='o'>)</span> <span class='o'><a href='https://magrittr.tidyverse.org/reference/pipe.html'>%&gt;%</a></span></span>
<span>  <span class='nf'><a href='https://dplyr.tidyverse.org/reference/mutate.html'>mutate</a></span><span class='o'>(</span>c <span class='o'>=</span> <span class='nv'>dd</span><span class='o'>$</span><span class='nf'>levenshtein</span><span class='o'>(</span><span class='nv'>a</span>, <span class='nv'>b</span><span class='o'>)</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># A tibble: 1 × 3</span></span></span>
<span><span class='c'>#&gt;   <span style='font-weight: bold;'>a</span>      <span style='font-weight: bold;'>b</span>            <span style='font-weight: bold;'>c</span></span></span>
<span><span class='c'>#&gt;   <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>  <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>    <span style='color: #555555; font-style: italic;'>&lt;dbl&gt;</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>1</span> dbplyr duckplyr     3</span></span>
<span></span></code></pre>
</div>
<p>See <a href="https://duckplyr.tidyverse.org/articles/duckdb.html" target="_blank" rel="noopener"><code>vignette(&quot;duckdb&quot;)</code></a>
 for more information on these features.</p>
<p>If you&rsquo;re working with dbplyr too, you can use <a href="https://duckplyr.tidyverse.org/reference/as_tbl.html" target="_blank" rel="noopener"><code>as_tbl()</code></a>
 you to convert a duckplyr tibble to a dbplyr lazy table. This allows you to seamlessly interact with existing code that might use inline SQL or other dbplyr functionality. With <a href="https://duckplyr.tidyverse.org/reference/duckdb_tibble.html" target="_blank" rel="noopener"><code>as_duckdb_tibble()</code></a>
, you can convert a dbplyr lazy table to a duckplyr tibble. Both operations work without intermediate materialization.</p>
<h2 id="benchmark">Benchmark
</h2>
<p>duckplyr is often much faster than dplyr. The comparison below is done in a fresh R session where dplyr is attached but duckplyr is not.</p>
<p>We use <code>tpch_dplyr()</code> as defined above to run the query with dplyr. The function that runs it with duckplyr only wraps the input data in a duck frame and forwards it to the dplyr function. The <a href="https://dplyr.tidyverse.org/reference/compute.html" target="_blank" rel="noopener"><code>collect()</code></a>
 at the end is required only for this benchmark to ensure fairness.<sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup></p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>tpch_duckplyr</span> <span class='o'>&lt;-</span> <span class='kr'>function</span><span class='o'>(</span><span class='nv'>lineitem</span><span class='o'>)</span> <span class='o'>&#123;</span></span>
<span>  <span class='nv'>lineitem</span> <span class='o'>|&gt;</span></span>
<span>    <span class='nf'>duckplyr</span><span class='nf'>::</span><span class='nf'><a href='https://duckplyr.tidyverse.org/reference/duckdb_tibble.html'>as_duckdb_tibble</a></span><span class='o'>(</span><span class='o'>)</span> <span class='o'>|&gt;</span></span>
<span>    <span class='nf'>tpch_dplyr</span><span class='o'>(</span><span class='o'>)</span> <span class='o'>|&gt;</span></span>
<span>    <span class='nf'><a href='https://dplyr.tidyverse.org/reference/compute.html'>collect</a></span><span class='o'>(</span><span class='o'>)</span></span>
<span><span class='o'>&#125;</span></span></code></pre>
</div>
<p>And now we compare the two:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nf'>bench</span><span class='nf'>::</span><span class='nf'><a href='https://bench.r-lib.org/reference/mark.html'>mark</a></span><span class='o'>(</span></span>
<span>  <span class='nf'>tpch_dplyr</span><span class='o'>(</span><span class='nv'>lineitem_tbl</span><span class='o'>)</span>,</span>
<span>  <span class='nf'>tpch_duckplyr</span><span class='o'>(</span><span class='nv'>lineitem_tbl</span><span class='o'>)</span>,</span>
<span>  check <span class='o'>=</span> <span class='o'>~</span> <span class='nf'><a href='https://rdrr.io/r/base/all.equal.html'>all.equal</a></span><span class='o'>(</span><span class='nv'>.x</span>, <span class='nv'>.y</span>, tolerance <span class='o'>=</span> <span class='m'>1e-10</span><span class='o'>)</span></span>
<span><span class='o'>)</span></span>
<span><span class='c'>#&gt; Warning: Some expressions had a GC in every iteration; so filtering is disabled.</span></span>
<span></span><span><span class='c'>#&gt; <span style='color: #555555;'># A tibble: 2 × 6</span></span></span>
<span><span class='c'>#&gt;   <span style='font-weight: bold;'>expression</span>                       <span style='font-weight: bold;'>min</span>   <span style='font-weight: bold;'>median</span> <span style='font-weight: bold;'>`itr/sec`</span> <span style='font-weight: bold;'>mem_alloc</span> <span style='font-weight: bold;'>`gc/sec`</span></span></span>
<span><span class='c'>#&gt;   <span style='color: #555555; font-style: italic;'>&lt;bch:expr&gt;</span>                  <span style='color: #555555; font-style: italic;'>&lt;bch:tm&gt;</span> <span style='color: #555555; font-style: italic;'>&lt;bch:tm&gt;</span>     <span style='color: #555555; font-style: italic;'>&lt;dbl&gt;</span> <span style='color: #555555; font-style: italic;'>&lt;bch:byt&gt;</span>    <span style='color: #555555; font-style: italic;'>&lt;dbl&gt;</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>1</span> tpch_dplyr(lineitem_tbl)     611.6ms  611.6ms      1.64    1.25GB     1.64</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>2</span> tpch_duckplyr(lineitem_tbl)   71.4ms   72.3ms     13.8   314.38KB     0</span></span>
<span></span></code></pre>
</div>
<p>In this example, duckplyr is a lot faster than dplyr. It also appears to use much less memory, but this is misleading: DuckDB manages the memory, not R, so the memory usage is not visible to <a href="https://bench.r-lib.org/reference/mark.html" target="_blank" rel="noopener"><code>bench::mark()</code></a>
.</p>
<h2 id="out-of-memory-data">Out-of-memory data
</h2>
<p>As well as improved speed with in-memory datasets, duckplyr makes it easy to work with datasets that are too big to fit in memory. In this case, you want:</p>
<ol>
<li>To work with data stored in modern formats designed for large data (e.g. Parquet).</li>
<li>To be able to store large intermediate results on disk, keeping them out of memory.</li>
<li>Fast computation!</li>
</ol>
<p>duckdplyr provides each of these features:</p>
<ol>
<li>You can read data from disk with functions like <a href="https://duckplyr.tidyverse.org/reference/read_parquet_duckdb.html" target="_blank" rel="noopener"><code>read_parquet_duckdb()</code></a>
.</li>
<li>You can save intermediate results to disk with <a href="https://duckplyr.tidyverse.org/reference/compute_parquet.html" target="_blank" rel="noopener"><code>compute_parquet()</code></a>
 and <a href="https://duckplyr.tidyverse.org/reference/compute_csv.html" target="_blank" rel="noopener"><code>compute_csv()</code></a>
.</li>
<li>duckdplyr takes advantage of DuckDB&rsquo;s query planner which considers your entire pipeline holistically to figure out the most efficient way to get the data you need.</li>
</ol>
<p>See <a href="https://duckplyr.tidyverse.org/articles/large.html" target="_blank" rel="noopener"><code>vignette(&quot;large&quot;)</code></a>
 for a walkthrough and more details.</p>
<h2 id="help-us-improve-duckplyr">Help us improve duckplyr!
</h2>
<p>Our goals for future development of duckplyr include:</p>
<ul>
<li>Enabling users to provide <a href="https://github.com/tidyverse/duckplyr/issues/158" target="_blank" rel="noopener">custom translations</a>
 of dplyr functionality;</li>
<li>Making it easier to contribute code to duckplyr;</li>
<li>Supporting more dplyr and tidyr functionality natively in DuckDB.</li>
</ul>
<p>You can help!</p>
<ul>
<li>Please report any issues, especially regarding unknown incompabilities. See <a href="https://duckplyr.tidyverse.org/articles/limits.html" target="_blank" rel="noopener"><code>vignette(&quot;limits&quot;)</code></a>
.</li>
<li>Contribute to the codebase after reading duckplyr&rsquo;s <a href="https://duckplyr.tidyverse.org/CONTRIBUTING.html" target="_blank" rel="noopener">contributing guide</a>
.</li>
<li>Turn on telemetry to help us hear about the most frequent fallbacks so we can prioritize working on the corresponding missing dplyr translation. See <a href="https://duckplyr.tidyverse.org/articles/telemetry.html" target="_blank" rel="noopener"><code>vignette(&quot;telemetry&quot;)</code></a>
 and <a href="https://duckplyr.tidyverse.org/reference/fallback.html" target="_blank" rel="noopener"><code>duckplyr::fallback_sitrep()</code></a>
.</li>
</ul>
<h2 id="additional-resources">Additional resources
</h2>
<p>Eager to learn more about duckplyr &ndash; beside by trying it out yourself? The duckplyr website features several <a href="https://duckplyr.tidyverse.org/articles/" target="_blank" rel="noopener">articles</a>
. Furthermore, the blog post <a href="https://duckdb.org/2024/04/02/duckplyr.html" target="_blank" rel="noopener">&ldquo;duckplyr: dplyr Powered by DuckDB&rdquo;</a>
 by Hannes Mühleisen provides some context on duckplyr including its inner workings, as also seen in a <a href="https://blog.r-hub.io/2025/02/13/lazy-meanings/#duckplyr-lazy-evaluation-and-prudence" target="_blank" rel="noopener">section</a>
 of the R-hub blog post <a href="https://blog.r-hub.io/2025/02/13/lazy-meanings/" target="_blank" rel="noopener">&ldquo;Lazy introduction to laziness in R&rdquo;</a>
 by Maëlle Salmon, Athanasia Mo Mowinckel and Hannah Frick.</p>
<h2 id="acknowledgements">Acknowledgements
</h2>
<p>A big thanks to all folks who filed issues, created PRs and generally helped to improve duckplyr and its workhorse <a href="https://r.duckdb.org/" target="_blank" rel="noopener">duckdb</a>
!</p>
<p><a href="https://github.com/adamschwing" target="_blank" rel="noopener">@adamschwing</a>
, <a href="https://github.com/alejandrohagan" target="_blank" rel="noopener">@alejandrohagan</a>
, <a href="https://github.com/andreranza" target="_blank" rel="noopener">@andreranza</a>
, <a href="https://github.com/apalacio9502" target="_blank" rel="noopener">@apalacio9502</a>
, <a href="https://github.com/apsteinmetz" target="_blank" rel="noopener">@apsteinmetz</a>
, <a href="https://github.com/barracuda156" target="_blank" rel="noopener">@barracuda156</a>
, <a href="https://github.com/beniaminogreen" target="_blank" rel="noopener">@beniaminogreen</a>
, <a href="https://github.com/bob-rietveld" target="_blank" rel="noopener">@bob-rietveld</a>
, <a href="https://github.com/brichards920" target="_blank" rel="noopener">@brichards920</a>
, <a href="https://github.com/cboettig" target="_blank" rel="noopener">@cboettig</a>
, <a href="https://github.com/davidjayjackson" target="_blank" rel="noopener">@davidjayjackson</a>
, <a href="https://github.com/DavisVaughan" target="_blank" rel="noopener">@DavisVaughan</a>
, <a href="https://github.com/Ed2uiz" target="_blank" rel="noopener">@Ed2uiz</a>
, <a href="https://github.com/eitsupi" target="_blank" rel="noopener">@eitsupi</a>
, <a href="https://github.com/era127" target="_blank" rel="noopener">@era127</a>
, <a href="https://github.com/etiennebacher" target="_blank" rel="noopener">@etiennebacher</a>
, <a href="https://github.com/eutwt" target="_blank" rel="noopener">@eutwt</a>
, <a href="https://github.com/fmichonneau" target="_blank" rel="noopener">@fmichonneau</a>
, <a href="https://github.com/hadley" target="_blank" rel="noopener">@hadley</a>
, <a href="https://github.com/hannes" target="_blank" rel="noopener">@hannes</a>
, <a href="https://github.com/hawkfish" target="_blank" rel="noopener">@hawkfish</a>
, <a href="https://github.com/IndrajeetPatil" target="_blank" rel="noopener">@IndrajeetPatil</a>
, <a href="https://github.com/JanSulavik" target="_blank" rel="noopener">@JanSulavik</a>
, <a href="https://github.com/JavOrraca" target="_blank" rel="noopener">@JavOrraca</a>
, <a href="https://github.com/jeroen" target="_blank" rel="noopener">@jeroen</a>
, <a href="https://github.com/jhk0530" target="_blank" rel="noopener">@jhk0530</a>
, <a href="https://github.com/joakimlinde" target="_blank" rel="noopener">@joakimlinde</a>
, <a href="https://github.com/JosiahParry" target="_blank" rel="noopener">@JosiahParry</a>
, <a href="https://github.com/kevbaer" target="_blank" rel="noopener">@kevbaer</a>
, <a href="https://github.com/larry77" target="_blank" rel="noopener">@larry77</a>
, <a href="https://github.com/lnkuiper" target="_blank" rel="noopener">@lnkuiper</a>
, <a href="https://github.com/lorenzwalthert" target="_blank" rel="noopener">@lorenzwalthert</a>
, <a href="https://github.com/lschneiderbauer" target="_blank" rel="noopener">@lschneiderbauer</a>
, <a href="https://github.com/luisDVA" target="_blank" rel="noopener">@luisDVA</a>
, <a href="https://github.com/math-mcshane" target="_blank" rel="noopener">@math-mcshane</a>
, <a href="https://github.com/meersel" target="_blank" rel="noopener">@meersel</a>
, <a href="https://github.com/multimeric" target="_blank" rel="noopener">@multimeric</a>
, <a href="https://github.com/mytarmail" target="_blank" rel="noopener">@mytarmail</a>
, <a href="https://github.com/nicki-dese" target="_blank" rel="noopener">@nicki-dese</a>
, <a href="https://github.com/PMassicotte" target="_blank" rel="noopener">@PMassicotte</a>
, <a href="https://github.com/prasundutta87" target="_blank" rel="noopener">@prasundutta87</a>
, <a href="https://github.com/rafapereirabr" target="_blank" rel="noopener">@rafapereirabr</a>
, <a href="https://github.com/Robinlovelace" target="_blank" rel="noopener">@Robinlovelace</a>
, <a href="https://github.com/romainfrancois" target="_blank" rel="noopener">@romainfrancois</a>
, <a href="https://github.com/sparrow925" target="_blank" rel="noopener">@sparrow925</a>
, <a href="https://github.com/stefanlinner" target="_blank" rel="noopener">@stefanlinner</a>
, <a href="https://github.com/szarnyasg" target="_blank" rel="noopener">@szarnyasg</a>
, <a href="https://github.com/thomasp85" target="_blank" rel="noopener">@thomasp85</a>
, <a href="https://github.com/TimTaylor" target="_blank" rel="noopener">@TimTaylor</a>
, <a href="https://github.com/Tmonster" target="_blank" rel="noopener">@Tmonster</a>
, <a href="https://github.com/toppyy" target="_blank" rel="noopener">@toppyy</a>
, <a href="https://github.com/wibeasley" target="_blank" rel="noopener">@wibeasley</a>
, <a href="https://github.com/yjunechoe" target="_blank" rel="noopener">@yjunechoe</a>
, <a href="https://github.com/ywhcuhk" target="_blank" rel="noopener">@ywhcuhk</a>
, <a href="https://github.com/zhjx19" target="_blank" rel="noopener">@zhjx19</a>
, <a href="https://github.com/ablack3" target="_blank" rel="noopener">@ablack3</a>
, <a href="https://github.com/actuarial-lonewolf" target="_blank" rel="noopener">@actuarial-lonewolf</a>
, <a href="https://github.com/ajdamico" target="_blank" rel="noopener">@ajdamico</a>
, <a href="https://github.com/amirmazmi" target="_blank" rel="noopener">@amirmazmi</a>
, <a href="https://github.com/anderson461123" target="_blank" rel="noopener">@anderson461123</a>
, <a href="https://github.com/andrewGhazi" target="_blank" rel="noopener">@andrewGhazi</a>
, <a href="https://github.com/Antonov548" target="_blank" rel="noopener">@Antonov548</a>
, <a href="https://github.com/appiehappie999" target="_blank" rel="noopener">@appiehappie999</a>
, <a href="https://github.com/ArthurAndrews" target="_blank" rel="noopener">@ArthurAndrews</a>
, <a href="https://github.com/arthurgailes" target="_blank" rel="noopener">@arthurgailes</a>
, <a href="https://github.com/babaknaimi" target="_blank" rel="noopener">@babaknaimi</a>
, <a href="https://github.com/bcaradima" target="_blank" rel="noopener">@bcaradima</a>
, <a href="https://github.com/bdforbes" target="_blank" rel="noopener">@bdforbes</a>
, <a href="https://github.com/bergest" target="_blank" rel="noopener">@bergest</a>
, <a href="https://github.com/bill-ash" target="_blank" rel="noopener">@bill-ash</a>
, <a href="https://github.com/BorgeJorge" target="_blank" rel="noopener">@BorgeJorge</a>
, <a href="https://github.com/brianmsm" target="_blank" rel="noopener">@brianmsm</a>
, <a href="https://github.com/chainsawriot" target="_blank" rel="noopener">@chainsawriot</a>
, <a href="https://github.com/ckarnes" target="_blank" rel="noopener">@ckarnes</a>
, <a href="https://github.com/clementlefevre" target="_blank" rel="noopener">@clementlefevre</a>
, <a href="https://github.com/cregouby" target="_blank" rel="noopener">@cregouby</a>
, <a href="https://github.com/cy-james-lee" target="_blank" rel="noopener">@cy-james-lee</a>
, <a href="https://github.com/daranzolin" target="_blank" rel="noopener">@daranzolin</a>
, <a href="https://github.com/david-cortes" target="_blank" rel="noopener">@david-cortes</a>
, <a href="https://github.com/DavZim" target="_blank" rel="noopener">@DavZim</a>
, <a href="https://github.com/denis-or" target="_blank" rel="noopener">@denis-or</a>
, <a href="https://github.com/developertest1234" target="_blank" rel="noopener">@developertest1234</a>
, <a href="https://github.com/dicorynia" target="_blank" rel="noopener">@dicorynia</a>
, <a href="https://github.com/dsolito" target="_blank" rel="noopener">@dsolito</a>
, <a href="https://github.com/e-kotov" target="_blank" rel="noopener">@e-kotov</a>
, <a href="https://github.com/EAVWing" target="_blank" rel="noopener">@EAVWing</a>
, <a href="https://github.com/eddelbuettel" target="_blank" rel="noopener">@eddelbuettel</a>
, <a href="https://github.com/edward-burn" target="_blank" rel="noopener">@edward-burn</a>
, <a href="https://github.com/elefeint" target="_blank" rel="noopener">@elefeint</a>
, <a href="https://github.com/eli-daniels" target="_blank" rel="noopener">@eli-daniels</a>
, <a href="https://github.com/elysabethpc" target="_blank" rel="noopener">@elysabethpc</a>
, <a href="https://github.com/erikvona" target="_blank" rel="noopener">@erikvona</a>
, <a href="https://github.com/florisvdh" target="_blank" rel="noopener">@florisvdh</a>
, <a href="https://github.com/gaborcsardi" target="_blank" rel="noopener">@gaborcsardi</a>
, <a href="https://github.com/ggrothendieck" target="_blank" rel="noopener">@ggrothendieck</a>
, <a href="https://github.com/hdmm3" target="_blank" rel="noopener">@hdmm3</a>
, <a href="https://github.com/hope-data-science" target="_blank" rel="noopener">@hope-data-science</a>
, <a href="https://github.com/IoannaNika" target="_blank" rel="noopener">@IoannaNika</a>
, <a href="https://github.com/jabrown-aepenergy" target="_blank" rel="noopener">@jabrown-aepenergy</a>
, <a href="https://github.com/JamesLMacAulay" target="_blank" rel="noopener">@JamesLMacAulay</a>
, <a href="https://github.com/jangorecki" target="_blank" rel="noopener">@jangorecki</a>
, <a href="https://github.com/javierlenzi" target="_blank" rel="noopener">@javierlenzi</a>
, <a href="https://github.com/Joe-Heffer-Shef" target="_blank" rel="noopener">@Joe-Heffer-Shef</a>
, <a href="https://github.com/kalibera" target="_blank" rel="noopener">@kalibera</a>
, <a href="https://github.com/lboller-pwbm" target="_blank" rel="noopener">@lboller-pwbm</a>
, <a href="https://github.com/lgaborini" target="_blank" rel="noopener">@lgaborini</a>
, <a href="https://github.com/m-muecke" target="_blank" rel="noopener">@m-muecke</a>
, <a href="https://github.com/meztez" target="_blank" rel="noopener">@meztez</a>
, <a href="https://github.com/mgirlich" target="_blank" rel="noopener">@mgirlich</a>
, <a href="https://github.com/mtmorgan" target="_blank" rel="noopener">@mtmorgan</a>
, <a href="https://github.com/nassuphis" target="_blank" rel="noopener">@nassuphis</a>
, <a href="https://github.com/nbc" target="_blank" rel="noopener">@nbc</a>
, <a href="https://github.com/olivroy" target="_blank" rel="noopener">@olivroy</a>
, <a href="https://github.com/pdet" target="_blank" rel="noopener">@pdet</a>
, <a href="https://github.com/phdjsep" target="_blank" rel="noopener">@phdjsep</a>
, <a href="https://github.com/pierre-lamarche" target="_blank" rel="noopener">@pierre-lamarche</a>
, <a href="https://github.com/r2evans" target="_blank" rel="noopener">@r2evans</a>
, <a href="https://github.com/ran-codes" target="_blank" rel="noopener">@ran-codes</a>
, <a href="https://github.com/rplsmn" target="_blank" rel="noopener">@rplsmn</a>
, <a href="https://github.com/Saarialho" target="_blank" rel="noopener">@Saarialho</a>
, <a href="https://github.com/SimonCoulombe" target="_blank" rel="noopener">@SimonCoulombe</a>
, <a href="https://github.com/tau31" target="_blank" rel="noopener">@tau31</a>
, <a href="https://github.com/thohan88" target="_blank" rel="noopener">@thohan88</a>
, <a href="https://github.com/ThomasSoeiro" target="_blank" rel="noopener">@ThomasSoeiro</a>
, <a href="https://github.com/timothygmitchell" target="_blank" rel="noopener">@timothygmitchell</a>
, <a href="https://github.com/vincentarelbundock" target="_blank" rel="noopener">@vincentarelbundock</a>
, <a href="https://github.com/VincentGuyader" target="_blank" rel="noopener">@VincentGuyader</a>
, <a href="https://github.com/wlangera" target="_blank" rel="noopener">@wlangera</a>
, <a href="https://github.com/xbasics" target="_blank" rel="noopener">@xbasics</a>
, <a href="https://github.com/xiaodaigh" target="_blank" rel="noopener">@xiaodaigh</a>
, <a href="https://github.com/xtimbeau" target="_blank" rel="noopener">@xtimbeau</a>
, <a href="https://github.com/yng-me" target="_blank" rel="noopener">@yng-me</a>
, <a href="https://github.com/Yousuf28" target="_blank" rel="noopener">@Yousuf28</a>
, <a href="https://github.com/yutannihilation" target="_blank" rel="noopener">@yutannihilation</a>
, and <a href="https://github.com/zcatav" target="_blank" rel="noopener">@zcatav</a>
</p>
<p>Special thanks to Joe Thorley (<a href="https://github.com/joethorley" target="_blank" rel="noopener">@joethorley</a>
) for help with choosing the right words.</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>If you haven&rsquo;t heard of it yet, watch <a href="https://www.youtube.com/watch?v=GELhdezYmP0&amp;feature=youtu.be" target="_blank" rel="noopener">Hannes Mühleisen&rsquo;s keynote at posit::conf(2024)</a>
.&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:2">
<p>If omitted, the results would be unchanged but the measurements would be wrong. The computation would then be triggered by the check. See <a href="https://duckplyr.tidyverse.org/articles/prudence.html" target="_blank" rel="noopener"><code>vignette(&quot;prudence&quot;)</code></a>
 for details.&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></description>
      <enclosure url="https://posit-open-source.netlify.app/blog/tidyverse/2025/duckplyr-1-1-0/thumbnail-wd.jpg" length="60990" type="image/jpeg" />
    </item>
    <item>
      <title>Data Validation Libraries for Polars (2025 Edition)</title>
      <link>https://posit-open-source.netlify.app/blog/pointblank/validation-libs-2025/</link>
      <pubDate>Wed, 04 Jun 2025 00:00:00 +0000</pubDate>
      <guid>https://posit-open-source.netlify.app/blog/pointblank/validation-libs-2025/</guid>
      <dc:creator>Rich Iannone</dc:creator><description><![CDATA[<script src="https://cdn.jsdelivr.net/npm/requirejs@2.3.6/require.min.js" integrity="sha384-c9c+LnTbwQ3aujuU7ULEPVvgLs+Fn6fJUvIGTsuu1ZcCf11fiEubah0ttpca4ntM sha384-6V1/AdqZRWk1KAlWbKBlGhN7VG4iE/yAZcO6NZPMF8od0vukrvr0tg4qY6NSrItx" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.min.js" integrity="sha384-ZvpUoO/+PpLXR1lu4jmpXWu80pZlYUAfxl5NsBMWOEPSjUn/6Z/hRTt8+pR6L4N2" crossorigin="anonymous" data-relocate-top="true"></script>
<script type="application/javascript">define('jquery', [],function() {return window.jQuery;})</script>
<p>Data validation is a very important part of any data pipeline. And with Polars gaining popularity as
a superfast and feature-packed DataFrame library, developers need validation tools that work
seamlessly with it. But here&rsquo;s the thing: not all validation libraries are created equal, and
choosing the wrong one can lead to frustration, technical debt, or validation gaps that could bite
you later.</p>
<p>In this survey (conducted halfway through 2025) we&rsquo;ll explore five Python validation libraries that
support Polars DataFrames, each bringing distinct strengths to different validation challenges.</p>
<div class="callout callout-note" role="note" aria-label="Note">
<div class="callout-header">
<span class="callout-title">Note</span>
</div>
<div class="callout-body">
<p>Great Expectations, while being one of the most established data validation frameworks in the Python
ecosystem, is not included in this survey as it doesn&rsquo;t yet offer native Polars support. See <a href="https://github.com/great-expectations/great_expectations/issues/10702" target="_blank" rel="noopener">this
issue</a>
 and
<a href="https://github.com/great-expectations/great_expectations/discussions/10144" target="_blank" rel="noopener">this discussion</a>
 for
the inside baseball.</p>
</div>
</div>
<h2 id="recommendations">Recommendations
</h2>
<p>Here are the unique strengths for each library:</p>
<div id="vzwypnqhnw" style="padding-left:0px;padding-right:0px;padding-top:10px;padding-bottom:10px;overflow-x:auto;overflow-y:auto;width:auto;height:auto;">
<style>
#vzwypnqhnw table {
          font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Helvetica Neue', 'Fira Sans', 'Droid Sans', Arial, sans-serif;
          -webkit-font-smoothing: antialiased;
          -moz-osx-font-smoothing: grayscale;
        }
<p>#vzwypnqhnw thead, tbody, tfoot, tr, td, th { border-style: none; }
tr { background-color: transparent; }
#vzwypnqhnw p { margin: 0; padding: 0; }
#vzwypnqhnw .gt_table { display: table; border-collapse: collapse; line-height: normal; margin-left: auto; margin-right: auto; color: #333333; font-size: 16px; font-weight: normal; font-style: normal; background-color: #FFFFFF; width: auto; border-top-style: solid; border-top-width: 2px; border-top-color: #A8A8A8; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #A8A8A8; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; }
#vzwypnqhnw .gt_caption { padding-top: 4px; padding-bottom: 4px; }
#vzwypnqhnw .gt_title { color: #333333; font-size: 125%; font-weight: initial; padding-top: 4px; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; border-bottom-color: #FFFFFF; border-bottom-width: 0; }
#vzwypnqhnw .gt_subtitle { color: #333333; font-size: 85%; font-weight: initial; padding-top: 3px; padding-bottom: 5px; padding-left: 10px; padding-right: 10px; border-top-color: #FFFFFF; border-top-width: 0; }
#vzwypnqhnw .gt_heading { background-color: #FFFFFF; text-align: center; border-bottom-color: #FFFFFF; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; }
#vzwypnqhnw .gt_bottom_border { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; }
#vzwypnqhnw .gt_col_headings { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; }
#vzwypnqhnw .gt_col_heading { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; padding-left: 10px; padding-right: 10px; overflow-x: hidden; }
#vzwypnqhnw .gt_column_spanner_outer { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; padding-top: 0; padding-bottom: 0; padding-left: 4px; padding-right: 4px; }
#vzwypnqhnw .gt_column_spanner_outer:first-child { padding-left: 0; }
#vzwypnqhnw .gt_column_spanner_outer:last-child { padding-right: 0; }
#vzwypnqhnw .gt_column_spanner { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; overflow-x: hidden; display: inline-block; width: 100%; }
#vzwypnqhnw .gt_spanner_row { border-bottom-style: hidden; }
#vzwypnqhnw .gt_group_heading { padding-top: 8px; padding-bottom: 8px; padding-left: 10px; padding-right: 10px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; text-align: left; }
#vzwypnqhnw .gt_empty_group_heading { padding: 0.5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: middle; }
#vzwypnqhnw .gt_from_md&gt; :first-child { margin-top: 0; }
#vzwypnqhnw .gt_from_md&gt; :last-child { margin-bottom: 0; }
#vzwypnqhnw .gt_row { padding-top: 8px; padding-bottom: 8px; padding-left: 10px; padding-right: 10px; margin: 10px; border-top-style: solid; border-top-width: 1px; border-top-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; overflow-x: hidden; }
#vzwypnqhnw .gt_stub { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 10px; padding-right: 10px; }
#vzwypnqhnw .gt_stub_row_group { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 10px; padding-right: 10px; vertical-align: top; }
#vzwypnqhnw .gt_row_group_first td { border-top-width: 2px; }
#vzwypnqhnw .gt_row_group_first th { border-top-width: 2px; }
#vzwypnqhnw .gt_striped { color: #333333; background-color: #F4F4F4; }
#vzwypnqhnw .gt_table_body { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; }
#vzwypnqhnw .gt_grand_summary_row { color: #333333; background-color: #FFFFFF; text-transform: inherit; padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; }
#vzwypnqhnw .gt_first_grand_summary_row_bottom { border-top-style: double; border-top-width: 6px; border-top-color: #D3D3D3; }
#vzwypnqhnw .gt_last_grand_summary_row_top { border-bottom-style: double; border-bottom-width: 6px; border-bottom-color: #D3D3D3; }
#vzwypnqhnw .gt_sourcenotes { color: #333333; background-color: #FFFFFF; border-bottom-style: none; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; }
#vzwypnqhnw .gt_sourcenote { font-size: 90%; padding-top: 4px; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; text-align: left; }
#vzwypnqhnw .gt_left { text-align: left; }
#vzwypnqhnw .gt_center { text-align: center; }
#vzwypnqhnw .gt_right { text-align: right; font-variant-numeric: tabular-nums; }
#vzwypnqhnw .gt_font_normal { font-weight: normal; }
#vzwypnqhnw .gt_font_bold { font-weight: bold; }
#vzwypnqhnw .gt_font_italic { font-style: italic; }
#vzwypnqhnw .gt_super { font-size: 65%; }
#vzwypnqhnw .gt_footnote_marks { font-size: 75%; vertical-align: 0.4em; position: initial; }
#vzwypnqhnw .gt_asterisk { font-size: 100%; vertical-align: 0; }</p>
<p></style></p>
<table>
  <thead>
      <tr>
          <th>Library</th>
          <th>⭐</th>
          <th>Best Features</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="https://github.com/unionai-oss/pandera" style="color: #333333; text-underline-offset: 3px;">Pandera</a></td>
          <td>3,838</td>
          <td>Statistical testing, schema-centric validation, mypy integration</td>
      </tr>
      <tr>
          <td><a href="https://github.com/JakobGM/patito" style="color: #333333; text-underline-offset: 3px;">Patito</a></td>
          <td>468</td>
          <td>Pydantic integration, model-based validation, row-level objects</td>
      </tr>
      <tr>
          <td><a href="https://github.com/posit-dev/pointblank" style="color: #333333; text-underline-offset: 3px;">Pointblank</a></td>
          <td>173</td>
          <td>Interactive reports, threshold management, stakeholder communication</td>
      </tr>
      <tr>
          <td><a href="https://github.com/akmalsoliev/Validoopsie" style="color: #333333; text-underline-offset: 3px;">Validoopsie</a></td>
          <td>63</td>
          <td>Built-in logging, composable validation, impact levels, lightweight Great Expectations alternative</td>
      </tr>
      <tr>
          <td><a href="https://github.com/Quantco/dataframely" style="color: #333333; text-underline-offset: 3px;">Dataframely</a></td>
          <td>319</td>
          <td>Collection validation, advanced type safety, failure analysis</td>
      </tr>
  </tbody>
</table>
</div>
<p>Based on these strengths, here are my recommendations for which libraries to use according to use case:</p>
<div id="pliqxkgbyp" style="padding-left:0px;padding-right:0px;padding-top:10px;padding-bottom:10px;overflow-x:auto;overflow-y:auto;width:auto;height:auto;">
<style>
#pliqxkgbyp table {
          font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Helvetica Neue', 'Fira Sans', 'Droid Sans', Arial, sans-serif;
          -webkit-font-smoothing: antialiased;
          -moz-osx-font-smoothing: grayscale;
        }
<p>#pliqxkgbyp thead, tbody, tfoot, tr, td, th { border-style: none; }
tr { background-color: transparent; }
#pliqxkgbyp p { margin: 0; padding: 0; }
#pliqxkgbyp .gt_table { display: table; border-collapse: collapse; line-height: normal; margin-left: auto; margin-right: auto; color: #333333; font-size: 16px; font-weight: normal; font-style: normal; background-color: #FFFFFF; width: auto; border-top-style: solid; border-top-width: 2px; border-top-color: #A8A8A8; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #A8A8A8; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; }
#pliqxkgbyp .gt_caption { padding-top: 4px; padding-bottom: 4px; }
#pliqxkgbyp .gt_title { color: #333333; font-size: 125%; font-weight: initial; padding-top: 4px; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; border-bottom-color: #FFFFFF; border-bottom-width: 0; }
#pliqxkgbyp .gt_subtitle { color: #333333; font-size: 85%; font-weight: initial; padding-top: 3px; padding-bottom: 5px; padding-left: 10px; padding-right: 10px; border-top-color: #FFFFFF; border-top-width: 0; }
#pliqxkgbyp .gt_heading { background-color: #FFFFFF; text-align: center; border-bottom-color: #FFFFFF; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; }
#pliqxkgbyp .gt_bottom_border { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; }
#pliqxkgbyp .gt_col_headings { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; }
#pliqxkgbyp .gt_col_heading { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; padding-left: 10px; padding-right: 10px; overflow-x: hidden; }
#pliqxkgbyp .gt_column_spanner_outer { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; padding-top: 0; padding-bottom: 0; padding-left: 4px; padding-right: 4px; }
#pliqxkgbyp .gt_column_spanner_outer:first-child { padding-left: 0; }
#pliqxkgbyp .gt_column_spanner_outer:last-child { padding-right: 0; }
#pliqxkgbyp .gt_column_spanner { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; overflow-x: hidden; display: inline-block; width: 100%; }
#pliqxkgbyp .gt_spanner_row { border-bottom-style: hidden; }
#pliqxkgbyp .gt_group_heading { padding-top: 8px; padding-bottom: 8px; padding-left: 10px; padding-right: 10px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; text-align: left; }
#pliqxkgbyp .gt_empty_group_heading { padding: 0.5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: middle; }
#pliqxkgbyp .gt_from_md&gt; :first-child { margin-top: 0; }
#pliqxkgbyp .gt_from_md&gt; :last-child { margin-bottom: 0; }
#pliqxkgbyp .gt_row { padding-top: 8px; padding-bottom: 8px; padding-left: 10px; padding-right: 10px; margin: 10px; border-top-style: solid; border-top-width: 1px; border-top-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; overflow-x: hidden; }
#pliqxkgbyp .gt_stub { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 10px; padding-right: 10px; }
#pliqxkgbyp .gt_stub_row_group { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 10px; padding-right: 10px; vertical-align: top; }
#pliqxkgbyp .gt_row_group_first td { border-top-width: 2px; }
#pliqxkgbyp .gt_row_group_first th { border-top-width: 2px; }
#pliqxkgbyp .gt_striped { color: #333333; background-color: #F4F4F4; }
#pliqxkgbyp .gt_table_body { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; }
#pliqxkgbyp .gt_grand_summary_row { color: #333333; background-color: #FFFFFF; text-transform: inherit; padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; }
#pliqxkgbyp .gt_first_grand_summary_row_bottom { border-top-style: double; border-top-width: 6px; border-top-color: #D3D3D3; }
#pliqxkgbyp .gt_last_grand_summary_row_top { border-bottom-style: double; border-bottom-width: 6px; border-bottom-color: #D3D3D3; }
#pliqxkgbyp .gt_sourcenotes { color: #333333; background-color: #FFFFFF; border-bottom-style: none; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; }
#pliqxkgbyp .gt_sourcenote { font-size: 90%; padding-top: 4px; padding-bottom: 4px; padding-left: 10px; padding-right: 10px; text-align: left; }
#pliqxkgbyp .gt_left { text-align: left; }
#pliqxkgbyp .gt_center { text-align: center; }
#pliqxkgbyp .gt_right { text-align: right; font-variant-numeric: tabular-nums; }
#pliqxkgbyp .gt_font_normal { font-weight: normal; }
#pliqxkgbyp .gt_font_bold { font-weight: bold; }
#pliqxkgbyp .gt_font_italic { font-style: italic; }
#pliqxkgbyp .gt_super { font-size: 65%; }
#pliqxkgbyp .gt_footnote_marks { font-size: 75%; vertical-align: 0.4em; position: initial; }
#pliqxkgbyp .gt_asterisk { font-size: 100%; vertical-align: 0; }</p>
<p></style></p>
<table>
  <thead>
      <tr>
          <th>Use Case</th>
          <th>Best Libraries</th>
          <th>Description</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Type-safe pipelines</td>
          <td>Pandera, Dataframely, Patito</td>
          <td>Static type checking and compile-time validation</td>
      </tr>
      <tr>
          <td>Stakeholder reporting</td>
          <td>Pointblank</td>
          <td>Sharing validation results with non-technical teams</td>
      </tr>
      <tr>
          <td>Row-level object modeling</td>
          <td>Patito</td>
          <td>Converting DataFrame rows to Python objects with business logic</td>
      </tr>
      <tr>
          <td>Statistical validation</td>
          <td>Pandera</td>
          <td>Testing data distributions and statistical properties</td>
      </tr>
      <tr>
          <td>Data quality improvement</td>
          <td>Pointblank, Validoopsie</td>
          <td>Gradual quality improvement with threshold tracking</td>
      </tr>
  </tbody>
</table>
</div>
<h2 id="setup">Setup
</h2>
<p>We are going to run through examples with <strong>Pandera</strong>, <strong>Patito</strong>, <strong>Pointblank</strong>, <strong>Validoopsie</strong>,
and <strong>Dataframely</strong>, using this Polars DataFrame as our test case:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">polars</span> <span class="k">as</span> <span class="nn">pl</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Standard dataset for all validation examples</span>
</span></span><span class="line"><span class="cl"><span class="n">user_data</span> <span class="o">=</span> <span class="n">pl</span><span class="o">.</span><span class="n">DataFrame</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;user_id&#34;</span><span class="p">:</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;age&#34;</span><span class="p">:</span> <span class="p">[</span><span class="mi">25</span><span class="p">,</span> <span class="mi">30</span><span class="p">,</span> <span class="mi">22</span><span class="p">,</span> <span class="mi">45</span><span class="p">,</span> <span class="mi">95</span><span class="p">],</span>  <span class="c1"># &lt;- includes a very high age</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;email&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;user1@example.com&#34;</span><span class="p">,</span> <span class="s2">&#34;user2@example.com&#34;</span><span class="p">,</span> <span class="s2">&#34;invalid-email&#34;</span><span class="p">,</span>  <span class="c1"># &lt;- has an invalid email</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;user4@example.com&#34;</span><span class="p">,</span> <span class="s2">&#34;user5@example.com&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">],</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;score&#34;</span><span class="p">:</span> <span class="p">[</span><span class="mf">85.5</span><span class="p">,</span> <span class="mf">92.0</span><span class="p">,</span> <span class="mf">78.3</span><span class="p">,</span> <span class="mf">88.7</span><span class="p">,</span> <span class="mf">95.2</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="p">})</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>We&rsquo;ll try to run the same data validation across the surveyed libraries, so we&rsquo;ll check:</p>
<ul>
<li>schema validation (correct column types)</li>
<li><code>user_id</code> values greater than <code>0</code></li>
<li><code>age</code> values between <code>18</code> and <code>80</code> (inclusive)</li>
<li><code>email</code> strings matching a basic email regex pattern</li>
<li><code>score</code> values between <code>0</code> and <code>100</code> (inclusive)</li>
</ul>
<p>Now let&rsquo;s dive into each library, starting with the statistically-focused Pandera.</p>
<h2 id="1-pandera-schema-first-validation-with-statistical-checks">1. Pandera: Schema-First Validation with Statistical Checks
</h2>
<p>Pandera is a statistical data validation toolkit designed to provide a flexible and expressive API
for performing data validation on dataframe-like objects. The library centers on schema-centric
validation, where you define the expected structure and constraints of your data upfront. You can
enable both runtime validation and static type checking integration. Pandera added Polars support in
version <code>0.19.0</code> (early 2024).</p>
<h3 id="example">Example
</h3>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">pandera.polars</span> <span class="k">as</span> <span class="nn">pa</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Define schema using our standard dataset</span>
</span></span><span class="line"><span class="cl"><span class="n">schema</span> <span class="o">=</span> <span class="n">pa</span><span class="o">.</span><span class="n">DataFrameSchema</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;user_id&#34;</span><span class="p">:</span> <span class="n">pa</span><span class="o">.</span><span class="n">Column</span><span class="p">(</span><span class="n">pl</span><span class="o">.</span><span class="n">Int64</span><span class="p">,</span> <span class="n">checks</span><span class="o">=</span><span class="n">pa</span><span class="o">.</span><span class="n">Check</span><span class="o">.</span><span class="n">gt</span><span class="p">(</span><span class="mi">0</span><span class="p">)),</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;age&#34;</span><span class="p">:</span> <span class="n">pa</span><span class="o">.</span><span class="n">Column</span><span class="p">(</span><span class="n">pl</span><span class="o">.</span><span class="n">Int64</span><span class="p">,</span> <span class="n">checks</span><span class="o">=</span><span class="p">[</span><span class="n">pa</span><span class="o">.</span><span class="n">Check</span><span class="o">.</span><span class="n">ge</span><span class="p">(</span><span class="mi">18</span><span class="p">),</span> <span class="n">pa</span><span class="o">.</span><span class="n">Check</span><span class="o">.</span><span class="n">le</span><span class="p">(</span><span class="mi">80</span><span class="p">)]),</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;email&#34;</span><span class="p">:</span> <span class="n">pa</span><span class="o">.</span><span class="n">Column</span><span class="p">(</span><span class="n">pl</span><span class="o">.</span><span class="n">Utf8</span><span class="p">,</span> <span class="n">checks</span><span class="o">=</span><span class="n">pa</span><span class="o">.</span><span class="n">Check</span><span class="o">.</span><span class="n">str_matches</span><span class="p">(</span><span class="sa">r</span><span class="s2">&#34;^[^@]+@[^@]+\.[^@]+$&#34;</span><span class="p">)),</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;score&#34;</span><span class="p">:</span> <span class="n">pa</span><span class="o">.</span><span class="n">Column</span><span class="p">(</span><span class="n">pl</span><span class="o">.</span><span class="n">Float64</span><span class="p">,</span> <span class="n">checks</span><span class="o">=</span><span class="n">pa</span><span class="o">.</span><span class="n">Check</span><span class="o">.</span><span class="n">in_range</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">100</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="p">})</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Validate the schema</span>
</span></span><span class="line"><span class="cl"><span class="k">try</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="n">validated_data</span> <span class="o">=</span> <span class="n">schema</span><span class="o">.</span><span class="n">validate</span><span class="p">(</span><span class="n">user_data</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;Validation successful!&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="k">except</span> <span class="n">pa</span><span class="o">.</span><span class="n">errors</span><span class="o">.</span><span class="n">SchemaError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;Validation failed: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><pre><code>Validation failed: Column 'age' failed validator number 1: &lt;Check less_than_or_equal_to: less_than_or_equal_to(80)&gt; failure case examples: [{'age': 95}]
</code></pre>
<p>This example demonstrates Pandera&rsquo;s declarative approach, where you define what your data should
look like rather than writing imperative validation logic. The schema acts as both documentation and
as a validation contract. Notice how multiple checks can be applied to a single column (here, the
<code>age</code> column receives two checks), and the validation either succeeds completely or provides
error information about what failed.</p>
<h3 id="comparisons">Comparisons
</h3>
<p>Both Pandera and Patito use declarative, schema-centric approaches, but differ in their design
philosophies:</p>
<ul>
<li>Pandera uses a dictionary-like schema structure with Column objects for defining validation rules</li>
<li>Patito uses Pydantic model classes with familiar Field syntax for validation constraints</li>
<li>Pandera focuses heavily on statistical validation capabilities like hypothesis testing</li>
<li>Patito emphasizes integration with existing Pydantic workflows and object modeling</li>
<li>a key behavioral difference: Patito reports all validation errors in a single pass, while Pandera
stops at the first failure</li>
</ul>
<p>The choice between them often comes down to whether you prefer Pandera&rsquo;s statistical focus or
Patito&rsquo;s Pydantic integration.</p>
<p>Unlike Pointblank&rsquo;s step-by-step validation reporting, Pandera validates the entire schema at once.
Compared to Patito&rsquo;s model-based approach, Pandera focuses more on statistical validation
capabilities. Unlike Validoopsie&rsquo;s and Pointblank&rsquo;s method chaining style, Pandera uses a more
declarative, schema-centric approach.</p>
<h3 id="unique-strengths-and-when-to-use">Unique Strengths and When to Use
</h3>
<p>Here are some of stand-out features that Pandera has:</p>
<ul>
<li>type-safe schema definitions with <code>mypy</code> integration</li>
<li>statistical hypothesis testing for data distributions: perform t-tests, chi-square tests, and
custom statistical tests directly in your validation schema</li>
<li>excellent integration with Pandas, Polars, and Arrow support</li>
<li>declarative schema syntax that serves as documentation</li>
<li>built-in support for data coercion and transformation</li>
</ul>
<p>This statistical validation capability goes beyond basic type and range checking to test actual data
relationships and distributional assumptions. For example, you can validate that the mean height of
group <code>&quot;M&quot;</code> is significantly greater than group <code>&quot;F&quot;</code> using a two-sample t-test, or test whether a
column follows a normal distribution. This makes Pandera uniquely powerful for data science
workflows where the statistical properties of your data are as important as individual data points
meeting basic constraints.</p>
<p>Data practitioners should choose Pandera when building type-safe data pipelines where schema
validation is critical, especially in data science workflows that require statistical validation.
It&rsquo;s ideal for users that value static type checking, need to validate statistical properties of
their data, or want schemas that double as documentation.</p>
<p>Pandera also excels in environments where data contracts between teams are important and where the
statistical properties of data matter as much as basic type checking.</p>
<h2 id="2-patito-pydantic-style-data-models-for-dataframes">2. Patito: Pydantic-Style Data Models for DataFrames
</h2>
<p>Patito brings Pydantic&rsquo;s well-received model-based validation approach to DataFrame validation,
creating a bridge between Pydantic-style data validation and DataFrame processing. The library&rsquo;s
primary goal is to provide a familiar, Pydantic-style interface for defining and validating
DataFrame schemas, making it particularly appealing to developers already using Pydantic in their
applications.</p>
<p>Patito launched with Polars support from the beginning (in late 2022). Native Polars integration is
touted as one of its core features, reflecting the growing adoption of Polars in the Python
ecosystem.</p>
<h3 id="example-1">Example
</h3>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">patito</span> <span class="k">as</span> <span class="nn">pt</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">typing</span> <span class="kn">import</span> <span class="n">Annotated</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">UserModel</span><span class="p">(</span><span class="n">pt</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="n">user_id</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="n">pt</span><span class="o">.</span><span class="n">Field</span><span class="p">(</span><span class="n">gt</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">age</span><span class="p">:</span> <span class="n">Annotated</span><span class="p">[</span><span class="nb">int</span><span class="p">,</span> <span class="n">pt</span><span class="o">.</span><span class="n">Field</span><span class="p">(</span><span class="n">ge</span><span class="o">=</span><span class="mi">18</span><span class="p">,</span> <span class="n">le</span><span class="o">=</span><span class="mi">80</span><span class="p">)]</span>
</span></span><span class="line"><span class="cl">    <span class="n">email</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="n">pt</span><span class="o">.</span><span class="n">Field</span><span class="p">(</span><span class="n">pattern</span><span class="o">=</span><span class="sa">r</span><span class="s2">&#34;^[^@]+@[^@]+\.[^@]+$&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">score</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="n">pt</span><span class="o">.</span><span class="n">Field</span><span class="p">(</span><span class="n">ge</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span> <span class="n">le</span><span class="o">=</span><span class="mf">100.0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Validate using the model</span>
</span></span><span class="line"><span class="cl"><span class="k">try</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="n">UserModel</span><span class="o">.</span><span class="n">validate</span><span class="p">(</span><span class="n">user_data</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;Validation successful!&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="k">except</span> <span class="n">pt</span><span class="o">.</span><span class="n">exceptions</span><span class="o">.</span><span class="n">DataFrameValidationError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;Validation failed: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><pre><code>Validation failed: 2 validation errors for UserModel
age
  1 row with out of bound values. (type=value_error.rowvalue)
email
  1 row with out of bound values. (type=value_error.rowvalue)
</code></pre>
<p>This example showcases Patito&rsquo;s model-centric approach where validation rules are embedded in class
definitions. The use of Python&rsquo;s type hints and Pydantic&rsquo;s Field syntax makes the validation rules
self-documenting. Notably, Patito reports all validation errors at once, providing a fairly
comprehensive view of data quality issues, whereas other libraries (e.g., Pandera) stop at the first
failure.</p>
<h3 id="column-validation-approaches-pandera-vs-patito">Column Validation Approaches: Pandera vs Patito
</h3>
<p><strong>Pandera offers a much more extensive and flexible system for column validation</strong> compared to
Patito&rsquo;s field-based approach. While Patito provides a solid set of built-in field constraints
(like <code>gt</code>, <code>le</code>, <code>regex</code>, <code>unique</code>, etc.) that cover common validation scenarios, Pandera&rsquo;s Check
system is designed for both simple and highly sophisticated validation logic.</p>
<p>The key architectural difference seems to lie in extensibility and complexity. Pandera&rsquo;s <code>Check</code>
objects accept arbitrary functions, allowing you to write custom validation logic that can be as
simple as <code>lambda s: s &gt; 0</code> or as complex as statistical hypothesis tests using scipy. You can
create vectorized checks that operate on entire Series objects for performance, element-wise checks
for atomic validation, and even grouped checks that validate subsets of data based on other columns.
Patito&rsquo;s <code>Field</code> constraints, while clean and declarative, are more limited to the predefined
validation types that Pydantic and Patito provide.</p>
<p>Pandera also supports advanced validation patterns that Patito doesn&rsquo;t directly offer, such as
wide-form data checks (validating relationships across multiple columns), grouped validation (where
checks are applied to subsets of data based on grouping columns), and the ability to raise warnings
instead of errors for non-critical validation failures. While Patito does support custom constraints
through Polars expressions via the <code>constraints</code> parameter, this requires knowledge of Polars
expression syntax and, depending on where you&rsquo;re coming from, could be less intuitive than Pandera&rsquo;s
function-based approach.</p>
<p>For most common validation scenarios, Patito&rsquo;s field-based validation is simpler and more readable,
especially for teams already familiar with Pydantic. However, for complex data validation
requirements, statistical validation, or when you need maximum flexibility in defining validation
logic, Pandera&rsquo;s Check system provides significantly more power and extensibility.</p>
<h3 id="unique-strengths-and-when-to-use-1">Unique Strengths and When to Use
</h3>
<ul>
<li>Pydantic-style model definitions with familiar syntax for Pydantic users</li>
<li>rich type system integration with Python&rsquo;s typing system</li>
<li>model inheritance and composition for complex data structures</li>
<li>seamless integration with existing Pydantic-based applications</li>
<li>row-level object modeling for converting DataFrame rows to Python objects with methods</li>
<li>mock data generation for testing with <code>.examples()</code> method</li>
</ul>
<p>People should choose Patito when they&rsquo;re already using Pydantic in their applications and want
consistent validation patterns across data processing and application logic. It&rsquo;s great when you
need to validate DataFrames and then work with individual rows as rich Python objects with embedded
business logic and methods (e.g., a <code>Product</code> row that has a <code>.url</code> property or
<code>.calculate_discount()</code> method). Patito is also good when you need to generate realistic test data
and want object-oriented interfaces for their data models.</p>
<h2 id="3-pointblank-comprehensive-validation-with-beautiful-reports">3. Pointblank: Comprehensive Validation with Beautiful Reports
</h2>
<p>Pointblank is a comprehensive data validation framework designed to make data quality assessment
both thorough and accessible to stakeholders. Originally inspired by the R package of the same name,
Pointblank&rsquo;s primary mission is to provide validation workflows that generate beautiful, interactive
reports that can be shared with both technical and non-technical team members.</p>
<p>Pointblank launched with Polars support as a core feature from its initial Python release in late
2024, built on top of the Narwhals and Ibis compatibility layers to provide consistent DataFrame
operations across multiple backends including Polars, Pandas, and database connections.</p>
<h3 id="example-2">Example
</h3>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">pointblank</span> <span class="k">as</span> <span class="nn">pb</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">schema</span> <span class="o">=</span> <span class="n">pb</span><span class="o">.</span><span class="n">Schema</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">columns</span><span class="o">=</span><span class="p">[(</span><span class="s2">&#34;user_id&#34;</span><span class="p">,</span> <span class="s2">&#34;Int64&#34;</span><span class="p">),</span> <span class="p">(</span><span class="s2">&#34;age&#34;</span><span class="p">,</span> <span class="s2">&#34;Int64&#34;</span><span class="p">),</span> <span class="p">(</span><span class="s2">&#34;email&#34;</span><span class="p">,</span> <span class="s2">&#34;String&#34;</span><span class="p">),</span> <span class="p">(</span><span class="s2">&#34;score&#34;</span><span class="p">,</span> <span class="s2">&#34;Float64&#34;</span><span class="p">)]</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">validation</span> <span class="o">=</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">pb</span><span class="o">.</span><span class="n">Validate</span><span class="p">(</span><span class="n">data</span><span class="o">=</span><span class="n">user_data</span><span class="p">,</span> <span class="n">label</span><span class="o">=</span><span class="s2">&#34;An example.&#34;</span><span class="p">,</span> <span class="n">tbl_name</span><span class="o">=</span><span class="s2">&#34;users&#34;</span><span class="p">,</span> <span class="n">thresholds</span><span class="o">=</span><span class="p">(</span><span class="mf">0.1</span><span class="p">,</span> <span class="mf">0.2</span><span class="p">,</span> <span class="mf">0.3</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">col_vals_gt</span><span class="p">(</span><span class="n">columns</span><span class="o">=</span><span class="s2">&#34;user_id&#34;</span><span class="p">,</span> <span class="n">value</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">col_vals_between</span><span class="p">(</span><span class="n">columns</span><span class="o">=</span><span class="s2">&#34;age&#34;</span><span class="p">,</span> <span class="n">left</span><span class="o">=</span><span class="mi">18</span><span class="p">,</span> <span class="n">right</span><span class="o">=</span><span class="mi">80</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">col_vals_regex</span><span class="p">(</span><span class="n">columns</span><span class="o">=</span><span class="s2">&#34;email&#34;</span><span class="p">,</span> <span class="n">pattern</span><span class="o">=</span><span class="sa">r</span><span class="s2">&#34;^[^@]+@[^@]+\.[^@]+$&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">col_vals_between</span><span class="p">(</span><span class="n">columns</span><span class="o">=</span><span class="s2">&#34;score&#34;</span><span class="p">,</span> <span class="n">left</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">right</span><span class="o">=</span><span class="mi">100</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">col_schema_match</span><span class="p">(</span><span class="n">schema</span><span class="o">=</span><span class="n">schema</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">interrogate</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">validation</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div id="pb_tbl" style="padding-left:0px;padding-right:0px;padding-top:10px;padding-bottom:10px;overflow-x:auto;overflow-y:auto;width:auto;height:auto;">
<style>
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono&display=swap');
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans&display=swap');
#pb_tbl table {
          font-family: 'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Helvetica Neue', 'Fira Sans', 'Droid Sans', Arial, sans-serif;
          -webkit-font-smoothing: antialiased;
          -moz-osx-font-smoothing: grayscale;
        }
<p>#pb_tbl thead, tbody, tfoot, tr, td, th { border-style: none; }
tr { background-color: transparent; }
#pb_tbl p { margin: 0; padding: 0; }
#pb_tbl .gt_table { display: table; border-collapse: collapse; line-height: normal; margin-left: auto; margin-right: auto; color: #333333; font-size: 90%; font-weight: normal; font-style: normal; background-color: #FFFFFF; width: auto; border-top-style: solid; border-top-width: 2px; border-top-color: #A8A8A8; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #A8A8A8; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; }
#pb_tbl .gt_caption { padding-top: 4px; padding-bottom: 4px; }
#pb_tbl .gt_title { color: #333333; font-size: 125%; font-weight: initial; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; border-bottom-color: #FFFFFF; border-bottom-width: 0; }
#pb_tbl .gt_subtitle { color: #333333; font-size: 85%; font-weight: initial; padding-top: 3px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; border-top-color: #FFFFFF; border-top-width: 0; }
#pb_tbl .gt_heading { background-color: #FFFFFF; text-align: left; border-bottom-color: #FFFFFF; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; }
#pb_tbl .gt_bottom_border { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; }
#pb_tbl .gt_col_headings { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; }
#pb_tbl .gt_col_heading { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; overflow-x: hidden; }
#pb_tbl .gt_column_spanner_outer { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; padding-top: 0; padding-bottom: 0; padding-left: 4px; padding-right: 4px; }
#pb_tbl .gt_column_spanner_outer:first-child { padding-left: 0; }
#pb_tbl .gt_column_spanner_outer:last-child { padding-right: 0; }
#pb_tbl .gt_column_spanner { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; overflow-x: hidden; display: inline-block; width: 100%; }
#pb_tbl .gt_spanner_row { border-bottom-style: hidden; }
#pb_tbl .gt_group_heading { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; text-align: left; }
#pb_tbl .gt_empty_group_heading { padding: 0.5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: middle; }
#pb_tbl .gt_from_md&gt; :first-child { margin-top: 0; }
#pb_tbl .gt_from_md&gt; :last-child { margin-bottom: 0; }
#pb_tbl .gt_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; margin: 10px; border-top-style: solid; border-top-width: 1px; border-top-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; overflow-x: hidden; }
#pb_tbl .gt_stub { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; }
#pb_tbl .gt_stub_row_group { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; vertical-align: top; }
#pb_tbl .gt_row_group_first td { border-top-width: 2px; }
#pb_tbl .gt_row_group_first th { border-top-width: 2px; }
#pb_tbl .gt_striped { color: #333333; background-color: #F4F4F4; }
#pb_tbl .gt_table_body { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; }
#pb_tbl .gt_grand_summary_row { color: #333333; background-color: #FFFFFF; text-transform: inherit; padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; }
#pb_tbl .gt_first_grand_summary_row_bottom { border-top-style: double; border-top-width: 6px; border-top-color: #D3D3D3; }
#pb_tbl .gt_last_grand_summary_row_top { border-bottom-style: double; border-bottom-width: 6px; border-bottom-color: #D3D3D3; }
#pb_tbl .gt_sourcenotes { color: #333333; background-color: #FFFFFF; border-bottom-style: none; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; }
#pb_tbl .gt_sourcenote { font-size: 90%; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; text-align: left; }
#pb_tbl .gt_left { text-align: left; }
#pb_tbl .gt_center { text-align: center; }
#pb_tbl .gt_right { text-align: right; font-variant-numeric: tabular-nums; }
#pb_tbl .gt_font_normal { font-weight: normal; }
#pb_tbl .gt_font_bold { font-weight: bold; }
#pb_tbl .gt_font_italic { font-style: italic; }
#pb_tbl .gt_super { font-size: 65%; }
#pb_tbl .gt_footnote_marks { font-size: 75%; vertical-align: 0.4em; position: initial; }
#pb_tbl .gt_asterisk { font-size: 100%; vertical-align: 0; }</p>
<p></style></p>
<table style="table-layout: fixed;; width: 0px" class="gt_table" data-quarto-disable-processing="true" data-quarto-bootstrap="false">
<colgroup>
  <col style="width:4px;"/>
  <col style="width:35px;"/>
  <col style="width:190px;"/>
  <col style="width:120px;"/>
  <col style="width:120px;"/>
  <col style="width:50px;"/>
  <col style="width:50px;"/>
  <col style="width:60px;"/>
  <col style="width:60px;"/>
  <col style="width:60px;"/>
  <col style="width:30px;"/>
  <col style="width:30px;"/>
  <col style="width:30px;"/>
  <col style="width:65px;"/>
</colgroup>
<thead>
  <tr class="gt_heading">
    <td colspan="14" class="gt_heading gt_title gt_font_normal" style="color: #444444;font-size: 28px;text-align: left;font-weight: bold; text-align: left;">Pointblank Validation</td>
  </tr>
  <tr class="gt_heading">
    <td colspan="14" class="gt_heading gt_subtitle gt_font_normal gt_bottom_border" style="text-align: left;"><div><span style='text-decoration-style: solid; text-decoration-color: #ADD8E6; text-decoration-line: underline; text-underline-position: under; color: #333333; font-variant-numeric: tabular-nums; padding-left: 4px; margin-right: 5px; padding-right: 2px;'>An example.</span><div style="padding-top: 10px; padding-bottom: 5px;"><span style='background-color: #0075FF; color: #FFFFFF; padding: 0.5em 0.5em; position: inherit; text-transform: uppercase; margin: 5px 0px 5px 0px; border: solid 1px #0075FF; font-weight: bold; padding: 2px 15px 2px 15px; font-size: 10px;'>Polars</span><span style='background-color: none; color: #222222; padding: 0.5em 0.5em; position: inherit; margin: 5px 10px 5px -4px; border: solid 1px #0075FF; font-weight: bold; padding: 2px 15px 2px 15px; font-size: 10px;'>users</span><span><span style="background-color: #AAAAAA; color: white; padding: 0.5em 0.5em; position: inherit; text-transform: uppercase; margin: 5px 0px 5px 5px; border: solid 1px #AAAAAA; font-weight: bold; padding: 2px 15px 2px 15px; font-size: smaller;">WARNING</span><span style="background-color: none; color: #333333; padding: 0.5em 0.5em; position: inherit; margin: 5px 0px 5px -4px; font-weight: bold; border: solid 1px #AAAAAA; padding: 2px 15px 2px 15px; font-size: smaller; margin-right: 5px;">0.1</span><span style="background-color: #EBBC14; color: white; padding: 0.5em 0.5em; position: inherit; text-transform: uppercase; margin: 5px 0px 5px 1px; border: solid 1px #EBBC14; font-weight: bold; padding: 2px 15px 2px 15px; font-size: smaller;">ERROR</span><span style="background-color: none; color: #333333; padding: 0.5em 0.5em; position: inherit; margin: 5px 0px 5px -4px; font-weight: bold; border: solid 1px #EBBC14; padding: 2px 15px 2px 15px; font-size: smaller; margin-right: 5px;">0.2</span><span style="background-color: #FF3300; color: white; padding: 0.5em 0.5em; position: inherit; text-transform: uppercase; margin: 5px 0px 5px 1px; border: solid 1px #FF3300; font-weight: bold; padding: 2px 15px 2px 15px; font-size: smaller;">CRITICAL</span><span style="background-color: none; color: #333333; padding: 0.5em 0.5em; position: inherit; margin: 5px 0px 5px -4px; font-weight: bold; border: solid 1px #FF3300; padding: 2px 15px 2px 15px; font-size: smaller;">0.3</span></span></div></div></td>
  </tr>
<tr class="gt_col_headings">
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-status_color"></th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-i"></th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-type_upd">STEP</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-columns_upd">COLUMNS</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-values_upd">VALUES</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-tbl">TBL</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-eval">EVAL</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-test_units">UNITS</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-pass">PASS</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-fail">FAIL</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-w_upd">W</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-e_upd">E</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-c_upd">C</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-extract_upd">EXT</th>
</tr>
</thead>
<tbody class="gt_table_body">
  <tr>
    <td style="height: 40px; background-color: #4CA64C; color: transparent;font-size: 0px;" class="gt_row gt_left">#4CA64C</td>
    <td style="height: 40px; color: #666666;font-size: 13px;font-weight: bold;" class="gt_row gt_right">1</td>
    <td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_left">
        <div style="margin: 0; padding: 0; display: inline-block; height: 30px; vertical-align: middle; width: 16%;">
            <!--?xml version="1.0" encoding="UTF-8"?--><?xml version="1.0" encoding="UTF-8"?>
<svg width="30px" height="30px" viewBox="0 0 67 67" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="background: #FFFFFF;">
    <title>col_vals_gt</title>
    <g id="Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="col_vals_gt" transform="translate(1.500000, 1.500000)" fill-rule="nonzero">
            <path d="M55,0 C57.4852813,0 59.7352813,1.00735931 61.363961,2.63603897 C62.9926407,4.26471863 64,6.51471863 64,9 L64,9 L64,64 L9,64 C6.51471862,64 4.26471862,62.9926407 2.63603897,61.363961 C1.00735931,59.7352814 0,57.4852814 0,55 L0,55 L0,9 C0,6.51471863 1.00735931,4.26471863 2.63603897,2.63603897 C4.26471862,1.00735931 6.51471862,0 9,0 L9,0 L55,0 Z" id="rectangle" stroke="#000000" stroke-width="2" fill="#FFFFFF"></path>
            <path d="M48.7619048,10 L15.2380953,10 C12.3466667,10 10,12.3466667 10,15.2380952 L10,48.7619048 C10,51.6533333 12.3466667,54 15.2380953,54 L48.7619048,54 C51.6533333,54 54,51.6533333 54,48.7619048 L54,15.2380952 C54,12.3466667 51.6533333,10 48.7619048,10 Z M25.2638095,44.3828571 L24.0695238,42.6647619 L39.5847619,32 L24.0695238,21.3352381 L25.2638095,19.6171429 L43.2828572,32 L25.2638095,44.3828571 Z" id="greater_than" fill="#000000"></path>
        </g>
    </g>
</svg>
        </div>
        <div style="font-family: 'IBM Plex Mono', monospace, courier; color: black; font-size: 11px; display: inline-block; vertical-align: middle;">
            <div>col_vals_gt()</div>
        </div>
<pre><code>    &lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;user_id&lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;&quot; class=&quot;gt_row gt_center&quot;&gt;&lt;svg width=&quot;25px&quot; height=&quot;25px&quot; viewBox=&quot;0 0 25 25&quot; version=&quot;1.1&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot; style=&quot;vertical-align: middle;&quot;&gt;
&lt;g id=&quot;unchanged&quot; stroke=&quot;none&quot; stroke-width=&quot;1&quot; fill=&quot;none&quot; fill-rule=&quot;evenodd&quot;&gt;
    &lt;g id=&quot;unchanged&quot; transform=&quot;translate(0.500000, 0.570147)&quot;&gt;
        &lt;rect id=&quot;Rectangle&quot; x=&quot;0.125132506&quot; y=&quot;0&quot; width=&quot;23.749735&quot; height=&quot;23.7894737&quot;&gt;&lt;/rect&gt;
        &lt;path d=&quot;M5.80375046,8.18194736 C3.77191832,8.18194736 2.11875046,9.83495328 2.11875046,11.8669474 C2.11875046,13.8989414 3.77191832,15.5519474 5.80375046,15.5519474 C7.8355826,15.5519474 9.48875046,13.8989414 9.48875046,11.8669474 C9.48875046,9.83495328 7.83552863,8.18194736 5.80375046,8.18194736 Z M5.80375046,14.814915 C4.17821997,14.814915 2.85578285,13.4924778 2.85578285,11.8669474 C2.85578285,10.2414169 4.17821997,8.91897975 5.80375046,8.91897975 C7.42928095,8.91897975 8.75171807,10.2414169 8.75171807,11.8669474 C8.75171807,13.4924778 7.42928095,14.814915 5.80375046,14.814915 Z&quot; id=&quot;Shape&quot; fill=&quot;#000000&quot; fill-rule=&quot;nonzero&quot;&gt;&lt;/path&gt;
        &lt;path d=&quot;M13.9638189,8.699335 C13.9364621,8.70430925 13.9091059,8.71176968 13.8842359,8.71923074 C13.7822704,8.73663967 13.6877654,8.77643115 13.6056956,8.83860518 L10.2433156,11.3852598 C10.0766886,11.5046343 9.97720993,11.6986181 9.97720993,11.9025491 C9.97720993,12.1064807 10.0766886,12.3004639 10.2433156,12.4198383 L13.6056956,14.966493 C13.891697,15.1803725 14.2970729,15.1231721 14.5109517,14.8371707 C14.7248313,14.5511692 14.6676309,14.145794 14.3816294,13.9319145 L12.5313257,12.5392127 L21.8812495,12.5392127 L21.8812495,11.2658854 L12.5313257,11.2658854 L14.3816294,9.87318364 C14.6377872,9.71650453 14.7497006,9.40066014 14.6477351,9.11714553 C14.5482564,8.83363156 14.262255,8.65954352 13.9638189,8.699335 Z&quot; id=&quot;arrow&quot; fill=&quot;#000000&quot; transform=&quot;translate(15.929230, 11.894737) rotate(-180.000000) translate(-15.929230, -11.894737) &quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
&lt;/g&gt;
</code></pre>
<p></svg></td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color:#4CA64C;">✓</span></td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_right">5</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">5<br />1.00</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">0<br />0.00</td>
<td style="height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color: #AAAAAA;">○</span></td>
<td style="height: 40px; background-color: #FCFCFC;" class="gt_row gt_center"><span style="color: #EBBC14;">○</span></td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color: #FF3300;">○</span></td>
<td style="height: 40px;" class="gt_row gt_center">—</td></p>
  </tr>
  <tr>
    <td style="height: 40px; background-color: #EBBC14; color: transparent;font-size: 0px;" class="gt_row gt_left">#EBBC14</td>
    <td style="height: 40px; color: #666666;font-size: 13px;font-weight: bold;" class="gt_row gt_right">2</td>
    <td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_left">
        <div style="margin: 0; padding: 0; display: inline-block; height: 30px; vertical-align: middle; width: 16%;">
            <!--?xml version="1.0" encoding="UTF-8"?--><?xml version="1.0" encoding="UTF-8"?>
<svg width="30px" height="30px" viewBox="0 0 67 67" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <title>col_vals_between</title>
    <g id="Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="col_vals_between" transform="translate(0.000000, 0.206897)">
            <path d="M56.712234,1 C59.1975153,1 61.4475153,2.00735931 63.076195,3.63603897 C64.7048747,5.26471863 65.712234,7.51471863 65.712234,10 L65.712234,10 L65.712234,65 L10.712234,65 C8.22695259,65 5.97695259,63.9926407 4.34827294,62.363961 C2.71959328,60.7352814 1.71223397,58.4852814 1.71223397,56 L1.71223397,56 L1.71223397,10 C1.71223397,7.51471863 2.71959328,5.26471863 4.34827294,3.63603897 C5.97695259,2.00735931 8.22695259,1 10.712234,1 L10.712234,1 Z" id="rectangle" stroke="#000000" stroke-width="2" fill="#FFFFFF"></path>
            <path d="M11.993484,21.96875 C10.962234,22.082031 10.188797,22.964844 10.212234,24 L10.212234,42 C10.200515,42.722656 10.579422,43.390625 11.204422,43.753906 C11.825515,44.121094 12.598953,44.121094 13.220047,43.753906 C13.845047,43.390625 14.223953,42.722656 14.212234,42 L14.212234,24 C14.220047,23.457031 14.009109,22.9375 13.626297,22.554688 C13.243484,22.171875 12.723953,21.960938 12.180984,21.96875 C12.118484,21.964844 12.055984,21.964844 11.993484,21.96875 Z M55.993484,21.96875 C54.962234,22.082031 54.188797,22.964844 54.212234,24 L54.212234,42 C54.200515,42.722656 54.579422,43.390625 55.204422,43.753906 C55.825515,44.121094 56.598953,44.121094 57.220047,43.753906 C57.845047,43.390625 58.223953,42.722656 58.212234,42 L58.212234,24 C58.220047,23.457031 58.009109,22.9375 57.626297,22.554688 C57.243484,22.171875 56.723953,21.960938 56.180984,21.96875 C56.118484,21.964844 56.055984,21.964844 55.993484,21.96875 Z M16.212234,22 C15.661453,22 15.212234,22.449219 15.212234,23 C15.212234,23.550781 15.661453,24 16.212234,24 C16.763015,24 17.212234,23.550781 17.212234,23 C17.212234,22.449219 16.763015,22 16.212234,22 Z M20.212234,22 C19.661453,22 19.212234,22.449219 19.212234,23 C19.212234,23.550781 19.661453,24 20.212234,24 C20.763015,24 21.212234,23.550781 21.212234,23 C21.212234,22.449219 20.763015,22 20.212234,22 Z M24.212234,22 C23.661453,22 23.212234,22.449219 23.212234,23 C23.212234,23.550781 23.661453,24 24.212234,24 C24.763015,24 25.212234,23.550781 25.212234,23 C25.212234,22.449219 24.763015,22 24.212234,22 Z M28.212234,22 C27.661453,22 27.212234,22.449219 27.212234,23 C27.212234,23.550781 27.661453,24 28.212234,24 C28.763015,24 29.212234,23.550781 29.212234,23 C29.212234,22.449219 28.763015,22 28.212234,22 Z M32.212234,22 C31.661453,22 31.212234,22.449219 31.212234,23 C31.212234,23.550781 31.661453,24 32.212234,24 C32.763015,24 33.212234,23.550781 33.212234,23 C33.212234,22.449219 32.763015,22 32.212234,22 Z M36.212234,22 C35.661453,22 35.212234,22.449219 35.212234,23 C35.212234,23.550781 35.661453,24 36.212234,24 C36.763015,24 37.212234,23.550781 37.212234,23 C37.212234,22.449219 36.763015,22 36.212234,22 Z M40.212234,22 C39.661453,22 39.212234,22.449219 39.212234,23 C39.212234,23.550781 39.661453,24 40.212234,24 C40.763015,24 41.212234,23.550781 41.212234,23 C41.212234,22.449219 40.763015,22 40.212234,22 Z M44.212234,22 C43.661453,22 43.212234,22.449219 43.212234,23 C43.212234,23.550781 43.661453,24 44.212234,24 C44.763015,24 45.212234,23.550781 45.212234,23 C45.212234,22.449219 44.763015,22 44.212234,22 Z M48.212234,22 C47.661453,22 47.212234,22.449219 47.212234,23 C47.212234,23.550781 47.661453,24 48.212234,24 C48.763015,24 49.212234,23.550781 49.212234,23 C49.212234,22.449219 48.763015,22 48.212234,22 Z M52.212234,22 C51.661453,22 51.212234,22.449219 51.212234,23 C51.212234,23.550781 51.661453,24 52.212234,24 C52.763015,24 53.212234,23.550781 53.212234,23 C53.212234,22.449219 52.763015,22 52.212234,22 Z M21.462234,27.96875 C21.419265,27.976563 21.376297,27.988281 21.337234,28 C21.177078,28.027344 21.02864,28.089844 20.899734,28.1875 L15.618484,32.1875 C15.356765,32.375 15.200515,32.679688 15.200515,33 C15.200515,33.320313 15.356765,33.625 15.618484,33.8125 L20.899734,37.8125 C21.348953,38.148438 21.985672,38.058594 22.321609,37.609375 C22.657547,37.160156 22.567703,36.523438 22.118484,36.1875 L19.212234,34 L49.212234,34 L46.305984,36.1875 C45.856765,36.523438 45.766922,37.160156 46.102859,37.609375 C46.438797,38.058594 47.075515,38.148438 47.524734,37.8125 L52.805984,33.8125 C53.067703,33.625 53.223953,33.320313 53.223953,33 C53.223953,32.679688 53.067703,32.375 52.805984,32.1875 L47.524734,28.1875 C47.30989,28.027344 47.040359,27.960938 46.774734,28 C46.743484,28 46.712234,28 46.680984,28 C46.282547,28.074219 45.96614,28.382813 45.884109,28.78125 C45.802078,29.179688 45.970047,29.585938 46.305984,29.8125 L49.212234,32 L19.212234,32 L22.118484,29.8125 C22.520828,29.566406 22.696609,29.070313 22.536453,28.625 C22.380203,28.179688 21.930984,27.90625 21.462234,27.96875 Z M16.212234,42 C15.661453,42 15.212234,42.449219 15.212234,43 C15.212234,43.550781 15.661453,44 16.212234,44 C16.763015,44 17.212234,43.550781 17.212234,43 C17.212234,42.449219 16.763015,42 16.212234,42 Z M20.212234,42 C19.661453,42 19.212234,42.449219 19.212234,43 C19.212234,43.550781 19.661453,44 20.212234,44 C20.763015,44 21.212234,43.550781 21.212234,43 C21.212234,42.449219 20.763015,42 20.212234,42 Z M24.212234,42 C23.661453,42 23.212234,42.449219 23.212234,43 C23.212234,43.550781 23.661453,44 24.212234,44 C24.763015,44 25.212234,43.550781 25.212234,43 C25.212234,42.449219 24.763015,42 24.212234,42 Z M28.212234,42 C27.661453,42 27.212234,42.449219 27.212234,43 C27.212234,43.550781 27.661453,44 28.212234,44 C28.763015,44 29.212234,43.550781 29.212234,43 C29.212234,42.449219 28.763015,42 28.212234,42 Z M32.212234,42 C31.661453,42 31.212234,42.449219 31.212234,43 C31.212234,43.550781 31.661453,44 32.212234,44 C32.763015,44 33.212234,43.550781 33.212234,43 C33.212234,42.449219 32.763015,42 32.212234,42 Z M36.212234,42 C35.661453,42 35.212234,42.449219 35.212234,43 C35.212234,43.550781 35.661453,44 36.212234,44 C36.763015,44 37.212234,43.550781 37.212234,43 C37.212234,42.449219 36.763015,42 36.212234,42 Z M40.212234,42 C39.661453,42 39.212234,42.449219 39.212234,43 C39.212234,43.550781 39.661453,44 40.212234,44 C40.763015,44 41.212234,43.550781 41.212234,43 C41.212234,42.449219 40.763015,42 40.212234,42 Z M44.212234,42 C43.661453,42 43.212234,42.449219 43.212234,43 C43.212234,43.550781 43.661453,44 44.212234,44 C44.763015,44 45.212234,43.550781 45.212234,43 C45.212234,42.449219 44.763015,42 44.212234,42 Z M48.212234,42 C47.661453,42 47.212234,42.449219 47.212234,43 C47.212234,43.550781 47.661453,44 48.212234,44 C48.763015,44 49.212234,43.550781 49.212234,43 C49.212234,42.449219 48.763015,42 48.212234,42 Z M52.212234,42 C51.661453,42 51.212234,42.449219 51.212234,43 C51.212234,43.550781 51.661453,44 52.212234,44 C52.763015,44 53.212234,43.550781 53.212234,43 C53.212234,42.449219 52.763015,42 52.212234,42 Z" id="inside_range" fill="#000000" fill-rule="nonzero"></path>
        </g>
    </g>
</svg>
        </div>
        <div style="font-family: 'IBM Plex Mono', monospace, courier; color: black; font-size: 10px; display: inline-block; vertical-align: middle;">
            <div>col_vals_between()</div>
        </div>
<pre><code>    &lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;age&lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;[18, 80]&lt;/td&gt;
&lt;td style=&quot;height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;&quot; class=&quot;gt_row gt_center&quot;&gt;&lt;svg width=&quot;25px&quot; height=&quot;25px&quot; viewBox=&quot;0 0 25 25&quot; version=&quot;1.1&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot; style=&quot;vertical-align: middle;&quot;&gt;
&lt;g id=&quot;unchanged&quot; stroke=&quot;none&quot; stroke-width=&quot;1&quot; fill=&quot;none&quot; fill-rule=&quot;evenodd&quot;&gt;
    &lt;g id=&quot;unchanged&quot; transform=&quot;translate(0.500000, 0.570147)&quot;&gt;
        &lt;rect id=&quot;Rectangle&quot; x=&quot;0.125132506&quot; y=&quot;0&quot; width=&quot;23.749735&quot; height=&quot;23.7894737&quot;&gt;&lt;/rect&gt;
        &lt;path d=&quot;M5.80375046,8.18194736 C3.77191832,8.18194736 2.11875046,9.83495328 2.11875046,11.8669474 C2.11875046,13.8989414 3.77191832,15.5519474 5.80375046,15.5519474 C7.8355826,15.5519474 9.48875046,13.8989414 9.48875046,11.8669474 C9.48875046,9.83495328 7.83552863,8.18194736 5.80375046,8.18194736 Z M5.80375046,14.814915 C4.17821997,14.814915 2.85578285,13.4924778 2.85578285,11.8669474 C2.85578285,10.2414169 4.17821997,8.91897975 5.80375046,8.91897975 C7.42928095,8.91897975 8.75171807,10.2414169 8.75171807,11.8669474 C8.75171807,13.4924778 7.42928095,14.814915 5.80375046,14.814915 Z&quot; id=&quot;Shape&quot; fill=&quot;#000000&quot; fill-rule=&quot;nonzero&quot;&gt;&lt;/path&gt;
        &lt;path d=&quot;M13.9638189,8.699335 C13.9364621,8.70430925 13.9091059,8.71176968 13.8842359,8.71923074 C13.7822704,8.73663967 13.6877654,8.77643115 13.6056956,8.83860518 L10.2433156,11.3852598 C10.0766886,11.5046343 9.97720993,11.6986181 9.97720993,11.9025491 C9.97720993,12.1064807 10.0766886,12.3004639 10.2433156,12.4198383 L13.6056956,14.966493 C13.891697,15.1803725 14.2970729,15.1231721 14.5109517,14.8371707 C14.7248313,14.5511692 14.6676309,14.145794 14.3816294,13.9319145 L12.5313257,12.5392127 L21.8812495,12.5392127 L21.8812495,11.2658854 L12.5313257,11.2658854 L14.3816294,9.87318364 C14.6377872,9.71650453 14.7497006,9.40066014 14.6477351,9.11714553 C14.5482564,8.83363156 14.262255,8.65954352 13.9638189,8.699335 Z&quot; id=&quot;arrow&quot; fill=&quot;#000000&quot; transform=&quot;translate(15.929230, 11.894737) rotate(-180.000000) translate(-15.929230, -11.894737) &quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
&lt;/g&gt;
</code></pre>
<p></svg></td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color:#4CA64C;">✓</span></td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_right">5</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">4<br />0.80</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">1<br />0.20</td>
<td style="height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color: #AAAAAA;">●</span></td>
<td style="height: 40px; background-color: #FCFCFC;" class="gt_row gt_center"><span style="color: #EBBC14;">●</span></td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color: #FF3300;">○</span></td>
<td style="height: 40px;" class="gt_row gt_center"><a href="data:text/csv;base64,X3Jvd19udW1fLHVzZXJfaWQsYWdlLGVtYWlsLHNjb3JlCjUsNSw5NSx1c2VyNUBleGFtcGxlLmNvbSw5NS4yCg==" download="extract_0002.csv"><button style="background-color: #67C2DC; color: #FFFFFF; border: none; padding: 5px; font-weight: bold; cursor: pointer; border-radius: 4px;">CSV</button></a></td></p>
  </tr>
  <tr>
    <td style="height: 40px; background-color: #EBBC14; color: transparent;font-size: 0px;" class="gt_row gt_left">#EBBC14</td>
    <td style="height: 40px; color: #666666;font-size: 13px;font-weight: bold;" class="gt_row gt_right">3</td>
    <td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_left">
        <div style="margin: 0; padding: 0; display: inline-block; height: 30px; vertical-align: middle; width: 16%;">
            <!--?xml version="1.0" encoding="UTF-8"?--><?xml version="1.0" encoding="UTF-8"?>
<svg width="30px" height="30px" viewBox="0 0 67 67" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <title>col_vals_regex</title>
    <g id="Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="col_vals_regex" transform="translate(0.000000, 0.034483)">
            <path d="M56.712234,1 C59.1975153,1 61.4475153,2.00735931 63.076195,3.63603897 C64.7048747,5.26471863 65.712234,7.51471863 65.712234,10 L65.712234,10 L65.712234,65 L10.712234,65 C8.22695259,65 5.97695259,63.9926407 4.34827294,62.363961 C2.71959328,60.7352814 1.71223397,58.4852814 1.71223397,56 L1.71223397,56 L1.71223397,10 C1.71223397,7.51471863 2.71959328,5.26471863 4.34827294,3.63603897 C5.97695259,2.00735931 8.22695259,1 10.712234,1 L10.712234,1 Z" id="rectangle" stroke="#000000" stroke-width="2" fill="#FFFFFF"></path>
            <g id="regex_symbols" transform="translate(18.000000, 12.000000)" fill="#000000" fill-rule="nonzero">
                <path d="M4.17434508,33.013582 C1.94895328,33.013582 0.138006923,34.8245284 0.138006923,37.0499202 C0.138006923,39.275312 1.94895328,41.0862583 4.17434508,41.0862583 C6.39973688,41.0862583 8.21068324,39.275312 8.21068324,37.0499202 C8.21068324,34.8245284 6.39973688,33.013582 4.17434508,33.013582 Z" id="full_stop"></path>
                <path d="M23.9479718,23.3175402 L21.5628264,23.3175402 C21.2344032,23.3175402 20.9665401,23.0520067 20.9665401,22.7212538 L20.9665401,15.1022979 L14.3445004,18.8873192 C14.0626621,19.050366 13.7016292,18.952538 13.5362533,18.6706991 L12.3436806,16.6442575 C12.262157,16.506832 12.2388642,16.3437852 12.2807909,16.1900549 C12.3203879,16.0363251 12.4205455,15.9058874 12.557971,15.8266929 L19.1800101,11.9880994 L12.557971,8.15183511 C12.4205455,8.07264112 12.3203879,7.93987439 12.2807909,7.78614401 C12.2388642,7.63241423 12.262157,7.46936689 12.3413509,7.33194137 L13.5339237,5.30549975 C13.6993001,5.02366143 14.0626621,4.92816199 14.3445004,5.09120934 L20.9665401,8.87390091 L20.9665401,1.25494501 C20.9665401,0.926521818 21.2344032,0.658658658 21.5628264,0.658658658 L23.9479718,0.658658658 C24.2787247,0.658658658 24.5442582,0.926521818 24.5442582,1.25494501 L24.5442582,8.87390091 L31.1662979,5.09120934 C31.4481362,4.92816199 31.8091691,5.02366143 31.9745455,5.30549975 L33.1671182,7.33194137 C33.2486413,7.46936689 33.2719341,7.63241423 33.2300074,7.78614401 C33.1904104,7.93987439 33.0902528,8.07264112 32.9528278,8.15183511 L26.3307882,11.9880994 L32.9528278,15.8243638 C33.0879237,15.9058874 33.1880813,16.0363251 33.2300074,16.1900549 C33.269605,16.3437852 33.2486413,16.506832 33.1671182,16.6442575 L31.9745455,18.6706991 C31.8091691,18.952538 31.4481362,19.050366 31.1662979,18.8849895 L24.5442582,15.1022979 L24.5442582,22.7212538 C24.5442582,23.0520067 24.2787247,23.3175402 23.9479718,23.3175402 Z" id="asterisk"></path>
            </g>
        </g>
    </g>
</svg>
        </div>
        <div style="font-family: 'IBM Plex Mono', monospace, courier; color: black; font-size: 11px; display: inline-block; vertical-align: middle;">
            <div>col_vals_regex()</div>
        </div>
<pre><code>    &lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;email&lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;^[^@]+@[^@]+\.[^@]+$&lt;/td&gt;
&lt;td style=&quot;height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;&quot; class=&quot;gt_row gt_center&quot;&gt;&lt;svg width=&quot;25px&quot; height=&quot;25px&quot; viewBox=&quot;0 0 25 25&quot; version=&quot;1.1&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot; style=&quot;vertical-align: middle;&quot;&gt;
&lt;g id=&quot;unchanged&quot; stroke=&quot;none&quot; stroke-width=&quot;1&quot; fill=&quot;none&quot; fill-rule=&quot;evenodd&quot;&gt;
    &lt;g id=&quot;unchanged&quot; transform=&quot;translate(0.500000, 0.570147)&quot;&gt;
        &lt;rect id=&quot;Rectangle&quot; x=&quot;0.125132506&quot; y=&quot;0&quot; width=&quot;23.749735&quot; height=&quot;23.7894737&quot;&gt;&lt;/rect&gt;
        &lt;path d=&quot;M5.80375046,8.18194736 C3.77191832,8.18194736 2.11875046,9.83495328 2.11875046,11.8669474 C2.11875046,13.8989414 3.77191832,15.5519474 5.80375046,15.5519474 C7.8355826,15.5519474 9.48875046,13.8989414 9.48875046,11.8669474 C9.48875046,9.83495328 7.83552863,8.18194736 5.80375046,8.18194736 Z M5.80375046,14.814915 C4.17821997,14.814915 2.85578285,13.4924778 2.85578285,11.8669474 C2.85578285,10.2414169 4.17821997,8.91897975 5.80375046,8.91897975 C7.42928095,8.91897975 8.75171807,10.2414169 8.75171807,11.8669474 C8.75171807,13.4924778 7.42928095,14.814915 5.80375046,14.814915 Z&quot; id=&quot;Shape&quot; fill=&quot;#000000&quot; fill-rule=&quot;nonzero&quot;&gt;&lt;/path&gt;
        &lt;path d=&quot;M13.9638189,8.699335 C13.9364621,8.70430925 13.9091059,8.71176968 13.8842359,8.71923074 C13.7822704,8.73663967 13.6877654,8.77643115 13.6056956,8.83860518 L10.2433156,11.3852598 C10.0766886,11.5046343 9.97720993,11.6986181 9.97720993,11.9025491 C9.97720993,12.1064807 10.0766886,12.3004639 10.2433156,12.4198383 L13.6056956,14.966493 C13.891697,15.1803725 14.2970729,15.1231721 14.5109517,14.8371707 C14.7248313,14.5511692 14.6676309,14.145794 14.3816294,13.9319145 L12.5313257,12.5392127 L21.8812495,12.5392127 L21.8812495,11.2658854 L12.5313257,11.2658854 L14.3816294,9.87318364 C14.6377872,9.71650453 14.7497006,9.40066014 14.6477351,9.11714553 C14.5482564,8.83363156 14.262255,8.65954352 13.9638189,8.699335 Z&quot; id=&quot;arrow&quot; fill=&quot;#000000&quot; transform=&quot;translate(15.929230, 11.894737) rotate(-180.000000) translate(-15.929230, -11.894737) &quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
&lt;/g&gt;
</code></pre>
<p></svg></td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color:#4CA64C;">✓</span></td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_right">5</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">4<br />0.80</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">1<br />0.20</td>
<td style="height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color: #AAAAAA;">●</span></td>
<td style="height: 40px; background-color: #FCFCFC;" class="gt_row gt_center"><span style="color: #EBBC14;">●</span></td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color: #FF3300;">○</span></td>
<td style="height: 40px;" class="gt_row gt_center"><a href="data:text/csv;base64,X3Jvd19udW1fLHVzZXJfaWQsYWdlLGVtYWlsLHNjb3JlCjMsMywyMixpbnZhbGlkLWVtYWlsLDc4LjMK" download="extract_0003.csv"><button style="background-color: #67C2DC; color: #FFFFFF; border: none; padding: 5px; font-weight: bold; cursor: pointer; border-radius: 4px;">CSV</button></a></td></p>
  </tr>
  <tr>
    <td style="height: 40px; background-color: #4CA64C; color: transparent;font-size: 0px;" class="gt_row gt_left">#4CA64C</td>
    <td style="height: 40px; color: #666666;font-size: 13px;font-weight: bold;" class="gt_row gt_right">4</td>
    <td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_left">
        <div style="margin: 0; padding: 0; display: inline-block; height: 30px; vertical-align: middle; width: 16%;">
            <!--?xml version="1.0" encoding="UTF-8"?--><?xml version="1.0" encoding="UTF-8"?>
<svg width="30px" height="30px" viewBox="0 0 67 67" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <title>col_vals_between</title>
    <g id="Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="col_vals_between" transform="translate(0.000000, 0.206897)">
            <path d="M56.712234,1 C59.1975153,1 61.4475153,2.00735931 63.076195,3.63603897 C64.7048747,5.26471863 65.712234,7.51471863 65.712234,10 L65.712234,10 L65.712234,65 L10.712234,65 C8.22695259,65 5.97695259,63.9926407 4.34827294,62.363961 C2.71959328,60.7352814 1.71223397,58.4852814 1.71223397,56 L1.71223397,56 L1.71223397,10 C1.71223397,7.51471863 2.71959328,5.26471863 4.34827294,3.63603897 C5.97695259,2.00735931 8.22695259,1 10.712234,1 L10.712234,1 Z" id="rectangle" stroke="#000000" stroke-width="2" fill="#FFFFFF"></path>
            <path d="M11.993484,21.96875 C10.962234,22.082031 10.188797,22.964844 10.212234,24 L10.212234,42 C10.200515,42.722656 10.579422,43.390625 11.204422,43.753906 C11.825515,44.121094 12.598953,44.121094 13.220047,43.753906 C13.845047,43.390625 14.223953,42.722656 14.212234,42 L14.212234,24 C14.220047,23.457031 14.009109,22.9375 13.626297,22.554688 C13.243484,22.171875 12.723953,21.960938 12.180984,21.96875 C12.118484,21.964844 12.055984,21.964844 11.993484,21.96875 Z M55.993484,21.96875 C54.962234,22.082031 54.188797,22.964844 54.212234,24 L54.212234,42 C54.200515,42.722656 54.579422,43.390625 55.204422,43.753906 C55.825515,44.121094 56.598953,44.121094 57.220047,43.753906 C57.845047,43.390625 58.223953,42.722656 58.212234,42 L58.212234,24 C58.220047,23.457031 58.009109,22.9375 57.626297,22.554688 C57.243484,22.171875 56.723953,21.960938 56.180984,21.96875 C56.118484,21.964844 56.055984,21.964844 55.993484,21.96875 Z M16.212234,22 C15.661453,22 15.212234,22.449219 15.212234,23 C15.212234,23.550781 15.661453,24 16.212234,24 C16.763015,24 17.212234,23.550781 17.212234,23 C17.212234,22.449219 16.763015,22 16.212234,22 Z M20.212234,22 C19.661453,22 19.212234,22.449219 19.212234,23 C19.212234,23.550781 19.661453,24 20.212234,24 C20.763015,24 21.212234,23.550781 21.212234,23 C21.212234,22.449219 20.763015,22 20.212234,22 Z M24.212234,22 C23.661453,22 23.212234,22.449219 23.212234,23 C23.212234,23.550781 23.661453,24 24.212234,24 C24.763015,24 25.212234,23.550781 25.212234,23 C25.212234,22.449219 24.763015,22 24.212234,22 Z M28.212234,22 C27.661453,22 27.212234,22.449219 27.212234,23 C27.212234,23.550781 27.661453,24 28.212234,24 C28.763015,24 29.212234,23.550781 29.212234,23 C29.212234,22.449219 28.763015,22 28.212234,22 Z M32.212234,22 C31.661453,22 31.212234,22.449219 31.212234,23 C31.212234,23.550781 31.661453,24 32.212234,24 C32.763015,24 33.212234,23.550781 33.212234,23 C33.212234,22.449219 32.763015,22 32.212234,22 Z M36.212234,22 C35.661453,22 35.212234,22.449219 35.212234,23 C35.212234,23.550781 35.661453,24 36.212234,24 C36.763015,24 37.212234,23.550781 37.212234,23 C37.212234,22.449219 36.763015,22 36.212234,22 Z M40.212234,22 C39.661453,22 39.212234,22.449219 39.212234,23 C39.212234,23.550781 39.661453,24 40.212234,24 C40.763015,24 41.212234,23.550781 41.212234,23 C41.212234,22.449219 40.763015,22 40.212234,22 Z M44.212234,22 C43.661453,22 43.212234,22.449219 43.212234,23 C43.212234,23.550781 43.661453,24 44.212234,24 C44.763015,24 45.212234,23.550781 45.212234,23 C45.212234,22.449219 44.763015,22 44.212234,22 Z M48.212234,22 C47.661453,22 47.212234,22.449219 47.212234,23 C47.212234,23.550781 47.661453,24 48.212234,24 C48.763015,24 49.212234,23.550781 49.212234,23 C49.212234,22.449219 48.763015,22 48.212234,22 Z M52.212234,22 C51.661453,22 51.212234,22.449219 51.212234,23 C51.212234,23.550781 51.661453,24 52.212234,24 C52.763015,24 53.212234,23.550781 53.212234,23 C53.212234,22.449219 52.763015,22 52.212234,22 Z M21.462234,27.96875 C21.419265,27.976563 21.376297,27.988281 21.337234,28 C21.177078,28.027344 21.02864,28.089844 20.899734,28.1875 L15.618484,32.1875 C15.356765,32.375 15.200515,32.679688 15.200515,33 C15.200515,33.320313 15.356765,33.625 15.618484,33.8125 L20.899734,37.8125 C21.348953,38.148438 21.985672,38.058594 22.321609,37.609375 C22.657547,37.160156 22.567703,36.523438 22.118484,36.1875 L19.212234,34 L49.212234,34 L46.305984,36.1875 C45.856765,36.523438 45.766922,37.160156 46.102859,37.609375 C46.438797,38.058594 47.075515,38.148438 47.524734,37.8125 L52.805984,33.8125 C53.067703,33.625 53.223953,33.320313 53.223953,33 C53.223953,32.679688 53.067703,32.375 52.805984,32.1875 L47.524734,28.1875 C47.30989,28.027344 47.040359,27.960938 46.774734,28 C46.743484,28 46.712234,28 46.680984,28 C46.282547,28.074219 45.96614,28.382813 45.884109,28.78125 C45.802078,29.179688 45.970047,29.585938 46.305984,29.8125 L49.212234,32 L19.212234,32 L22.118484,29.8125 C22.520828,29.566406 22.696609,29.070313 22.536453,28.625 C22.380203,28.179688 21.930984,27.90625 21.462234,27.96875 Z M16.212234,42 C15.661453,42 15.212234,42.449219 15.212234,43 C15.212234,43.550781 15.661453,44 16.212234,44 C16.763015,44 17.212234,43.550781 17.212234,43 C17.212234,42.449219 16.763015,42 16.212234,42 Z M20.212234,42 C19.661453,42 19.212234,42.449219 19.212234,43 C19.212234,43.550781 19.661453,44 20.212234,44 C20.763015,44 21.212234,43.550781 21.212234,43 C21.212234,42.449219 20.763015,42 20.212234,42 Z M24.212234,42 C23.661453,42 23.212234,42.449219 23.212234,43 C23.212234,43.550781 23.661453,44 24.212234,44 C24.763015,44 25.212234,43.550781 25.212234,43 C25.212234,42.449219 24.763015,42 24.212234,42 Z M28.212234,42 C27.661453,42 27.212234,42.449219 27.212234,43 C27.212234,43.550781 27.661453,44 28.212234,44 C28.763015,44 29.212234,43.550781 29.212234,43 C29.212234,42.449219 28.763015,42 28.212234,42 Z M32.212234,42 C31.661453,42 31.212234,42.449219 31.212234,43 C31.212234,43.550781 31.661453,44 32.212234,44 C32.763015,44 33.212234,43.550781 33.212234,43 C33.212234,42.449219 32.763015,42 32.212234,42 Z M36.212234,42 C35.661453,42 35.212234,42.449219 35.212234,43 C35.212234,43.550781 35.661453,44 36.212234,44 C36.763015,44 37.212234,43.550781 37.212234,43 C37.212234,42.449219 36.763015,42 36.212234,42 Z M40.212234,42 C39.661453,42 39.212234,42.449219 39.212234,43 C39.212234,43.550781 39.661453,44 40.212234,44 C40.763015,44 41.212234,43.550781 41.212234,43 C41.212234,42.449219 40.763015,42 40.212234,42 Z M44.212234,42 C43.661453,42 43.212234,42.449219 43.212234,43 C43.212234,43.550781 43.661453,44 44.212234,44 C44.763015,44 45.212234,43.550781 45.212234,43 C45.212234,42.449219 44.763015,42 44.212234,42 Z M48.212234,42 C47.661453,42 47.212234,42.449219 47.212234,43 C47.212234,43.550781 47.661453,44 48.212234,44 C48.763015,44 49.212234,43.550781 49.212234,43 C49.212234,42.449219 48.763015,42 48.212234,42 Z M52.212234,42 C51.661453,42 51.212234,42.449219 51.212234,43 C51.212234,43.550781 51.661453,44 52.212234,44 C52.763015,44 53.212234,43.550781 53.212234,43 C53.212234,42.449219 52.763015,42 52.212234,42 Z" id="inside_range" fill="#000000" fill-rule="nonzero"></path>
        </g>
    </g>
</svg>
        </div>
        <div style="font-family: 'IBM Plex Mono', monospace, courier; color: black; font-size: 10px; display: inline-block; vertical-align: middle;">
            <div>col_vals_between()</div>
        </div>
<pre><code>    &lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;score&lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;[0, 100]&lt;/td&gt;
&lt;td style=&quot;height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;&quot; class=&quot;gt_row gt_center&quot;&gt;&lt;svg width=&quot;25px&quot; height=&quot;25px&quot; viewBox=&quot;0 0 25 25&quot; version=&quot;1.1&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot; style=&quot;vertical-align: middle;&quot;&gt;
&lt;g id=&quot;unchanged&quot; stroke=&quot;none&quot; stroke-width=&quot;1&quot; fill=&quot;none&quot; fill-rule=&quot;evenodd&quot;&gt;
    &lt;g id=&quot;unchanged&quot; transform=&quot;translate(0.500000, 0.570147)&quot;&gt;
        &lt;rect id=&quot;Rectangle&quot; x=&quot;0.125132506&quot; y=&quot;0&quot; width=&quot;23.749735&quot; height=&quot;23.7894737&quot;&gt;&lt;/rect&gt;
        &lt;path d=&quot;M5.80375046,8.18194736 C3.77191832,8.18194736 2.11875046,9.83495328 2.11875046,11.8669474 C2.11875046,13.8989414 3.77191832,15.5519474 5.80375046,15.5519474 C7.8355826,15.5519474 9.48875046,13.8989414 9.48875046,11.8669474 C9.48875046,9.83495328 7.83552863,8.18194736 5.80375046,8.18194736 Z M5.80375046,14.814915 C4.17821997,14.814915 2.85578285,13.4924778 2.85578285,11.8669474 C2.85578285,10.2414169 4.17821997,8.91897975 5.80375046,8.91897975 C7.42928095,8.91897975 8.75171807,10.2414169 8.75171807,11.8669474 C8.75171807,13.4924778 7.42928095,14.814915 5.80375046,14.814915 Z&quot; id=&quot;Shape&quot; fill=&quot;#000000&quot; fill-rule=&quot;nonzero&quot;&gt;&lt;/path&gt;
        &lt;path d=&quot;M13.9638189,8.699335 C13.9364621,8.70430925 13.9091059,8.71176968 13.8842359,8.71923074 C13.7822704,8.73663967 13.6877654,8.77643115 13.6056956,8.83860518 L10.2433156,11.3852598 C10.0766886,11.5046343 9.97720993,11.6986181 9.97720993,11.9025491 C9.97720993,12.1064807 10.0766886,12.3004639 10.2433156,12.4198383 L13.6056956,14.966493 C13.891697,15.1803725 14.2970729,15.1231721 14.5109517,14.8371707 C14.7248313,14.5511692 14.6676309,14.145794 14.3816294,13.9319145 L12.5313257,12.5392127 L21.8812495,12.5392127 L21.8812495,11.2658854 L12.5313257,11.2658854 L14.3816294,9.87318364 C14.6377872,9.71650453 14.7497006,9.40066014 14.6477351,9.11714553 C14.5482564,8.83363156 14.262255,8.65954352 13.9638189,8.699335 Z&quot; id=&quot;arrow&quot; fill=&quot;#000000&quot; transform=&quot;translate(15.929230, 11.894737) rotate(-180.000000) translate(-15.929230, -11.894737) &quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
&lt;/g&gt;
</code></pre>
<p></svg></td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color:#4CA64C;">✓</span></td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_right">5</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">5<br />1.00</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">0<br />0.00</td>
<td style="height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color: #AAAAAA;">○</span></td>
<td style="height: 40px; background-color: #FCFCFC;" class="gt_row gt_center"><span style="color: #EBBC14;">○</span></td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color: #FF3300;">○</span></td>
<td style="height: 40px;" class="gt_row gt_center">—</td></p>
  </tr>
  <tr>
    <td style="height: 40px; background-color: #4CA64C; color: transparent;font-size: 0px;" class="gt_row gt_left">#4CA64C</td>
    <td style="height: 40px; color: #666666;font-size: 13px;font-weight: bold;" class="gt_row gt_right">5</td>
    <td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_left">
        <div style="margin: 0; padding: 0; display: inline-block; height: 30px; vertical-align: middle; width: 16%;">
            <!--?xml version="1.0" encoding="UTF-8"?--><?xml version="1.0" encoding="UTF-8"?>
<svg width="30px" height="30px" viewBox="0 0 67 67" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <title>col_schema_match</title>
    <g id="Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="col_schema_match" transform="translate(0.000000, 0.310345)">
            <path d="M56.712234,1.01466935 C59.1975153,1.01466935 61.4475153,2.02202867 63.076195,3.65070832 C64.7048747,5.27938798 65.712234,7.52938798 65.712234,10.0146694 L65.712234,10.0146694 L65.712234,65.0146694 L10.712234,65.0146694 C8.22695259,65.0146694 5.97695259,64.00731 4.34827294,62.3786304 C2.71959328,60.7499507 1.71223397,58.4999507 1.71223397,56.0146694 L1.71223397,56.0146694 L1.71223397,10.0146694 C1.71223397,7.52938798 2.71959328,5.27938798 4.34827294,3.65070832 C5.97695259,2.02202867 8.22695259,1.01466935 10.712234,1.01466935 L10.712234,1.01466935 Z" id="rectangle" stroke="#000000" stroke-width="2" fill="#FFFFFF"></path>
            <path d="M53.712234,39.7885268 L54.212234,56.2885268 L42.212234,56.7885268 L42.212234,39.7885268 L53.712234,39.7885268 Z M39.712234,39.7885268 L39.712234,56.7885268 L27.712234,56.7885268 L27.712234,39.7885268 L39.712234,39.7885268 Z M25.212234,39.7885268 L25.212234,56.7885268 L13.712234,56.7885268 L13.212234,40.2885268 L25.212234,39.7885268 Z" id="columns_schema" stroke="#000000" fill-rule="nonzero"></path>
            <g id="vertical_equal" transform="translate(30.000000, 29.000000)" stroke="#000000" stroke-linecap="square">
                <line x1="2.21223397" y1="0.514669353" x2="2.21223397" y2="7.58573716" id="Line"></line>
                <line x1="5.21223397" y1="0.514669353" x2="5.21223397" y2="7.58573716" id="Line-Copy"></line>
            </g>
            <path d="M41.712234,9.01466935 L41.712234,27.0146694 L53.712234,27.0146694 C54.262234,27.0146694 54.712234,26.5646694 54.712234,26.0146694 L54.712234,10.0146694 C54.712234,9.46466935 54.262234,9.01466935 53.712234,9.01466935 L41.712234,9.01466935 Z M27.212234,9.01466935 C27.212234,9.01466935 27.212234,15.0146694 27.212234,27.0146694 L40.212234,27.0146694 L40.212234,9.01466935 C31.5455673,9.01466935 27.212234,9.01466935 27.212234,9.01466935 Z M13.712234,9.01466935 C13.162234,9.01466935 12.712234,9.46466935 12.712234,10.0146694 L12.712234,26.0146694 C12.712234,26.5646694 13.162234,27.0146694 13.712234,27.0146694 L25.712234,27.0146694 L25.712234,9.01466935 L13.712234,9.01466935 Z" id="columns_real" fill="#000000" fill-rule="nonzero"></path>
        </g>
    </g>
</svg>
        </div>
        <div style="font-family: 'IBM Plex Mono', monospace, courier; color: black; font-size: 10px; display: inline-block; vertical-align: middle;">
            <div>col_schema_match()</div>
        </div>
<pre><code>    &lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;&amp;mdash;&lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;SCHEMA&lt;/td&gt;
&lt;td style=&quot;height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;&quot; class=&quot;gt_row gt_center&quot;&gt;&lt;svg width=&quot;25px&quot; height=&quot;25px&quot; viewBox=&quot;0 0 25 25&quot; version=&quot;1.1&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot; style=&quot;vertical-align: middle;&quot;&gt;
&lt;g id=&quot;unchanged&quot; stroke=&quot;none&quot; stroke-width=&quot;1&quot; fill=&quot;none&quot; fill-rule=&quot;evenodd&quot;&gt;
    &lt;g id=&quot;unchanged&quot; transform=&quot;translate(0.500000, 0.570147)&quot;&gt;
        &lt;rect id=&quot;Rectangle&quot; x=&quot;0.125132506&quot; y=&quot;0&quot; width=&quot;23.749735&quot; height=&quot;23.7894737&quot;&gt;&lt;/rect&gt;
        &lt;path d=&quot;M5.80375046,8.18194736 C3.77191832,8.18194736 2.11875046,9.83495328 2.11875046,11.8669474 C2.11875046,13.8989414 3.77191832,15.5519474 5.80375046,15.5519474 C7.8355826,15.5519474 9.48875046,13.8989414 9.48875046,11.8669474 C9.48875046,9.83495328 7.83552863,8.18194736 5.80375046,8.18194736 Z M5.80375046,14.814915 C4.17821997,14.814915 2.85578285,13.4924778 2.85578285,11.8669474 C2.85578285,10.2414169 4.17821997,8.91897975 5.80375046,8.91897975 C7.42928095,8.91897975 8.75171807,10.2414169 8.75171807,11.8669474 C8.75171807,13.4924778 7.42928095,14.814915 5.80375046,14.814915 Z&quot; id=&quot;Shape&quot; fill=&quot;#000000&quot; fill-rule=&quot;nonzero&quot;&gt;&lt;/path&gt;
        &lt;path d=&quot;M13.9638189,8.699335 C13.9364621,8.70430925 13.9091059,8.71176968 13.8842359,8.71923074 C13.7822704,8.73663967 13.6877654,8.77643115 13.6056956,8.83860518 L10.2433156,11.3852598 C10.0766886,11.5046343 9.97720993,11.6986181 9.97720993,11.9025491 C9.97720993,12.1064807 10.0766886,12.3004639 10.2433156,12.4198383 L13.6056956,14.966493 C13.891697,15.1803725 14.2970729,15.1231721 14.5109517,14.8371707 C14.7248313,14.5511692 14.6676309,14.145794 14.3816294,13.9319145 L12.5313257,12.5392127 L21.8812495,12.5392127 L21.8812495,11.2658854 L12.5313257,11.2658854 L14.3816294,9.87318364 C14.6377872,9.71650453 14.7497006,9.40066014 14.6477351,9.11714553 C14.5482564,8.83363156 14.262255,8.65954352 13.9638189,8.699335 Z&quot; id=&quot;arrow&quot; fill=&quot;#000000&quot; transform=&quot;translate(15.929230, 11.894737) rotate(-180.000000) translate(-15.929230, -11.894737) &quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
&lt;/g&gt;
</code></pre>
<p></svg></td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color:#4CA64C;">✓</span></td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_right">1</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">1<br />1.00</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">0<br />0.00</td>
<td style="height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color: #AAAAAA;">○</span></td>
<td style="height: 40px; background-color: #FCFCFC;" class="gt_row gt_center"><span style="color: #EBBC14;">○</span></td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color: #FF3300;">○</span></td>
<td style="height: 40px;" class="gt_row gt_center">—</td></p>
  </tr>
</tbody>
  <tfoot class="gt_sourcenotes">
  <tr>
    <td class="gt_sourcenote" colspan="14" style="text-align: left;"><div style='margin-top: 5px; margin-bottom: 5px;'><span style='background-color: #FFF; color: #444; padding: 0.5em 0.5em; position: inherit; text-transform: uppercase; margin-left: 10px; margin-right: 5px; border: solid 1px #999999; font-variant-numeric: tabular-nums; border-radius: 0; padding: 2px 10px 2px 10px;'>2026-04-02 19:07:38 UTC</span><span style='background-color: #FFF; color: #444; padding: 0.5em 0.5em; position: inherit; margin-right: 5px; border: solid 1px #999999; font-variant-numeric: tabular-nums; border-radius: 0; padding: 2px 10px 2px 10px;'>< 1 s</span><span style='background-color: #FFF; color: #444; padding: 0.5em 0.5em; position: inherit; text-transform: uppercase; margin: 5px 1px 5px -1px; border: solid 1px #999999; font-variant-numeric: tabular-nums; border-radius: 0; padding: 2px 10px 2px 10px;'>2026-04-02 19:07:38 UTC</span></div></td>
  </tr>
  <tr>
    <td class="gt_sourcenote" colspan="14" style="text-align: left;"><hr style='border: none; border-top-width: 1px; border-top-style: dotted; border-top-color: #B5B5B5; margin-top: -3px; margin-bottom: 3px;'>
<strong>Notes</strong>
<p><span style='font-variant: small-caps; font-weight: bold; font-size: smaller; text-transform: uppercase; color: #333333;'>Step 5</span> <span style='font-family: "IBM Plex Mono", monospace; font-size: smaller;'>(schema_check)</span> <span style="color:#4CA64C;">✓</span> Schema validation <strong>passed</strong>.</p>
<details style="margin-top: 2px; margin-bottom: 8px; font-size: 12px; text-indent: 12px;">
<summary style="cursor: pointer; font-weight: bold; color: #555; margin-bottom: -5px;">Schema Comparison</summary>
<div style="margin-top: 6px; padding-left: 15px; padding-right: 15px;">
<div id="pb_step_tbl" style="padding-left:0px;padding-right:0px;padding-top:10px;padding-bottom:10px;overflow-x:auto;overflow-y:auto;width:auto;height:auto;">
<style>
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono&display=swap');
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans&display=swap');
#pb_step_tbl table {
          font-family: 'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Helvetica Neue', 'Fira Sans', 'Droid Sans', Arial, sans-serif;
          -webkit-font-smoothing: antialiased;
          -moz-osx-font-smoothing: grayscale;
        }
<p>#pb_step_tbl thead, tbody, tfoot, tr, td, th { border-style: none; }
tr { background-color: transparent; }
#pb_step_tbl p { margin: 0; padding: 0; }
#pb_step_tbl .gt_table { display: table; border-collapse: collapse; line-height: normal; margin-left: auto; margin-right: auto; color: #333333; font-size: 16px; font-weight: normal; font-style: normal; background-color: #FFFFFF; width: auto; border-top-style: solid; border-top-width: 2px; border-top-color: #A8A8A8; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #A8A8A8; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; }
#pb_step_tbl .gt_caption { padding-top: 4px; padding-bottom: 4px; }
#pb_step_tbl .gt_title { color: #333333; font-size: 125%; font-weight: initial; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; border-bottom-color: #FFFFFF; border-bottom-width: 0; }
#pb_step_tbl .gt_subtitle { color: #333333; font-size: 85%; font-weight: initial; padding-top: 3px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; border-top-color: #FFFFFF; border-top-width: 0; }
#pb_step_tbl .gt_heading { background-color: #FFFFFF; text-align: left; border-bottom-color: #FFFFFF; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; }
#pb_step_tbl .gt_bottom_border { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; }
#pb_step_tbl .gt_col_headings { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; }
#pb_step_tbl .gt_col_heading { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; overflow-x: hidden; }
#pb_step_tbl .gt_column_spanner_outer { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; padding-top: 0; padding-bottom: 0; padding-left: 4px; padding-right: 4px; }
#pb_step_tbl .gt_column_spanner_outer:first-child { padding-left: 0; }
#pb_step_tbl .gt_column_spanner_outer:last-child { padding-right: 0; }
#pb_step_tbl .gt_column_spanner { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; overflow-x: hidden; display: inline-block; width: 100%; }
#pb_step_tbl .gt_spanner_row { border-bottom-style: hidden; }
#pb_step_tbl .gt_group_heading { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; text-align: left; }
#pb_step_tbl .gt_empty_group_heading { padding: 0.5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: middle; }
#pb_step_tbl .gt_from_md&gt; :first-child { margin-top: 0; }
#pb_step_tbl .gt_from_md&gt; :last-child { margin-bottom: 0; }
#pb_step_tbl .gt_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; margin: 10px; border-top-style: solid; border-top-width: 1px; border-top-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; overflow-x: hidden; }
#pb_step_tbl .gt_stub { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; }
#pb_step_tbl .gt_stub_row_group { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; vertical-align: top; }
#pb_step_tbl .gt_row_group_first td { border-top-width: 2px; }
#pb_step_tbl .gt_row_group_first th { border-top-width: 2px; }
#pb_step_tbl .gt_striped { color: #333333; background-color: #F4F4F4; }
#pb_step_tbl .gt_table_body { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; }
#pb_step_tbl .gt_grand_summary_row { color: #333333; background-color: #FFFFFF; text-transform: inherit; padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; }
#pb_step_tbl .gt_first_grand_summary_row_bottom { border-top-style: double; border-top-width: 6px; border-top-color: #D3D3D3; }
#pb_step_tbl .gt_last_grand_summary_row_top { border-bottom-style: double; border-bottom-width: 6px; border-bottom-color: #D3D3D3; }
#pb_step_tbl .gt_sourcenotes { color: #333333; background-color: #FFFFFF; border-bottom-style: none; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; }
#pb_step_tbl .gt_sourcenote { font-size: 12px; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; text-align: left; }
#pb_step_tbl .gt_left { text-align: left; }
#pb_step_tbl .gt_center { text-align: center; }
#pb_step_tbl .gt_right { text-align: right; font-variant-numeric: tabular-nums; }
#pb_step_tbl .gt_font_normal { font-weight: normal; }
#pb_step_tbl .gt_font_bold { font-weight: bold; }
#pb_step_tbl .gt_font_italic { font-style: italic; }
#pb_step_tbl .gt_super { font-size: 65%; }
#pb_step_tbl .gt_footnote_marks { font-size: 75%; vertical-align: 0.4em; position: initial; }
#pb_step_tbl .gt_asterisk { font-size: 100%; vertical-align: 0; }</p>
</style>
<table style="table-layout: fixed;; width: 0px" class="gt_table" data-quarto-disable-processing="true" data-quarto-bootstrap="false">
<colgroup>
  <col style="width:40px;"/>
  <col style="width:190px;"/>
  <col style="width:190px;"/>
  <col style="width:40px;"/>
  <col style="width:190px;"/>
  <col style="width:30px;"/>
  <col style="width:190px;"/>
  <col style="width:30px;"/>
</colgroup>
<thead>
<tr class="gt_col_headings gt_spanner_row">
  <th class="gt_center gt_columns_top_border gt_column_spanner_outer" rowspan="1" colspan="3" scope="colgroup" id="pb_step_tbl-TARGET">
    <span class="gt_column_spanner">TARGET</span>
  </th>
  <th class="gt_center gt_columns_top_border gt_column_spanner_outer" rowspan="1" colspan="5" scope="colgroup" id="pb_step_tbl-EXPECTED">
    <span class="gt_column_spanner">EXPECTED</span>
  </th>
</tr>
<tr class="gt_col_headings">
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" scope="col" id="pb_step_tbl-index_target"></th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" scope="col" id="pb_step_tbl-col_name_target">COLUMN</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" scope="col" id="pb_step_tbl-dtype_target">DATA TYPE</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" scope="col" id="pb_step_tbl-index_exp"></th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" scope="col" id="pb_step_tbl-col_name_exp">COLUMN</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" scope="col" id="pb_step_tbl-col_name_exp_correct"></th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" scope="col" id="pb_step_tbl-dtype_exp">DATA TYPE</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" scope="col" id="pb_step_tbl-dtype_exp_correct"></th>
</tr>
</thead>
<tbody class="gt_table_body">
  <tr>
    <td style="font-size: 13px;" class="gt_row gt_right">1</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">user_id</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">Int64</td>
    <td style="font-size: 13px; border-left: 3px double #E5E5E5;" class="gt_row gt_right">1</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">user_id</td>
    <td class="gt_row gt_left"><span style='color: #4CA64C;'>✓</span></td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">Int64</td>
    <td class="gt_row gt_left"><span style='color: #4CA64C;'>✓</span></td>
  </tr>
  <tr>
    <td style="font-size: 13px;" class="gt_row gt_right">2</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">age</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">Int64</td>
    <td style="font-size: 13px; border-left: 3px double #E5E5E5;" class="gt_row gt_right">2</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">age</td>
    <td class="gt_row gt_left"><span style='color: #4CA64C;'>✓</span></td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">Int64</td>
    <td class="gt_row gt_left"><span style='color: #4CA64C;'>✓</span></td>
  </tr>
  <tr>
    <td style="font-size: 13px;" class="gt_row gt_right">3</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">email</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">String</td>
    <td style="font-size: 13px; border-left: 3px double #E5E5E5;" class="gt_row gt_right">3</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">email</td>
    <td class="gt_row gt_left"><span style='color: #4CA64C;'>✓</span></td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">String</td>
    <td class="gt_row gt_left"><span style='color: #4CA64C;'>✓</span></td>
  </tr>
  <tr>
    <td style="font-size: 13px;" class="gt_row gt_right">4</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">score</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">Float64</td>
    <td style="font-size: 13px; border-left: 3px double #E5E5E5;" class="gt_row gt_right">4</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">score</td>
    <td class="gt_row gt_left"><span style='color: #4CA64C;'>✓</span></td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">Float64</td>
    <td class="gt_row gt_left"><span style='color: #4CA64C;'>✓</span></td>
  </tr>
</tbody>
  <tfoot class="gt_sourcenotes">
  <tr>
    <td class="gt_sourcenote" colspan="8"><div style='padding-bottom: 2px;'>Supplied Column Schema:</div><div style='border-style: solid; border-width: thin; border-color: lightblue; padding-left: 2px; padding-right: 2px; padding-bottom: 3px;'><code style='color: #303030; font-family: monospace; font-size: 8px;'>[('user_id', 'Int64'), ('age', 'Int64'), ('email', 'String'), ('score', 'Float64')]</code></div></td>
  </tr>
  <tr>
    <td class="gt_sourcenote" colspan="8">
<div style='padding-bottom: 2px;'>Schema Match Settings</div>
<div style='padding-bottom: 4px;'><div style="display: flex; font-size: 13.7px; padding-top: 2px;"><div style="border-style: solid; border-width: 1px; border-color: #87CEFA; border-radius: 5px; background-color: #F0F8FF; font-size: x-small; padding-left: 4px; padding-right: 4px; margin-left: 5px; margin-right: 5px;  margin-top: 2px; ">COMPLETE</div><div style="border-style: solid; border-width: 1px; border-color: #87CEFA; border-radius: 5px; background-color: #F0F8FF; font-size: x-small; padding-left: 4px; padding-right: 4px; margin-left: 5px; margin-right: 5px;  margin-top: 2px; ">IN ORDER</div><div style="border-style: solid; border-width: 1px; border-color: #A9A9A9; border-radius: 5px; background-color: #F5F5F5; font-size: x-small; padding-left: 4px; padding-right: 4px; margin-left: 5px; margin-right: 5px;  margin-top: 2px; ">COLUMN &ne; column</div><div style="border-style: solid; border-width: 1px; border-color: #A9A9A9; border-radius: 5px; background-color: #F5F5F5; font-size: x-small; padding-left: 4px; padding-right: 4px; margin-left: 5px; margin-right: 5px;  margin-top: 2px; ">DTYPE &ne; dtype</div><div style="border-style: solid; border-width: 1px; border-color: #A9A9A9; border-radius: 5px; background-color: #F5F5F5; font-size: x-small; padding-left: 4px; padding-right: 4px; margin-left: 5px; margin-right: 5px;  margin-top: 2px; ">float &ne; float64</div></div></div>
</td>
  </tr>
</tfoot>
</table>
</div>
</div>
</details>
</td>
  </tr>
</tfoot>
</table>
</div>
<p>This example demonstrates Pointblank&rsquo;s chainable validation approach where each validation step is
clearly defined and can be configured with different threshold levels. The resulting validation
object provides rich, interactive reporting that shows not just what passed or failed, but detailed
statistics about the validation process. The threshold system allows for nuanced responses to data
quality issues.</p>
<h3 id="comparisons-1">Comparisons
</h3>
<p>Unlike Pandera&rsquo;s schema-first approach, Pointblank focuses on step-by-step validation with detailed
reporting and flexible failure thresholds that can be set at both the global and individual
validation step level. Both Pointblank and Validoopsie use numeric threshold values for granular
control over acceptable failure rates, but they differ in their primary focus: Pointblank emphasizes
comprehensive reporting and stakeholder communication, while Validoopsie prioritizes operational
resilience through its impact level system (low/medium/high) that controls whether threshold
breaches are logged, reported, or raise exceptions.</p>
<p>While both libraries support custom validation logic, Pointblank&rsquo;s <code>specially()</code> method integrates
seamlessly with its reporting system, whereas Validoopsie provides a structured framework for
creating custom validation classes that fit into its modular validation catalog.</p>
<h3 id="unique-strengths-and-when-to-use-2">Unique Strengths and When to Use
</h3>
<ul>
<li>beautiful, interactive HTML reports perfect for sharing with stakeholders</li>
<li>threshold-based alerting system with configurable actions</li>
<li>segmented validation for analyzing subsets of data</li>
<li>LLM-powered validation suggestions via <code>DraftValidation</code></li>
<li>comprehensive data inspection tools and summary tables</li>
<li>step-by-step validation reporting with detailed failure analysis (via <code>.get_step_report()</code>)</li>
</ul>
<p>Data practitioners might want to choose Pointblank when stakeholder communication and comprehensive
data quality reporting are priorities. Because of the reporting tables it can generate, it&rsquo;s
well-suited for data teams that need to regularly report on data quality to relevant stakeholders.
Pointblank also excels in production data monitoring scenarios, data observability workflows, and
situations where understanding the nuances of data quality issues matters more than simple pass/fail
validation.</p>
<h2 id="4-validoopsie-composable-checks-with-smart-failure-handling">4. Validoopsie: Composable Checks with Smart Failure Handling
</h2>
<p>Validoopsie is built around composable validation principles, providing a toolkit for creating
reusable validation functions organized into logical modules. Drawing inspiration from Great
Expectations but with a much lighter footprint, Validoopsie emphasizes building validation logic
from modular, testable components that can be combined in flexible ways to create complex validation
workflows. The library had Polars support from its very first release (early-2025).</p>
<p>What sets Validoopsie apart is its sophisticated approach to handling validation failures through
<em>impact levels</em> and <em>threshold tolerances</em>. These features that give you fine-grained control over
how your validation pipeline behaves when things go wrong.</p>
<h3 id="example-3">Example
</h3>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">validoopsie</span> <span class="kn">import</span> <span class="n">Validate</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">narwhals.dtypes</span> <span class="kn">import</span> <span class="n">Int64</span><span class="p">,</span> <span class="n">Float64</span><span class="p">,</span> <span class="n">String</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Composable validation checks with impact levels and thresholds</span>
</span></span><span class="line"><span class="cl"><span class="n">validation</span> <span class="o">=</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">Validate</span><span class="p">(</span><span class="n">user_data</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">ValuesValidation</span><span class="o">.</span><span class="n">ColumnValuesToBeBetween</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="n">column</span><span class="o">=</span><span class="s2">&#34;user_id&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="n">min_value</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="n">impact</span><span class="o">=</span><span class="s2">&#34;high&#34;</span>  <span class="c1"># Critical - will raise exception</span>
</span></span><span class="line"><span class="cl">    <span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">ValuesValidation</span><span class="o">.</span><span class="n">ColumnValuesToBeBetween</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="n">column</span><span class="o">=</span><span class="s2">&#34;age&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="n">min_value</span><span class="o">=</span><span class="mi">18</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="n">max_value</span><span class="o">=</span><span class="mi">80</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="n">threshold</span><span class="o">=</span><span class="mf">0.1</span><span class="p">,</span>  <span class="c1"># Allow 10% failures</span>
</span></span><span class="line"><span class="cl">        <span class="n">impact</span><span class="o">=</span><span class="s2">&#34;medium&#34;</span>  <span class="c1"># Important but not critical</span>
</span></span><span class="line"><span class="cl">    <span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">StringValidation</span><span class="o">.</span><span class="n">PatternMatch</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="n">column</span><span class="o">=</span><span class="s2">&#34;email&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="n">pattern</span><span class="o">=</span><span class="sa">r</span><span class="s2">&#34;^[^@]+@[^@]+\.[^@]+$&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="n">threshold</span><span class="o">=</span><span class="mf">0.05</span><span class="p">,</span>  <span class="c1"># Allow 5% malformed emails</span>
</span></span><span class="line"><span class="cl">        <span class="n">impact</span><span class="o">=</span><span class="s2">&#34;low&#34;</span>  <span class="c1"># Record but don&#39;t interrupt</span>
</span></span><span class="line"><span class="cl">    <span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">ValuesValidation</span><span class="o">.</span><span class="n">ColumnValuesToBeBetween</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="n">column</span><span class="o">=</span><span class="s2">&#34;score&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="n">min_value</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="n">max_value</span><span class="o">=</span><span class="mi">100</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="n">impact</span><span class="o">=</span><span class="s2">&#34;medium&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">TypeValidation</span><span class="o">.</span><span class="n">TypeCheck</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="n">frame_schema_definition</span><span class="o">=</span><span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="s2">&#34;user_id&#34;</span><span class="p">:</span> <span class="n">Int64</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="s2">&#34;age&#34;</span><span class="p">:</span> <span class="n">Int64</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="s2">&#34;email&#34;</span><span class="p">:</span> <span class="n">String</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="s2">&#34;score&#34;</span><span class="p">:</span> <span class="n">Float64</span>
</span></span><span class="line"><span class="cl">        <span class="p">},</span>
</span></span><span class="line"><span class="cl">        <span class="n">impact</span><span class="o">=</span><span class="s2">&#34;high&#34;</span>  <span class="c1"># Schema compliance is critical</span>
</span></span><span class="line"><span class="cl">    <span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Get validation results</span>
</span></span><span class="line"><span class="cl"><span class="n">validation</span><span class="o">.</span><span class="n">validate</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Access detailed results for analysis</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="s2">&#34;Validation results:&#34;</span><span class="p">,</span> <span class="n">validation</span><span class="o">.</span><span class="n">results</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><pre><span class="ansi-green-fg">2026-04-02 12:07:38.191</span> | <span class="ansi-bold">INFO    </span> | <span class="ansi-cyan-fg">validoopsie.validate</span>:<span class="ansi-cyan-fg">validate</span>:<span class="ansi-cyan-fg">414</span> - <span class="ansi-bold">Passed validation: {'validation': 'ColumnValuesToBeBetween', 'impact': 'high', 'timestamp': '2026-04-02T12:07:38.179694-07:00', 'column': 'user_id', 'result': {'status': 'Success', 'threshold_pass': True, 'message': 'All items passed the validation.', 'frame_row_number': 5, 'threshold': 0.0}}</span>

<span class="ansi-green-fg">2026-04-02 12:07:38.191</span> | <span class="ansi-red-fg ansi-bold">ERROR   </span> | <span class="ansi-cyan-fg">validoopsie.validate</span>:<span class="ansi-cyan-fg">validate</span>:<span class="ansi-cyan-fg">406</span> - <span class="ansi-red-fg ansi-bold">Failed validation: ColumnValuesToBeBetween_age - The column 'age' has values that are not between 18 and 80.</span>

<span class="ansi-green-fg">2026-04-02 12:07:38.192</span> | <span class="ansi-yellow-fg ansi-bold">WARNING </span> | <span class="ansi-cyan-fg">validoopsie.validate</span>:<span class="ansi-cyan-fg">validate</span>:<span class="ansi-cyan-fg">408</span> - <span class="ansi-yellow-fg ansi-bold">Failed validation: PatternMatch_email - The column 'email' has entries that do not match the pattern '^[^@]+@[^@]+\.[^@]+$'.</span>

<span class="ansi-green-fg">2026-04-02 12:07:38.192</span> | <span class="ansi-bold">INFO    </span> | <span class="ansi-cyan-fg">validoopsie.validate</span>:<span class="ansi-cyan-fg">validate</span>:<span class="ansi-cyan-fg">414</span> - <span class="ansi-bold">Passed validation: {'validation': 'ColumnValuesToBeBetween', 'impact': 'medium', 'timestamp': '2026-04-02T12:07:38.182269-07:00', 'column': 'score', 'result': {'status': 'Success', 'threshold_pass': True, 'message': 'All items passed the validation.', 'frame_row_number': 5, 'threshold': 0.0}}</span>

<span class="ansi-green-fg">2026-04-02 12:07:38.192</span> | <span class="ansi-bold">INFO    </span> | <span class="ansi-cyan-fg">validoopsie.validate</span>:<span class="ansi-cyan-fg">validate</span>:<span class="ansi-cyan-fg">414</span> - <span class="ansi-bold">Passed validation: {'validation': 'TypeCheck', 'impact': 'high', 'timestamp': '2026-04-02T12:07:38.182676-07:00', 'column': 'DataTypeColumnValidation', 'result': {'status': 'Success', 'threshold_pass': True, 'message': 'All items passed the validation.', 'frame_row_number': 4, 'threshold': 0.0}}</span>
</pre>
<pre><code>Validation results: {'Summary': {'passed': False, 'validations': ['ColumnValuesToBeBetween_user_id', 'ColumnValuesToBeBetween_age', 'PatternMatch_email', 'ColumnValuesToBeBetween_score', 'TypeCheck_DataTypeColumnValidation'], 'failed_validation': ['ColumnValuesToBeBetween_age', 'PatternMatch_email']}, 'ColumnValuesToBeBetween_user_id': {'validation': 'ColumnValuesToBeBetween', 'impact': 'high', 'timestamp': '2026-04-02T12:07:38.179694-07:00', 'column': 'user_id', 'result': {'status': 'Success', 'threshold_pass': True, 'message': 'All items passed the validation.', 'frame_row_number': 5, 'threshold': 0.0}}, 'ColumnValuesToBeBetween_age': {'validation': 'ColumnValuesToBeBetween', 'impact': 'medium', 'timestamp': '2026-04-02T12:07:38.181019-07:00', 'column': 'age', 'result': {'status': 'Fail', 'threshold_pass': False, 'message': &quot;The column 'age' has values that are not between 18 and 80.&quot;, 'failing_items': [95], 'failed_number': 1, 'frame_row_number': 5, 'threshold': 0.1, 'failed_percentage': 0.2}}, 'PatternMatch_email': {'validation': 'PatternMatch', 'impact': 'low', 'timestamp': '2026-04-02T12:07:38.181596-07:00', 'column': 'email', 'result': {'status': 'Fail', 'threshold_pass': False, 'message': &quot;The column 'email' has entries that do not match the pattern '^[^@]+@[^@]+\\.[^@]+$'.&quot;, 'failing_items': ['invalid-email'], 'failed_number': 1, 'frame_row_number': 5, 'threshold': 0.05, 'failed_percentage': 0.2}}, 'ColumnValuesToBeBetween_score': {'validation': 'ColumnValuesToBeBetween', 'impact': 'medium', 'timestamp': '2026-04-02T12:07:38.182269-07:00', 'column': 'score', 'result': {'status': 'Success', 'threshold_pass': True, 'message': 'All items passed the validation.', 'frame_row_number': 5, 'threshold': 0.0}}, 'TypeCheck_DataTypeColumnValidation': {'validation': 'TypeCheck', 'impact': 'high', 'timestamp': '2026-04-02T12:07:38.182676-07:00', 'column': 'DataTypeColumnValidation', 'result': {'status': 'Success', 'threshold_pass': True, 'message': 'All items passed the validation.', 'frame_row_number': 4, 'threshold': 0.0}}}
</code></pre>
<p>This example showcases Validoopsie&rsquo;s key differentiators: modular validation categories
(<code>ValuesValidation</code>, <code>StringValidation</code>, <code>TypeValidation</code>) combined with <em>impact levels</em> that
control failure behavior and <em>thresholds</em> that allow controlled tolerance for data quality issues.
Unlike other libraries that treat all validation failures equally, Validoopsie lets you specify
which validations are critical (&ldquo;high&rdquo; impact raises exceptions) versus informational (&ldquo;low&rdquo; impact
just logs results).</p>
<p>Validoopsie&rsquo;s most powerful feature is its three-tier <code>impact=</code> system combined with <code>threshold=</code>
tolerance:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># Example showing sophisticated failure handling</span>
</span></span><span class="line"><span class="cl"><span class="n">validation</span> <span class="o">=</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">Validate</span><span class="p">(</span><span class="n">user_data</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># Critical validation - no tolerance</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">NullValidation</span><span class="o">.</span><span class="n">ColumnNotBeNull</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="n">column</span><span class="o">=</span><span class="s2">&#34;user_id&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="n">impact</span><span class="o">=</span><span class="s2">&#34;high&#34;</span>    <span class="c1"># Will raise an exception if any Null values found</span>
</span></span><span class="line"><span class="cl">    <span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># Important validation with tolerance</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">StringValidation</span><span class="o">.</span><span class="n">PatternMatch</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="n">column</span><span class="o">=</span><span class="s2">&#34;email&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="n">pattern</span><span class="o">=</span><span class="sa">r</span><span class="s2">&#34;^[^@]+@[^@]+\.[^@]+$&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="n">threshold</span><span class="o">=</span><span class="mf">0.15</span><span class="p">,</span>  <span class="c1"># Allow up to 15% malformed emails</span>
</span></span><span class="line"><span class="cl">        <span class="n">impact</span><span class="o">=</span><span class="s2">&#34;medium&#34;</span>  <span class="c1"># Log failures but don&#39;t stop processing</span>
</span></span><span class="line"><span class="cl">    <span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># Informational validation</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">ValuesValidation</span><span class="o">.</span><span class="n">ColumnValuesToBeBetween</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="n">column</span><span class="o">=</span><span class="s2">&#34;score&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="n">min_value</span><span class="o">=</span><span class="mi">90</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="n">max_value</span><span class="o">=</span><span class="mi">100</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="n">threshold</span><span class="o">=</span><span class="mf">0.8</span><span class="p">,</span>  <span class="c1"># Allow 80% to be outside &#34;excellent&#34; range</span>
</span></span><span class="line"><span class="cl">        <span class="n">impact</span><span class="o">=</span><span class="s2">&#34;low&#34;</span>    <span class="c1"># Just track high performers</span>
</span></span><span class="line"><span class="cl">    <span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">validation</span><span class="o">.</span><span class="n">validate</span><span class="p">()</span>
</span></span></code></pre></td></tr></table>
</div>
</div><pre><span class="ansi-green-fg">2026-04-02 12:07:38.199</span> | <span class="ansi-bold">INFO    </span> | <span class="ansi-cyan-fg">validoopsie.validate</span>:<span class="ansi-cyan-fg">validate</span>:<span class="ansi-cyan-fg">414</span> - <span class="ansi-bold">Passed validation: {'validation': 'ColumnNotBeNull', 'impact': 'high', 'timestamp': '2026-04-02T12:07:38.197433-07:00', 'column': 'user_id', 'result': {'status': 'Success', 'threshold_pass': True, 'message': 'All items passed the validation.', 'frame_row_number': 5, 'threshold': 0.0}}</span>

<span class="ansi-green-fg">2026-04-02 12:07:38.199</span> | <span class="ansi-red-fg ansi-bold">ERROR   </span> | <span class="ansi-cyan-fg">validoopsie.validate</span>:<span class="ansi-cyan-fg">validate</span>:<span class="ansi-cyan-fg">406</span> - <span class="ansi-red-fg ansi-bold">Failed validation: PatternMatch_email - The column 'email' has entries that do not match the pattern '^[^@]+@[^@]+\.[^@]+$'.</span>

<span class="ansi-green-fg">2026-04-02 12:07:38.199</span> | <span class="ansi-bold">INFO    </span> | <span class="ansi-cyan-fg">validoopsie.validate</span>:<span class="ansi-cyan-fg">validate</span>:<span class="ansi-cyan-fg">414</span> - <span class="ansi-bold">Passed validation: {'validation': 'ColumnValuesToBeBetween', 'impact': 'low', 'timestamp': '2026-04-02T12:07:38.198631-07:00', 'column': 'score', 'result': {'status': 'Success', 'threshold_pass': True, 'message': "The column 'score' has values that are not between 90 and 100.", 'failing_items': [78.3, 85.5, 88.7], 'failed_number': 3, 'frame_row_number': 5, 'threshold': 0.8, 'failed_percentage': 0.6}}</span>
</pre>
<p>Validoopsie strikes a unique balance between operational flexibility and production reliability,
making it an excellent choice for teams that need sophisticated failure handling without the
complexity of larger validation frameworks.</p>
<h3 id="comparisons-2">Comparisons
</h3>
<p>Validoopsie&rsquo;s functional approach contrasts with Pandera&rsquo;s schema-centric methodology and Patito&rsquo;s
object-oriented models. While Pandera focuses on statistical validation and Patito emphasizes
Pydantic integration, Validoopsie prioritizes flexibility and operational robustness.</p>
<p>Compared to Pointblank, both libraries offer sophisticated threshold-based failure handling using
numeric values (e.g., 0.1 for 10% tolerance), but they differ in their architectural approach:
Validoopsie combines numeric thresholds with impact levels (low/medium/high) that control the
behavioral response to threshold breaches, while Pointblank integrates thresholds directly into its
comprehensive reporting and alerting system. Both support custom validation, but Validoopsie uses a
modular validation catalog approach while Pointblank&rsquo;s <code>specially()</code> method integrates seamlessly
with its step-by-step reporting workflow.</p>
<p>Validoopsie is the only library in this survey that provides built-in logging capabilities, making
it particularly valuable for production environments where validation events need to be tracked and
monitored.</p>
<p>The library&rsquo;s Great Expectations inspiration is evident in its modular design, but Validoopsie
delivers this functionality with a much lighter dependency footprint and simpler API. Teams
familiar with Great Expectations will find Validoopsie&rsquo;s approach familiar but more streamlined.</p>
<h3 id="unique-strengths-and-when-to-use-3">Unique Strengths and When to Use
</h3>
<p>Validoopsie&rsquo;s standout features include:</p>
<ul>
<li>graduated failure handling through impact levels (low/medium/high) combined with numeric
thresholds that control both tolerance levels and behavioral responses to failures</li>
<li>numeric threshold tolerance allowing controlled acceptance of data quality issues (e.g., &ldquo;allow
10% email format failures&rdquo; with <code>threshold=0.1</code>)</li>
<li>built-in structured logging using loguru allows for automatic logging of validation results,
failures, and performance metrics (unique among these libraries)</li>
<li>being a lightweight Great Expectations alternative with similar composability but minimal
dependencies</li>
<li>an extensive validation catalog organized into logical namespaces (Date, String, Null, Values,
etc.)</li>
<li>custom validation framework with consistent patterns for creating domain-specific rules</li>
</ul>
<p>Choose Validoopsie when you need:</p>
<ul>
<li>operational resilience in production pipelines where partial data quality issues shouldn&rsquo;t
stop processing</li>
<li>comprehensive validation logging and monitoring for observability in production environments</li>
<li>fine-grained control over validation failure behavior with different criticality levels</li>
<li>lightweight Great Expectations functionality without the complexity and dependencies</li>
<li>custom validation development with a clear, consistent framework</li>
<li>modular validation design that promotes reusability across projects</li>
</ul>
<p>Validoopsie is particularly well-suited for data engineering teams building robust production
pipelines where data quality monitoring is important but pipeline availability is critical. Its
impact/threshold system makes it uniquely powerful for environments where you need to distinguish
between &ldquo;nice to have&rdquo; and &ldquo;must have&rdquo; data quality requirements.</p>
<h2 id="5-dataframely-type-safe-schema-validation-with-advanced-features">5. Dataframely: Type-Safe Schema Validation with Advanced Features
</h2>
<p>Dataframely is a comprehensive data validation framework that brings type-safe schema validation to
Polars DataFrames with some of the most advanced features in the ecosystem. The library focuses on
providing both runtime validation and static type checking, with particular strengths in
collection validation for related DataFrames and extensive integration capabilities with external
tools.</p>
<p>Dataframely launched in early 2025 with native Polars support as a core feature, built specifically
for the modern data ecosystem with first-class support for complex validation scenarios.</p>
<h3 id="example-4">Example
</h3>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">polars</span> <span class="k">as</span> <span class="nn">pl</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">dataframely</span> <span class="k">as</span> <span class="nn">dy</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">UserSchema</span><span class="p">(</span><span class="n">dy</span><span class="o">.</span><span class="n">Schema</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="n">user_id</span> <span class="o">=</span> <span class="n">dy</span><span class="o">.</span><span class="n">Int64</span><span class="p">(</span><span class="n">primary_key</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="nb">min</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">nullable</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">age</span> <span class="o">=</span> <span class="n">dy</span><span class="o">.</span><span class="n">Int64</span><span class="p">(</span><span class="n">nullable</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">email</span> <span class="o">=</span> <span class="n">dy</span><span class="o">.</span><span class="n">String</span><span class="p">(</span><span class="n">nullable</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">regex</span><span class="o">=</span><span class="sa">r</span><span class="s2">&#34;^[^@]+@[^@]+\.[^@]+$&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">score</span> <span class="o">=</span> <span class="n">dy</span><span class="o">.</span><span class="n">Float64</span><span class="p">(</span><span class="n">nullable</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="nb">min</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span> <span class="nb">max</span><span class="o">=</span><span class="mf">100.0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># Use @dy.rule() for age range validation</span>
</span></span><span class="line"><span class="cl">    <span class="nd">@dy.rule</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">age_in_range</span><span class="p">(</span><span class="bp">cls</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">pl</span><span class="o">.</span><span class="n">Expr</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">pl</span><span class="o">.</span><span class="n">col</span><span class="p">(</span><span class="s2">&#34;age&#34;</span><span class="p">)</span><span class="o">.</span><span class="n">is_between</span><span class="p">(</span><span class="mi">18</span><span class="p">,</span> <span class="mi">80</span><span class="p">,</span> <span class="n">closed</span><span class="o">=</span><span class="s2">&#34;both&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Validate using the schema</span>
</span></span><span class="line"><span class="cl"><span class="k">try</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="n">validated_data</span> <span class="o">=</span> <span class="n">UserSchema</span><span class="o">.</span><span class="n">validate</span><span class="p">(</span><span class="n">user_data</span><span class="p">,</span> <span class="n">cast</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;Validation successful!&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="n">validated_data</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;Validation failed: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>This example showcases Dataframely&rsquo;s class-based schema approach with several notable features:
primary key constraints, comprehensive type validation with bounds, regex pattern matching, and
custom validation rules using the <code>@dy.rule()</code> decorator (used here for age range checking).</p>
<p>The <code>cast=True</code> parameter automatically coerces column types to match the schema definitions. This
is really useful when working with data from external sources where column types might not exactly
match your schema expectations (e.g., integers loaded as strings from CSV files).</p>
<p>Dataframely features soft validation and failure introspection. As one of Dataframely&rsquo;s standout
features, it brings a fairly sophisticated approach to validation failures. Rather than just raising
exceptions, it provides detailed failure analysis:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># Soft validation: separate valid and invalid rows</span>
</span></span><span class="line"><span class="cl"><span class="n">good_data</span><span class="p">,</span> <span class="n">failure_info</span> <span class="o">=</span> <span class="n">UserSchema</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">user_data</span><span class="p">,</span> <span class="n">cast</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="s2">&#34;Valid rows:&#34;</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">good_data</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="s2">&#34;Failure counts:&#34;</span><span class="p">,</span> <span class="n">failure_info</span><span class="o">.</span><span class="n">counts</span><span class="p">())</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="s2">&#34;Co-occurrence analysis:&#34;</span><span class="p">,</span> <span class="n">failure_info</span><span class="o">.</span><span class="n">cooccurrence_counts</span><span class="p">())</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Inspect the actual failed rows</span>
</span></span><span class="line"><span class="cl"><span class="n">failed_rows</span> <span class="o">=</span> <span class="n">failure_info</span><span class="o">.</span><span class="n">invalid</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="s2">&#34;Failed data:&#34;</span><span class="p">,</span> <span class="n">failed_rows</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="comparisons-3">Comparisons
</h3>
<p>While both Dataframely and Pandera offer schema-centric validation approaches, they serve different
validation philosophies. Pandera excels in statistical validation with hypothesis testing and
distribution checks, making it ideal for data science workflows where statistical properties matter.
Dataframely, by contrast, emphasizes relational data integrity and type safety, providing more
sophisticated failure analysis and collection-level validation capabilities that Pandera doesn&rsquo;t
offer.</p>
<p>The relationship between Dataframely and Patito is particularly interesting since both use
class-based schema definitions. However, Dataframely extends far beyond Patito&rsquo;s Pydantic-focused
approach. Where Patito provides clean, simple validation with excellent Pydantic integration,
Dataframely offers advanced features like collection validation, group rules, and comprehensive
failure introspection. Teams already invested in Pydantic workflows might prefer Patito&rsquo;s
simplicity, while those building complex data systems will appreciate Dataframely&rsquo;s feature set.</p>
<p>Dataframely and Pointblank represent two different approaches to comprehensive data validation.
Pointblank shines in stakeholder communication with its beautiful interactive reports and
threshold-based alerting systems, making it perfect for data quality reporting. Dataframely focuses
instead on type safety and complex validation logic, with unique collection validation capabilities
that no other library in this survey provides. The choice between these two will comes down to
whether your priority is communicating validation results or ensuring complex data relationships
remain consistent.</p>
<p>When compared to Validoopsie&rsquo;s method chaining approach, Dataframely offers a more structured,
schema-centric methodology with advanced type safety features that Validoopsie doesn&rsquo;t provide.
While Validoopsie excels in operational flexibility and lightweight design for building reusable
validation components, Dataframely&rsquo;s strength lies in its comprehensive type system integration,
collection validation capabilities, and sophisticated failure analysis. And that makes it ideal for
complex data engineering workflows where relationships between multiple DataFrames matter as much as
individual DataFrame validation.</p>
<h3 id="unique-strengths-and-when-to-use-4">Unique Strengths and When to Use
</h3>
<p>Dataframely&rsquo;s standout features include:</p>
<ul>
<li>advanced type safety with full mypy integration and generic DataFrame types</li>
<li>collection validation for ensuring consistency across related DataFrames</li>
<li>group-based validation rules using <code>@dy.rule(group_by=[...])</code> for aggregate constraints</li>
<li>schema inheritance for reducing code duplication in related schemas</li>
<li>production-ready soft validation that separates valid and invalid data</li>
</ul>
<p>One might choose Dataframely when building complex data systems where:</p>
<ul>
<li>type safety and static analysis are critical for code quality</li>
<li>you need to validate relationships between multiple related DataFrames</li>
<li>you&rsquo;re working with production pipelines that need to handle partial data quality issues
gracefully</li>
<li>schema reuse and inheritance would benefit your codebase organization</li>
</ul>
<p>Dataframely is particularly well-suited for data engineering teams building robust, type-safe data
pipelines where the relationships between different data entities are as important as the validation
of individual DataFrames. Its collection validation capabilities make it uniquely powerful for
ensuring referential integrity in complex data workflows.</p>
<h2 id="choosing-the-right-library">Choosing the Right Library
</h2>
<p>With five solid validation libraries to choose from, the decision often comes down to your team&rsquo;s
specific workflow, existing tech stack, and validation requirements. Here are some practical
considerations to help guide your choice:</p>
<p><em>Start with your existing tools</em></p>
<p>If you&rsquo;re already using Pydantic extensively, Patito will feel natural. Teams that are heavily
invested in type checking and statistical analysis should probably gravitate toward Pandera. If
you&rsquo;re building data products that need stakeholder buy-in, Pointblank&rsquo;s reporting capabilities
become incredibly useful in that context. For teams already committed to strong typing and static
analysis workflows, Dataframely&rsquo;s advanced type safety features will feel like a natural extension
of your existing practices.</p>
<p><em>Consider your validation complexity</em></p>
<p>For straightforward schema validation and type checking, any of these libraries will work well. But
if you need statistical hypothesis testing, Pandera is your best bet. For highly custom validation
logic that needs to be composed and reused, Validoopsie shines. When validation results need to be
communicated to non-technical stakeholders, Pointblank&rsquo;s interactive reports are basically
unmatched. If you&rsquo;re dealing with complex relational data where multiple DataFrames need to maintain
consistency with each other, Dataframely&rsquo;s collection validation capabilities are unique in the
ecosystem.</p>
<p><em>Think about failure tolerance requirements</em></p>
<p>One of the most important architectural differences among these libraries is how they handle
validation failures. Only Pointblank and Validoopsie offer numeric threshold-based failure
tolerance. This is the ability to accept a controlled percentage of validation failures without
treating the entire validation as failed.</p>
<p>This distinction can be crucial for production environments where some level of data quality issues
is acceptable and you need fine-grained control over when validations should fail versus warn. In
many real-world scenarios, poor data quality is a given reality, and the goal becomes gradually
improving quality over time rather than enforcing perfection. Thresholds can then be seen not as
simple failure tolerances but more like data quality metrics and improvement goals (e.g., you might
start with <code>threshold=0.15</code> for email validation and progressively tighten to <code>0.05</code> as upstream
systems improve).</p>
<p><em>Think about your team&rsquo;s preferences</em></p>
<p>There&rsquo;s a human dimension here. Some data teams might prefer the declarative, schema-first approach
of Pandera, Patito, and Dataframely, whereas others like the step-by-step, method-chaining style of
Pointblank and Validoopsie. There&rsquo;s really no right or wrong choice here. It&rsquo;s all about what feels
right and most natural for your team&rsquo;s coding style and mental model.</p>
<p><em>Don&rsquo;t feel locked into one choice</em></p>
<p>My hunch is that many teams already successfully use different libraries for different parts of
their data pipeline. They&rsquo;re leveraging each tool&rsquo;s strengths where they matter most. So you could
conceivably use Patito for Pydantic-style validation, Pandera for statistical checks in your
analysis pipeline, Pointblank for generating stakeholder reports, and Dataframely for complex data
engineering workflows (use &rsquo;em all!). This multi-library approach can be particularly effective in
larger organizations with diverse validation needs.</p>
<p>I suppose the key is to start with one library that fits your immediate needs, learn it well, and
then consider expanding your toolkit as your validation requirements evolve.</p>
<h2 id="summary-and-wrapping-up">Summary and Wrapping Up
</h2>
<p>The Python ecosystem offers truly excellent options for validating Polars DataFrames! Choosing is
always tough but this is how one could make the decision based on specific needs:</p>
<ul>
<li>for type-safe pipelines, <strong>Pandera</strong>, <strong>Dataframely</strong>, or <strong>Patito</strong> are ideal</li>
<li>for stakeholder reporting, <strong>Pointblank</strong> is a great choice</li>
<li>for row-level object modeling, go with <strong>Patito</strong></li>
<li>for statistical validation, <strong>Pandera</strong> is perfect</li>
<li>for data quality improvement, <strong>Pointblank</strong> or <strong>Validoopsie</strong> fit well</li>
</ul>
<p>Each library has evolved to serve different aspects of the data validation ecosystem. Try them all
and, with a little understanding of their strengths, you&rsquo;ll get good at picking the right data
validation tool for your specific use case.</p>
<p>This survey represents our understanding of these libraries as of mid-2025. Given the rapid pace of
development in the Python data ecosystem, some details may become outdated or contain inaccuracies
(we may have even gotten things wrong at the outset). If you notice any errors or have updates to
share, we&rsquo;d love to hear from you! Please reach out through:</p>
<ul>
<li><a href="https://github.com/posit-dev/pointblank/issues" target="_blank" rel="noopener">GitHub Issues</a>
</li>
<li><a href="https://github.com/posit-dev/pointblank/discussions" target="_blank" rel="noopener">GitHub Discussions</a>
</li>
<li>Our <a href="https://discord.com/invite/YH7CybCNCQ" target="_blank" rel="noopener">Discord Server</a>
</li>
</ul>
<p>Any feedback you provide helps keep this resource accurate and useful for the community!</p>
]]></description>
    </item>
    <item>
      <title>C&#39;mon C&#39;mon: Let&#39;s Do a Pointblank Workshop!</title>
      <link>https://posit-open-source.netlify.app/blog/pointblank/lets-workshop-together/</link>
      <pubDate>Tue, 03 Jun 2025 00:00:00 +0000</pubDate>
      <guid>https://posit-open-source.netlify.app/blog/pointblank/lets-workshop-together/</guid>
      <dc:creator>Rich Iannone</dc:creator><description><![CDATA[<p>Recently, I&rsquo;ve been giving free workshops to data teams on Pointblank. These sorts of engagements
energize me, and I truly enjoy hearing what people are concerned with when it comes to data
validation. If <em>your</em> team is interested, I would love to schedule something with y&rsquo;all! Please
reach out at <a href="mailto:rich@posit.co">rich@posit.co</a>
 or message me on the (<a href="https://discord.com/invite/YH7CybCNCQ" target="_blank" rel="noopener">Pointblank Discord</a>
).</p>
<p>Workshops have been especially helpful for understanding how people use and share Pointblank&rsquo;s
<a href="https://posit-dev.github.io/pointblank/user-guide/index.html" target="_blank" rel="noopener">validation results table</a>
. For example, I learned that people like to
email or pull up the table for stakeholders so they can walk through problem cases (it&rsquo;s a great
conversation starter for getting to the heart of data quality issues).</p>
<p>A couple of months ago, I gave a workshop to one of Apple&rsquo;s data teams. During the Q&amp;A afterwards,
someone asked whether you can perform the same validation on different chunks of table rows. This
was a very helpful nudge for me to add a <a href="https://posit-dev.github.io/pointblank/user-guide/segmentation.html" target="_blank" rel="noopener"><code>segments=</code> argument</a>

to all of Pointblank&rsquo;s validation methods!</p>
<p>We are excited about how things are going with the Pointblank project and are <em>always up</em> for
providing a workshop to your data team (at no cost). If this sounds interesting to you please feel
free to contact me through email or via Discord. Don&rsquo;t be shy. Just know that if you have a need for
data validation, we&rsquo;re here to help!</p>
<h2 id="acknowledgment">Acknowledgment
</h2>
<p>I&rsquo;d like to give special thanks to Rami Krispin for his interest in Pointblank and for facilitating
a recent workshop. If you&rsquo;re interested in more data science insights, check out
<a href="https://ramikrispin.substack.com" target="_blank" rel="noopener">Rami&rsquo;s Data Newsletter</a>
 where he shares valuable perspectives
on data engineering, LLMs, and analytics.</p>
]]></description>
    </item>
    <item>
      <title>Overhauling Pointblank&#39;s User Guide</title>
      <link>https://posit-open-source.netlify.app/blog/pointblank/overhauled-user-guide/</link>
      <pubDate>Tue, 20 May 2025 00:00:00 +0000</pubDate>
      <guid>https://posit-open-source.netlify.app/blog/pointblank/overhauled-user-guide/</guid>
      <dc:creator>Rich Iannone</dc:creator>
      <dc:creator>Michael Chow</dc:creator><description><![CDATA[<p>The Pointblank documentation just got a major upgrade! We&rsquo;ve completely overhauled our
<a href="https://posit-dev.github.io/pointblank/user-guide/index.html" target="_blank" rel="noopener"><strong>User Guide</strong></a>
. Our goal was to enable readers to start fast on
validation and work through the many pieces needed in realistic situations.</p>
<p>We realized that at the core of Pointblank is the validation plan. Its made up of rules, results,
and steps.</p>
<img src="https://posit-open-source.netlify.app/blog/pointblank/overhauled-user-guide/validation-three-things.png" style="width:80.0%" />
<p>For example, the first row is a step that checks whether values in column &lsquo;a&rsquo; are less than <code>10</code>.
The <code>COLUMNS</code> and <code>VALUES</code> column contain the rules used to configure the step. The <code>PASS</code> column
for the first row indicates that all 13 values in the column passed.</p>
<p>In this post, we&rsquo;ll cover:</p>
<ul>
<li>using a spiral sequence to balance introductory breadth with subsequent depth</li>
<li>improving examples with direct explanatory text</li>
<li>rounding out API coverage for cross-linking</li>
<li>surfacing advanced topics</li>
</ul>
<p>Let us walk you through the key improvements in our refreshed <a href="https://posit-dev.github.io/pointblank/user-guide/index.html" target="_blank" rel="noopener"><strong>User Guide</strong></a>
!</p>
<h2 id="introduction-embracing-the-spiral-sequence">Introduction: Embracing the Spiral Sequence
</h2>
<p>We chose to use a spiral sequence for our <a href="https://posit-dev.github.io/pointblank/user-guide/index.html" target="_blank" rel="noopener">Introduction</a>
 and
<em>Validation Plan</em> section. The <a href="https://posit-dev.github.io/pointblank/user-guide/index.html" target="_blank" rel="noopener">Introduction</a>
 quickly covers parts of
validation plan, while each article of the <em>Validation Plan</em> section dives
deeper into different aspects of defining validation rules.</p>
<img src="https://posit-open-source.netlify.app/blog/pointblank/overhauled-user-guide/breadth-and-depth.png" style="width:50.0%" />
<p>The introduction does a broad pass on the validation plan table diagram, identifying the core pieces
of the output and then giving a quick overview of the code that produced it. This sets people up for
the <em>Validation Plan</em> section in the guide, where each concept is discussed in depth.</p>
<h2 id="improving-examples">Improving Examples
</h2>
<p>Examples are everywhere in the <a href="https://posit-dev.github.io/pointblank/user-guide/index.html" target="_blank" rel="noopener"><strong>User Guide</strong></a>
. We&rsquo;ve tightened up our
approach to examples by:</p>
<ul>
<li>presenting example code, output, or both, early in each section</li>
<li>showing the actual output you&rsquo;ll see in your environment</li>
<li>following up with explanatory text that guides attention to specific places in the output</li>
</ul>
<p>This approach makes learning more intuitive. Here&rsquo;s an excerpt that shows this in practice.</p>
<img src="https://posit-open-source.netlify.app/blog/pointblank/overhauled-user-guide/explanation-of-visual.png" style="width:80.0%" />
<p>The blue arrow marks the flow of reading and the red arrows map where we anticipate people will look
from the text to the output. Focusing explicitly on where we think attention will go forces us to
think carefully about exactly what readers will get from the output. The hope is that readers get to
work more quickly on new concepts.</p>
<h2 id="rounding-out-api-coverage">Rounding Out API Coverage
</h2>
<p>Documentation has to balance jobs between a user guide and an API Reference:</p>
<ul>
<li>User Guide: explains concepts that cut across functions (like common arguments across
<a href="https://posit-dev.github.io/pointblank/user-guide/validation-methods.html" target="_blank" rel="noopener">validation methods</a>
)</li>
<li>API Reference: explains each individual function</li>
</ul>
<p>Importantly, user guides often link to the API reference so, as part of this work, we made sure that
all individual API entries are well-documented and linked to from the guide.
Here&rsquo;s an excerpt from the <a href="https://posit-dev.github.io/pointblank/user-guide/index.html" target="_blank" rel="noopener"><strong>User Guide</strong></a>
 that shows links marked:</p>
<img src="https://posit-open-source.netlify.app/blog/pointblank/overhauled-user-guide/links-in-guide.png" style="width:80.0%" />
<h2 id="surfacing-advanced-topics">Surfacing Advanced Topics
</h2>
<p>There&rsquo;s a lot of potential slicing and dicing involved in validation, as well as work after
validation (post interrogation) to make sense of the results. We added pages to the
<a href="https://posit-dev.github.io/pointblank/user-guide/index.html" target="_blank" rel="noopener"><strong>User Guide</strong></a>
 for some core situations.
In this section, I&rsquo;ll highlight two advanced topics we added pages for:</p>
<ul>
<li>segmentation: splitting a column into groups, and validating each group</li>
<li>step reports: view failing cases (e.g., view rows of data that failed validation)</li>
</ul>
<p>These are marked in the <a href="https://posit-dev.github.io/pointblank/user-guide/index.html" target="_blank" rel="noopener"><strong>User Guide</strong></a>
 sidebar screenshot below:</p>
<img src="https://posit-open-source.netlify.app/blog/pointblank/overhauled-user-guide/advanced-in-sidebar.png" style="width:35.0%" />
<h3 id="segmentation">Segmentation
</h3>
<p>Here&rsquo;s a screenshot of a validation report with two validation steps, one for each segment (<code>&quot;low&quot;</code>
and <code>&quot;high&quot;</code>) in the <code>f</code> column of the <code>small_table</code> dataset.</p>
<img src="https://posit-open-source.netlify.app/blog/pointblank/overhauled-user-guide/segments.png" style="width:80.0%" />
<p>Notice that segments split columns into groups and apply the same validation to each of the groups.
Each group is given its own step.</p>
<p>Each of the 20+ validation methods accept a <code>segment=</code> argument. The value of the
<a href="https://posit-dev.github.io/pointblank/user-guide/segmentation.html" target="_blank" rel="noopener">Segmentation article in the User Guide</a>
 is to describe this
cross-cutting behavior in a single place.</p>
<p>Compare the <code>segments=</code> parameter in the API Reference (e.g., look at
<a href="https://posit-dev.github.io/pointblank/reference/Validate.col_vals_gt.html" target="_blank" rel="noopener"><code>col_vals_gt()</code></a>
) and the
<a href="https://posit-dev.github.io/pointblank/user-guide/segmentation.html" target="_blank" rel="noopener">Segmentation article</a>
 to get a feel for how each location
documents the segments feature.</p>
<h3 id="step-report">Step Report
</h3>
<p>Step reports display failing cases (e.g., rows) for a validation step, so you can dig deeper into
validation failures. Here&rsquo;s a screenshot of a step report for some validation step 2:</p>
<img src="https://posit-open-source.netlify.app/blog/pointblank/overhauled-user-guide/step-report.png" style="width:80.0%" />
<p>Notice the arrow pointing to &lsquo;Step 2&rsquo; in the title. Failing values are highlighted in red. Once we
know we have failures, it&rsquo;s important to take action and discover <em>why</em> data is failing. Looking at
failing cases in step reports often uncovers obvious causes behind failures.</p>
<p>The <code>get_step_report()</code> entry is one of 50 in the API Reference. Here it is listed the API
Reference, in the <a href="https://posit-dev.github.io/pointblank/reference/index.html#interrogation-and-reporting" target="_blank" rel="noopener">Interrogation and Reporting section</a>
.
Critically, it&rsquo;s only one of 20 entries in the <a href="https://posit-dev.github.io/pointblank/user-guide/index.html" target="_blank" rel="noopener">User Guide</a>
, which
emphasizes its importance in validation workflows.</p>
<h2 id="looking-forward">Looking Forward
</h2>
<p>The refreshed <strong>User Guide</strong> is just the beginning of our documentation improvements. We&rsquo;re
committed to continuously enhancing our documentation to support your data validation needs.</p>
<p>Michael Chow gave feedback on this <strong>User Guide</strong> in preparation for his
<a href="https://cfp.scipy.org/scipy2025/talk/NRMNDX/" target="_blank" rel="noopener">upcoming talk at SciPy 2025</a>
.</p>
<p>We&rsquo;d love to hear your feedback on the new User Guide! Feel free to open an issue on our
<a href="https://github.com/posit-dev/pointblank/issues" target="_blank" rel="noopener">GitHub repository</a>
 with suggestions, corrections,
or requests for additional topics you&rsquo;d like to see covered. You can also join our community
discussions in the dedicated <code>#Documentation</code> channel on our
<a href="https://discord.com/invite/YH7CybCNCQ" target="_blank" rel="noopener">Discord server</a>
, where you can share ideas, ask questions,
and get help directly from the Pointblank team and other users.</p>
]]></description>
    </item>
    <item>
      <title>Level Up Your Data Validation with `Actions` and `FinalActions`</title>
      <link>https://posit-open-source.netlify.app/blog/pointblank/all-about-actions/</link>
      <pubDate>Fri, 02 May 2025 00:00:00 +0000</pubDate>
      <guid>https://posit-open-source.netlify.app/blog/pointblank/all-about-actions/</guid>
      <dc:creator>Rich Iannone</dc:creator><description><![CDATA[<script src="https://cdn.jsdelivr.net/npm/requirejs@2.3.6/require.min.js" integrity="sha384-c9c+LnTbwQ3aujuU7ULEPVvgLs+Fn6fJUvIGTsuu1ZcCf11fiEubah0ttpca4ntM sha384-6V1/AdqZRWk1KAlWbKBlGhN7VG4iE/yAZcO6NZPMF8od0vukrvr0tg4qY6NSrItx" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.min.js" integrity="sha384-ZvpUoO/+PpLXR1lu4jmpXWu80pZlYUAfxl5NsBMWOEPSjUn/6Z/hRTt8+pR6L4N2" crossorigin="anonymous" data-relocate-top="true"></script>
<script type="application/javascript">define('jquery', [],function() {return window.jQuery;})</script>
<p>Data validation is only useful if you can respond appropriately when problems arise. That&rsquo;s why
Pointblank&rsquo;s recent <code>v0.8.0</code> and <code>v0.8.1</code> releases have significantly enhanced our action framework,
allowing you to create sophisticated, automated responses to validation failures.</p>
<p>In this post, we&rsquo;ll explore how to use:</p>
<ol>
<li><strong>Actions</strong> to respond to individual validation failures</li>
<li><strong>FinalActions</strong> to execute code after your entire validation plan completes</li>
<li>New customization features that make your validation workflows more expressive</li>
</ol>
<p>Let&rsquo;s dive into how these features can transform your data validation process from passive reporting
to active response.</p>
<h2 id="from-passive-validation-to-active-response">From Passive Validation to Active Response
</h2>
<p>Traditional data validation simply reports problems: &ldquo;Column X has invalid values.&rdquo; But what if you
want to:</p>
<ul>
<li>send a Slack message when critical errors occur?</li>
<li>log detailed diagnostics about failing data?</li>
<li>trigger automatic data cleaning processes?</li>
<li>generate custom reports for stakeholders?</li>
</ul>
<p>This is where Pointblank&rsquo;s action system can help. By pairing thresholds with actions, you can
create automated responses that trigger exactly when needed.</p>
<h2 id="getting-started-with-actions">Getting Started with Actions
</h2>
<p>Actions are executed when validation steps fail to meet certain thresholds. Let&rsquo;s start with a
simple example:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">pointblank</span> <span class="k">as</span> <span class="nn">pb</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">validation_1</span> <span class="o">=</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">pb</span><span class="o">.</span><span class="n">Validate</span><span class="p">(</span><span class="n">data</span><span class="o">=</span><span class="n">pb</span><span class="o">.</span><span class="n">load_dataset</span><span class="p">(</span><span class="n">dataset</span><span class="o">=</span><span class="s2">&#34;small_table&#34;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">col_vals_gt</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="n">columns</span><span class="o">=</span><span class="s2">&#34;d&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="n">value</span><span class="o">=</span><span class="mi">1000</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="n">thresholds</span><span class="o">=</span><span class="n">pb</span><span class="o">.</span><span class="n">Thresholds</span><span class="p">(</span><span class="n">warning</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">error</span><span class="o">=</span><span class="mi">5</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">        <span class="n">actions</span><span class="o">=</span><span class="n">pb</span><span class="o">.</span><span class="n">Actions</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">            <span class="n">warning</span><span class="o">=</span><span class="s2">&#34;⚠️ WARNING: Some values in column &#39;d&#39; are below the minimum threshold!&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">interrogate</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">validation_1</span>
</span></span></code></pre></td></tr></table>
</div>
</div><pre><code>⚠️ WARNING: Some values in column 'd' are below the minimum threshold!
</code></pre>
<div id="pb_tbl" style="padding-left:0px;padding-right:0px;padding-top:10px;padding-bottom:10px;overflow-x:auto;overflow-y:auto;width:auto;height:auto;">
<style>
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono&display=swap');
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans&display=swap');
#pb_tbl table {
          font-family: 'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Helvetica Neue', 'Fira Sans', 'Droid Sans', Arial, sans-serif;
          -webkit-font-smoothing: antialiased;
          -moz-osx-font-smoothing: grayscale;
        }
<p>#pb_tbl thead, tbody, tfoot, tr, td, th { border-style: none; }
tr { background-color: transparent; }
#pb_tbl p { margin: 0; padding: 0; }
#pb_tbl .gt_table { display: table; border-collapse: collapse; line-height: normal; margin-left: auto; margin-right: auto; color: #333333; font-size: 90%; font-weight: normal; font-style: normal; background-color: #FFFFFF; width: auto; border-top-style: solid; border-top-width: 2px; border-top-color: #A8A8A8; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #A8A8A8; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; }
#pb_tbl .gt_caption { padding-top: 4px; padding-bottom: 4px; }
#pb_tbl .gt_title { color: #333333; font-size: 125%; font-weight: initial; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; border-bottom-color: #FFFFFF; border-bottom-width: 0; }
#pb_tbl .gt_subtitle { color: #333333; font-size: 85%; font-weight: initial; padding-top: 3px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; border-top-color: #FFFFFF; border-top-width: 0; }
#pb_tbl .gt_heading { background-color: #FFFFFF; text-align: left; border-bottom-color: #FFFFFF; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; }
#pb_tbl .gt_bottom_border { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; }
#pb_tbl .gt_col_headings { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; }
#pb_tbl .gt_col_heading { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; overflow-x: hidden; }
#pb_tbl .gt_column_spanner_outer { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; padding-top: 0; padding-bottom: 0; padding-left: 4px; padding-right: 4px; }
#pb_tbl .gt_column_spanner_outer:first-child { padding-left: 0; }
#pb_tbl .gt_column_spanner_outer:last-child { padding-right: 0; }
#pb_tbl .gt_column_spanner { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; overflow-x: hidden; display: inline-block; width: 100%; }
#pb_tbl .gt_spanner_row { border-bottom-style: hidden; }
#pb_tbl .gt_group_heading { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; text-align: left; }
#pb_tbl .gt_empty_group_heading { padding: 0.5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: middle; }
#pb_tbl .gt_from_md&gt; :first-child { margin-top: 0; }
#pb_tbl .gt_from_md&gt; :last-child { margin-bottom: 0; }
#pb_tbl .gt_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; margin: 10px; border-top-style: solid; border-top-width: 1px; border-top-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; overflow-x: hidden; }
#pb_tbl .gt_stub { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; }
#pb_tbl .gt_stub_row_group { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; vertical-align: top; }
#pb_tbl .gt_row_group_first td { border-top-width: 2px; }
#pb_tbl .gt_row_group_first th { border-top-width: 2px; }
#pb_tbl .gt_striped { color: #333333; background-color: #F4F4F4; }
#pb_tbl .gt_table_body { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; }
#pb_tbl .gt_grand_summary_row { color: #333333; background-color: #FFFFFF; text-transform: inherit; padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; }
#pb_tbl .gt_first_grand_summary_row_bottom { border-top-style: double; border-top-width: 6px; border-top-color: #D3D3D3; }
#pb_tbl .gt_last_grand_summary_row_top { border-bottom-style: double; border-bottom-width: 6px; border-bottom-color: #D3D3D3; }
#pb_tbl .gt_sourcenotes { color: #333333; background-color: #FFFFFF; border-bottom-style: none; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; }
#pb_tbl .gt_sourcenote { font-size: 90%; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; text-align: left; }
#pb_tbl .gt_left { text-align: left; }
#pb_tbl .gt_center { text-align: center; }
#pb_tbl .gt_right { text-align: right; font-variant-numeric: tabular-nums; }
#pb_tbl .gt_font_normal { font-weight: normal; }
#pb_tbl .gt_font_bold { font-weight: bold; }
#pb_tbl .gt_font_italic { font-style: italic; }
#pb_tbl .gt_super { font-size: 65%; }
#pb_tbl .gt_footnote_marks { font-size: 75%; vertical-align: 0.4em; position: initial; }
#pb_tbl .gt_asterisk { font-size: 100%; vertical-align: 0; }</p>
<p></style></p>
<table style="table-layout: fixed;; width: 0px" class="gt_table" data-quarto-disable-processing="true" data-quarto-bootstrap="false">
<colgroup>
  <col style="width:4px;"/>
  <col style="width:35px;"/>
  <col style="width:190px;"/>
  <col style="width:120px;"/>
  <col style="width:120px;"/>
  <col style="width:50px;"/>
  <col style="width:50px;"/>
  <col style="width:60px;"/>
  <col style="width:60px;"/>
  <col style="width:60px;"/>
  <col style="width:30px;"/>
  <col style="width:30px;"/>
  <col style="width:30px;"/>
  <col style="width:65px;"/>
</colgroup>
<thead>
  <tr class="gt_heading">
    <td colspan="14" class="gt_heading gt_title gt_font_normal" style="color: #444444;font-size: 28px;text-align: left;font-weight: bold; text-align: left;">Pointblank Validation</td>
  </tr>
  <tr class="gt_heading">
    <td colspan="14" class="gt_heading gt_subtitle gt_font_normal gt_bottom_border" style="text-align: left;"><div><span style='text-decoration-style: solid; text-decoration-color: #ADD8E6; text-decoration-line: underline; text-underline-position: under; color: #333333; font-variant-numeric: tabular-nums; padding-left: 4px; margin-right: 5px; padding-right: 2px;'>2026-03-13|19:09:28</span><div style="padding-top: 10px; padding-bottom: 5px;"><span style='background-color: #0075FF; color: #FFFFFF; padding: 0.5em 0.5em; position: inherit; text-transform: uppercase; margin: 5px 10px 5px 0px; border: solid 1px #0075FF; font-weight: bold; padding: 2px 10px 2px 10px; font-size: 10px;'>Polars</span></div></div></td>
  </tr>
<tr class="gt_col_headings">
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-status_color"></th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-i"></th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-type_upd">STEP</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-columns_upd">COLUMNS</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-values_upd">VALUES</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-tbl">TBL</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-eval">EVAL</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-test_units">UNITS</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-pass">PASS</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-fail">FAIL</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-w_upd">W</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-e_upd">E</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-c_upd">C</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-extract_upd">EXT</th>
</tr>
</thead>
<tbody class="gt_table_body">
  <tr>
    <td style="height: 40px; background-color: #EBBC14; color: transparent;font-size: 0px;" class="gt_row gt_left">#EBBC14</td>
    <td style="height: 40px; color: #666666;font-size: 13px;font-weight: bold;" class="gt_row gt_right">1</td>
    <td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_left">
        <div style="margin: 0; padding: 0; display: inline-block; height: 30px; vertical-align: middle; width: 16%;">
            <!--?xml version="1.0" encoding="UTF-8"?--><?xml version="1.0" encoding="UTF-8"?>
<svg width="30px" height="30px" viewBox="0 0 67 67" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="background: #FFFFFF;">
    <title>col_vals_gt</title>
    <g id="Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="col_vals_gt" transform="translate(1.500000, 1.500000)" fill-rule="nonzero">
            <path d="M55,0 C57.4852813,0 59.7352813,1.00735931 61.363961,2.63603897 C62.9926407,4.26471863 64,6.51471863 64,9 L64,9 L64,64 L9,64 C6.51471862,64 4.26471862,62.9926407 2.63603897,61.363961 C1.00735931,59.7352814 0,57.4852814 0,55 L0,55 L0,9 C0,6.51471863 1.00735931,4.26471863 2.63603897,2.63603897 C4.26471862,1.00735931 6.51471862,0 9,0 L9,0 L55,0 Z" id="rectangle" stroke="#000000" stroke-width="2" fill="#FFFFFF"></path>
            <path d="M48.7619048,10 L15.2380953,10 C12.3466667,10 10,12.3466667 10,15.2380952 L10,48.7619048 C10,51.6533333 12.3466667,54 15.2380953,54 L48.7619048,54 C51.6533333,54 54,51.6533333 54,48.7619048 L54,15.2380952 C54,12.3466667 51.6533333,10 48.7619048,10 Z M25.2638095,44.3828571 L24.0695238,42.6647619 L39.5847619,32 L24.0695238,21.3352381 L25.2638095,19.6171429 L43.2828572,32 L25.2638095,44.3828571 Z" id="greater_than" fill="#000000"></path>
        </g>
    </g>
</svg>
        </div>
        <div style="font-family: 'IBM Plex Mono', monospace, courier; color: black; font-size: 11px; display: inline-block; vertical-align: middle;">
            <div>col_vals_gt()</div>
        </div>
<pre><code>    &lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;d&lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;1000&lt;/td&gt;
&lt;td style=&quot;height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;&quot; class=&quot;gt_row gt_center&quot;&gt;&lt;svg width=&quot;25px&quot; height=&quot;25px&quot; viewBox=&quot;0 0 25 25&quot; version=&quot;1.1&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot; style=&quot;vertical-align: middle;&quot;&gt;
&lt;g id=&quot;unchanged&quot; stroke=&quot;none&quot; stroke-width=&quot;1&quot; fill=&quot;none&quot; fill-rule=&quot;evenodd&quot;&gt;
    &lt;g id=&quot;unchanged&quot; transform=&quot;translate(0.500000, 0.570147)&quot;&gt;
        &lt;rect id=&quot;Rectangle&quot; x=&quot;0.125132506&quot; y=&quot;0&quot; width=&quot;23.749735&quot; height=&quot;23.7894737&quot;&gt;&lt;/rect&gt;
        &lt;path d=&quot;M5.80375046,8.18194736 C3.77191832,8.18194736 2.11875046,9.83495328 2.11875046,11.8669474 C2.11875046,13.8989414 3.77191832,15.5519474 5.80375046,15.5519474 C7.8355826,15.5519474 9.48875046,13.8989414 9.48875046,11.8669474 C9.48875046,9.83495328 7.83552863,8.18194736 5.80375046,8.18194736 Z M5.80375046,14.814915 C4.17821997,14.814915 2.85578285,13.4924778 2.85578285,11.8669474 C2.85578285,10.2414169 4.17821997,8.91897975 5.80375046,8.91897975 C7.42928095,8.91897975 8.75171807,10.2414169 8.75171807,11.8669474 C8.75171807,13.4924778 7.42928095,14.814915 5.80375046,14.814915 Z&quot; id=&quot;Shape&quot; fill=&quot;#000000&quot; fill-rule=&quot;nonzero&quot;&gt;&lt;/path&gt;
        &lt;path d=&quot;M13.9638189,8.699335 C13.9364621,8.70430925 13.9091059,8.71176968 13.8842359,8.71923074 C13.7822704,8.73663967 13.6877654,8.77643115 13.6056956,8.83860518 L10.2433156,11.3852598 C10.0766886,11.5046343 9.97720993,11.6986181 9.97720993,11.9025491 C9.97720993,12.1064807 10.0766886,12.3004639 10.2433156,12.4198383 L13.6056956,14.966493 C13.891697,15.1803725 14.2970729,15.1231721 14.5109517,14.8371707 C14.7248313,14.5511692 14.6676309,14.145794 14.3816294,13.9319145 L12.5313257,12.5392127 L21.8812495,12.5392127 L21.8812495,11.2658854 L12.5313257,11.2658854 L14.3816294,9.87318364 C14.6377872,9.71650453 14.7497006,9.40066014 14.6477351,9.11714553 C14.5482564,8.83363156 14.262255,8.65954352 13.9638189,8.699335 Z&quot; id=&quot;arrow&quot; fill=&quot;#000000&quot; transform=&quot;translate(15.929230, 11.894737) rotate(-180.000000) translate(-15.929230, -11.894737) &quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
&lt;/g&gt;
</code></pre>
<p></svg></td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color:#4CA64C;">✓</span></td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_right">13</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">7<br />0.54</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">6<br />0.46</td>
<td style="height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color: #AAAAAA;">●</span></td>
<td style="height: 40px; background-color: #FCFCFC;" class="gt_row gt_center"><span style="color: #EBBC14;">●</span></td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center">—</td>
<td style="height: 40px;" class="gt_row gt_center"><a href="data:text/csv;base64,X3Jvd19udW1fLGRhdGVfdGltZSxkYXRlLGEsYixjLGQsZSxmCjUsMjAxNi0wMS0wOVQxMjozNjowMC4wMDAwMDAsMjAxNi0wMS0wOSw4LDMtbGRtLTAzOCw3LDI4My45NCx0cnVlLGxvdwo3LDIwMTYtMDEtMTVUMTg6NDY6MDAuMDAwMDAwLDIwMTYtMDEtMTUsNywxLWtudy0wOTMsMyw4NDMuMzQsdHJ1ZSxoaWdoCjksMjAxNi0wMS0yMFQwNDozMDowMC4wMDAwMDAsMjAxNi0wMS0yMCwzLDUtYmNlLTY0Miw5LDgzNy45MyxmYWxzZSxoaWdoCjEwLDIwMTYtMDEtMjBUMDQ6MzA6MDAuMDAwMDAwLDIwMTYtMDEtMjAsMyw1LWJjZS02NDIsOSw4MzcuOTMsZmFsc2UsaGlnaAoxMSwyMDE2LTAxLTI2VDIwOjA3OjAwLjAwMDAwMCwyMDE2LTAxLTI2LDQsMi1kbXgtMDEwLDcsODMzLjk4LHRydWUsbG93CjEyLDIwMTYtMDEtMjhUMDI6NTE6MDAuMDAwMDAwLDIwMTYtMDEtMjgsMiw3LWRteC0wMTAsOCwxMDguMzQsZmFsc2UsbG93Cg==" download="extract_0001.csv"><button style="background-color: #67C2DC; color: #FFFFFF; border: none; padding: 5px; font-weight: bold; cursor: pointer; border-radius: 4px;">CSV</button></a></td></p>
  </tr>
</tbody>
</table>
</div>
<p>In this example:</p>
<ol>
<li>we&rsquo;re validating that values in column &ldquo;d&rdquo; are greater than 1000</li>
<li>we set a warning threshold of 1 (triggers if any values fail)</li>
<li>we define an action that prints a warning message when the threshold is exceeded</li>
</ol>
<p>Since several values in column <code>d</code> are below <code>1000</code>, our &lsquo;warning&rsquo; action is triggered and the
message appears above the validation report.</p>
<h2 id="the-anatomy-of-actions">The Anatomy of Actions
</h2>
<p>The <a href="https://posit-dev.github.io/pointblank/reference/Actions.html" target="_blank" rel="noopener"><code>Actions</code></a>
 class is a very
important piece of Pointblank&rsquo;s response system. Actions can be defined in several ways:</p>
<ol>
<li><strong>String messages</strong>: simple text output to the console</li>
<li><strong>Callable functions</strong>: custom Python functions that execute when triggered</li>
<li><strong>Lists of strings/callables</strong>: multiple actions that execute in sequence</li>
</ol>
<p>Actions can be paired with different severity levels:</p>
<ul>
<li>&lsquo;warning&rsquo;: for minor issues that need attention</li>
<li>&rsquo;error&rsquo;: for more significant problems</li>
<li>&lsquo;critical&rsquo;: for severe issues that require immediate action</li>
</ul>
<p>The <code>v0.8.0</code> release added two (very) useful new parameters:</p>
<ul>
<li><code>default=</code>: apply the same action to all threshold levels</li>
<li><code>highest_only=</code>: only trigger the action for the highest threshold level reached (<code>True</code> by
default)</li>
</ul>
<p>Let&rsquo;s see how these work in practice:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">log_problem</span><span class="p">():</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># Simple action that runs when thresholds are exceeded</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;A validation threshold has been exceeded!&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">validation_2</span> <span class="o">=</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">pb</span><span class="o">.</span><span class="n">Validate</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="n">data</span><span class="o">=</span><span class="n">pb</span><span class="o">.</span><span class="n">load_dataset</span><span class="p">(</span><span class="n">dataset</span><span class="o">=</span><span class="s2">&#34;game_revenue&#34;</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">        <span class="n">thresholds</span><span class="o">=</span><span class="n">pb</span><span class="o">.</span><span class="n">Thresholds</span><span class="p">(</span><span class="n">warning</span><span class="o">=</span><span class="mf">0.05</span><span class="p">,</span> <span class="n">error</span><span class="o">=</span><span class="mf">0.10</span><span class="p">,</span> <span class="n">critical</span><span class="o">=</span><span class="mf">0.15</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">        <span class="n">actions</span><span class="o">=</span><span class="n">pb</span><span class="o">.</span><span class="n">Actions</span><span class="p">(</span><span class="n">default</span><span class="o">=</span><span class="n">log_problem</span><span class="p">)</span>  <span class="c1"># Apply this action to all threshold levels</span>
</span></span><span class="line"><span class="cl">    <span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">col_vals_regex</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="n">columns</span><span class="o">=</span><span class="s2">&#34;player_id&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="n">pattern</span><span class="o">=</span><span class="sa">r</span><span class="s2">&#34;[A-Z]</span><span class="si">{12}</span><span class="s2">\d</span><span class="si">{3}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">col_vals_gt</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="n">columns</span><span class="o">=</span><span class="s2">&#34;item_revenue&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="n">value</span><span class="o">=</span><span class="mf">0.10</span>
</span></span><span class="line"><span class="cl">    <span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">interrogate</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">validation_2</span>
</span></span></code></pre></td></tr></table>
</div>
</div><pre><code>A validation threshold has been exceeded!
</code></pre>
<div id="pb_tbl" style="padding-left:0px;padding-right:0px;padding-top:10px;padding-bottom:10px;overflow-x:auto;overflow-y:auto;width:auto;height:auto;">
<style>
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono&display=swap');
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans&display=swap');
#pb_tbl table {
          font-family: 'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Helvetica Neue', 'Fira Sans', 'Droid Sans', Arial, sans-serif;
          -webkit-font-smoothing: antialiased;
          -moz-osx-font-smoothing: grayscale;
        }
<p>#pb_tbl thead, tbody, tfoot, tr, td, th { border-style: none; }
tr { background-color: transparent; }
#pb_tbl p { margin: 0; padding: 0; }
#pb_tbl .gt_table { display: table; border-collapse: collapse; line-height: normal; margin-left: auto; margin-right: auto; color: #333333; font-size: 90%; font-weight: normal; font-style: normal; background-color: #FFFFFF; width: auto; border-top-style: solid; border-top-width: 2px; border-top-color: #A8A8A8; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #A8A8A8; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; }
#pb_tbl .gt_caption { padding-top: 4px; padding-bottom: 4px; }
#pb_tbl .gt_title { color: #333333; font-size: 125%; font-weight: initial; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; border-bottom-color: #FFFFFF; border-bottom-width: 0; }
#pb_tbl .gt_subtitle { color: #333333; font-size: 85%; font-weight: initial; padding-top: 3px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; border-top-color: #FFFFFF; border-top-width: 0; }
#pb_tbl .gt_heading { background-color: #FFFFFF; text-align: left; border-bottom-color: #FFFFFF; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; }
#pb_tbl .gt_bottom_border { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; }
#pb_tbl .gt_col_headings { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; }
#pb_tbl .gt_col_heading { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; overflow-x: hidden; }
#pb_tbl .gt_column_spanner_outer { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; padding-top: 0; padding-bottom: 0; padding-left: 4px; padding-right: 4px; }
#pb_tbl .gt_column_spanner_outer:first-child { padding-left: 0; }
#pb_tbl .gt_column_spanner_outer:last-child { padding-right: 0; }
#pb_tbl .gt_column_spanner { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; overflow-x: hidden; display: inline-block; width: 100%; }
#pb_tbl .gt_spanner_row { border-bottom-style: hidden; }
#pb_tbl .gt_group_heading { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; text-align: left; }
#pb_tbl .gt_empty_group_heading { padding: 0.5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: middle; }
#pb_tbl .gt_from_md&gt; :first-child { margin-top: 0; }
#pb_tbl .gt_from_md&gt; :last-child { margin-bottom: 0; }
#pb_tbl .gt_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; margin: 10px; border-top-style: solid; border-top-width: 1px; border-top-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; overflow-x: hidden; }
#pb_tbl .gt_stub { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; }
#pb_tbl .gt_stub_row_group { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; vertical-align: top; }
#pb_tbl .gt_row_group_first td { border-top-width: 2px; }
#pb_tbl .gt_row_group_first th { border-top-width: 2px; }
#pb_tbl .gt_striped { color: #333333; background-color: #F4F4F4; }
#pb_tbl .gt_table_body { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; }
#pb_tbl .gt_grand_summary_row { color: #333333; background-color: #FFFFFF; text-transform: inherit; padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; }
#pb_tbl .gt_first_grand_summary_row_bottom { border-top-style: double; border-top-width: 6px; border-top-color: #D3D3D3; }
#pb_tbl .gt_last_grand_summary_row_top { border-bottom-style: double; border-bottom-width: 6px; border-bottom-color: #D3D3D3; }
#pb_tbl .gt_sourcenotes { color: #333333; background-color: #FFFFFF; border-bottom-style: none; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; }
#pb_tbl .gt_sourcenote { font-size: 90%; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; text-align: left; }
#pb_tbl .gt_left { text-align: left; }
#pb_tbl .gt_center { text-align: center; }
#pb_tbl .gt_right { text-align: right; font-variant-numeric: tabular-nums; }
#pb_tbl .gt_font_normal { font-weight: normal; }
#pb_tbl .gt_font_bold { font-weight: bold; }
#pb_tbl .gt_font_italic { font-style: italic; }
#pb_tbl .gt_super { font-size: 65%; }
#pb_tbl .gt_footnote_marks { font-size: 75%; vertical-align: 0.4em; position: initial; }
#pb_tbl .gt_asterisk { font-size: 100%; vertical-align: 0; }</p>
<p></style></p>
<table style="table-layout: fixed;; width: 0px" class="gt_table" data-quarto-disable-processing="true" data-quarto-bootstrap="false">
<colgroup>
  <col style="width:4px;"/>
  <col style="width:35px;"/>
  <col style="width:190px;"/>
  <col style="width:120px;"/>
  <col style="width:120px;"/>
  <col style="width:50px;"/>
  <col style="width:50px;"/>
  <col style="width:60px;"/>
  <col style="width:60px;"/>
  <col style="width:60px;"/>
  <col style="width:30px;"/>
  <col style="width:30px;"/>
  <col style="width:30px;"/>
  <col style="width:65px;"/>
</colgroup>
<thead>
  <tr class="gt_heading">
    <td colspan="14" class="gt_heading gt_title gt_font_normal" style="color: #444444;font-size: 28px;text-align: left;font-weight: bold; text-align: left;">Pointblank Validation</td>
  </tr>
  <tr class="gt_heading">
    <td colspan="14" class="gt_heading gt_subtitle gt_font_normal gt_bottom_border" style="text-align: left;"><div><span style='text-decoration-style: solid; text-decoration-color: #ADD8E6; text-decoration-line: underline; text-underline-position: under; color: #333333; font-variant-numeric: tabular-nums; padding-left: 4px; margin-right: 5px; padding-right: 2px;'>2026-03-13|19:09:28</span><div style="padding-top: 10px; padding-bottom: 5px;"><span style='background-color: #0075FF; color: #FFFFFF; padding: 0.5em 0.5em; position: inherit; text-transform: uppercase; margin: 5px 10px 5px 0px; border: solid 1px #0075FF; font-weight: bold; padding: 2px 10px 2px 10px; font-size: 10px;'>Polars</span><span><span style="background-color: #AAAAAA; color: white; padding: 0.5em 0.5em; position: inherit; text-transform: uppercase; margin: 5px 0px 5px 5px; border: solid 1px #AAAAAA; font-weight: bold; padding: 2px 15px 2px 15px; font-size: smaller;">WARNING</span><span style="background-color: none; color: #333333; padding: 0.5em 0.5em; position: inherit; margin: 5px 0px 5px -4px; font-weight: bold; border: solid 1px #AAAAAA; padding: 2px 15px 2px 15px; font-size: smaller; margin-right: 5px;">0.05</span><span style="background-color: #EBBC14; color: white; padding: 0.5em 0.5em; position: inherit; text-transform: uppercase; margin: 5px 0px 5px 1px; border: solid 1px #EBBC14; font-weight: bold; padding: 2px 15px 2px 15px; font-size: smaller;">ERROR</span><span style="background-color: none; color: #333333; padding: 0.5em 0.5em; position: inherit; margin: 5px 0px 5px -4px; font-weight: bold; border: solid 1px #EBBC14; padding: 2px 15px 2px 15px; font-size: smaller; margin-right: 5px;">0.1</span><span style="background-color: #FF3300; color: white; padding: 0.5em 0.5em; position: inherit; text-transform: uppercase; margin: 5px 0px 5px 1px; border: solid 1px #FF3300; font-weight: bold; padding: 2px 15px 2px 15px; font-size: smaller;">CRITICAL</span><span style="background-color: none; color: #333333; padding: 0.5em 0.5em; position: inherit; margin: 5px 0px 5px -4px; font-weight: bold; border: solid 1px #FF3300; padding: 2px 15px 2px 15px; font-size: smaller;">0.15</span></span></div></div></td>
  </tr>
<tr class="gt_col_headings">
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-status_color"></th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-i"></th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-type_upd">STEP</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-columns_upd">COLUMNS</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-values_upd">VALUES</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-tbl">TBL</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-eval">EVAL</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-test_units">UNITS</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-pass">PASS</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-fail">FAIL</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-w_upd">W</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-e_upd">E</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-c_upd">C</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-extract_upd">EXT</th>
</tr>
</thead>
<tbody class="gt_table_body">
  <tr>
    <td style="height: 40px; background-color: #4CA64C; color: transparent;font-size: 0px;" class="gt_row gt_left">#4CA64C</td>
    <td style="height: 40px; color: #666666;font-size: 13px;font-weight: bold;" class="gt_row gt_right">1</td>
    <td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_left">
        <div style="margin: 0; padding: 0; display: inline-block; height: 30px; vertical-align: middle; width: 16%;">
            <!--?xml version="1.0" encoding="UTF-8"?--><?xml version="1.0" encoding="UTF-8"?>
<svg width="30px" height="30px" viewBox="0 0 67 67" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <title>col_vals_regex</title>
    <g id="Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="col_vals_regex" transform="translate(0.000000, 0.034483)">
            <path d="M56.712234,1 C59.1975153,1 61.4475153,2.00735931 63.076195,3.63603897 C64.7048747,5.26471863 65.712234,7.51471863 65.712234,10 L65.712234,10 L65.712234,65 L10.712234,65 C8.22695259,65 5.97695259,63.9926407 4.34827294,62.363961 C2.71959328,60.7352814 1.71223397,58.4852814 1.71223397,56 L1.71223397,56 L1.71223397,10 C1.71223397,7.51471863 2.71959328,5.26471863 4.34827294,3.63603897 C5.97695259,2.00735931 8.22695259,1 10.712234,1 L10.712234,1 Z" id="rectangle" stroke="#000000" stroke-width="2" fill="#FFFFFF"></path>
            <g id="regex_symbols" transform="translate(18.000000, 12.000000)" fill="#000000" fill-rule="nonzero">
                <path d="M4.17434508,33.013582 C1.94895328,33.013582 0.138006923,34.8245284 0.138006923,37.0499202 C0.138006923,39.275312 1.94895328,41.0862583 4.17434508,41.0862583 C6.39973688,41.0862583 8.21068324,39.275312 8.21068324,37.0499202 C8.21068324,34.8245284 6.39973688,33.013582 4.17434508,33.013582 Z" id="full_stop"></path>
                <path d="M23.9479718,23.3175402 L21.5628264,23.3175402 C21.2344032,23.3175402 20.9665401,23.0520067 20.9665401,22.7212538 L20.9665401,15.1022979 L14.3445004,18.8873192 C14.0626621,19.050366 13.7016292,18.952538 13.5362533,18.6706991 L12.3436806,16.6442575 C12.262157,16.506832 12.2388642,16.3437852 12.2807909,16.1900549 C12.3203879,16.0363251 12.4205455,15.9058874 12.557971,15.8266929 L19.1800101,11.9880994 L12.557971,8.15183511 C12.4205455,8.07264112 12.3203879,7.93987439 12.2807909,7.78614401 C12.2388642,7.63241423 12.262157,7.46936689 12.3413509,7.33194137 L13.5339237,5.30549975 C13.6993001,5.02366143 14.0626621,4.92816199 14.3445004,5.09120934 L20.9665401,8.87390091 L20.9665401,1.25494501 C20.9665401,0.926521818 21.2344032,0.658658658 21.5628264,0.658658658 L23.9479718,0.658658658 C24.2787247,0.658658658 24.5442582,0.926521818 24.5442582,1.25494501 L24.5442582,8.87390091 L31.1662979,5.09120934 C31.4481362,4.92816199 31.8091691,5.02366143 31.9745455,5.30549975 L33.1671182,7.33194137 C33.2486413,7.46936689 33.2719341,7.63241423 33.2300074,7.78614401 C33.1904104,7.93987439 33.0902528,8.07264112 32.9528278,8.15183511 L26.3307882,11.9880994 L32.9528278,15.8243638 C33.0879237,15.9058874 33.1880813,16.0363251 33.2300074,16.1900549 C33.269605,16.3437852 33.2486413,16.506832 33.1671182,16.6442575 L31.9745455,18.6706991 C31.8091691,18.952538 31.4481362,19.050366 31.1662979,18.8849895 L24.5442582,15.1022979 L24.5442582,22.7212538 C24.5442582,23.0520067 24.2787247,23.3175402 23.9479718,23.3175402 Z" id="asterisk"></path>
            </g>
        </g>
    </g>
</svg>
        </div>
        <div style="font-family: 'IBM Plex Mono', monospace, courier; color: black; font-size: 11px; display: inline-block; vertical-align: middle;">
            <div>col_vals_regex()</div>
        </div>
<pre><code>    &lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;player_id&lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;[A-Z]{12}\d{3}&lt;/td&gt;
&lt;td style=&quot;height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;&quot; class=&quot;gt_row gt_center&quot;&gt;&lt;svg width=&quot;25px&quot; height=&quot;25px&quot; viewBox=&quot;0 0 25 25&quot; version=&quot;1.1&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot; style=&quot;vertical-align: middle;&quot;&gt;
&lt;g id=&quot;unchanged&quot; stroke=&quot;none&quot; stroke-width=&quot;1&quot; fill=&quot;none&quot; fill-rule=&quot;evenodd&quot;&gt;
    &lt;g id=&quot;unchanged&quot; transform=&quot;translate(0.500000, 0.570147)&quot;&gt;
        &lt;rect id=&quot;Rectangle&quot; x=&quot;0.125132506&quot; y=&quot;0&quot; width=&quot;23.749735&quot; height=&quot;23.7894737&quot;&gt;&lt;/rect&gt;
        &lt;path d=&quot;M5.80375046,8.18194736 C3.77191832,8.18194736 2.11875046,9.83495328 2.11875046,11.8669474 C2.11875046,13.8989414 3.77191832,15.5519474 5.80375046,15.5519474 C7.8355826,15.5519474 9.48875046,13.8989414 9.48875046,11.8669474 C9.48875046,9.83495328 7.83552863,8.18194736 5.80375046,8.18194736 Z M5.80375046,14.814915 C4.17821997,14.814915 2.85578285,13.4924778 2.85578285,11.8669474 C2.85578285,10.2414169 4.17821997,8.91897975 5.80375046,8.91897975 C7.42928095,8.91897975 8.75171807,10.2414169 8.75171807,11.8669474 C8.75171807,13.4924778 7.42928095,14.814915 5.80375046,14.814915 Z&quot; id=&quot;Shape&quot; fill=&quot;#000000&quot; fill-rule=&quot;nonzero&quot;&gt;&lt;/path&gt;
        &lt;path d=&quot;M13.9638189,8.699335 C13.9364621,8.70430925 13.9091059,8.71176968 13.8842359,8.71923074 C13.7822704,8.73663967 13.6877654,8.77643115 13.6056956,8.83860518 L10.2433156,11.3852598 C10.0766886,11.5046343 9.97720993,11.6986181 9.97720993,11.9025491 C9.97720993,12.1064807 10.0766886,12.3004639 10.2433156,12.4198383 L13.6056956,14.966493 C13.891697,15.1803725 14.2970729,15.1231721 14.5109517,14.8371707 C14.7248313,14.5511692 14.6676309,14.145794 14.3816294,13.9319145 L12.5313257,12.5392127 L21.8812495,12.5392127 L21.8812495,11.2658854 L12.5313257,11.2658854 L14.3816294,9.87318364 C14.6377872,9.71650453 14.7497006,9.40066014 14.6477351,9.11714553 C14.5482564,8.83363156 14.262255,8.65954352 13.9638189,8.699335 Z&quot; id=&quot;arrow&quot; fill=&quot;#000000&quot; transform=&quot;translate(15.929230, 11.894737) rotate(-180.000000) translate(-15.929230, -11.894737) &quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
&lt;/g&gt;
</code></pre>
<p></svg></td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color:#4CA64C;">✓</span></td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_right">2000</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">2000<br />1.00</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">0<br />0.00</td>
<td style="height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color: #AAAAAA;">○</span></td>
<td style="height: 40px; background-color: #FCFCFC;" class="gt_row gt_center"><span style="color: #EBBC14;">○</span></td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color: #FF3300;">○</span></td>
<td style="height: 40px;" class="gt_row gt_center">—</td></p>
  </tr>
  <tr>
    <td style="height: 40px; background-color: #FF3300; color: transparent;font-size: 0px;" class="gt_row gt_left">#FF3300</td>
    <td style="height: 40px; color: #666666;font-size: 13px;font-weight: bold;" class="gt_row gt_right">2</td>
    <td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_left">
        <div style="margin: 0; padding: 0; display: inline-block; height: 30px; vertical-align: middle; width: 16%;">
            <!--?xml version="1.0" encoding="UTF-8"?--><?xml version="1.0" encoding="UTF-8"?>
<svg width="30px" height="30px" viewBox="0 0 67 67" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="background: #FFFFFF;">
    <title>col_vals_gt</title>
    <g id="Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="col_vals_gt" transform="translate(1.500000, 1.500000)" fill-rule="nonzero">
            <path d="M55,0 C57.4852813,0 59.7352813,1.00735931 61.363961,2.63603897 C62.9926407,4.26471863 64,6.51471863 64,9 L64,9 L64,64 L9,64 C6.51471862,64 4.26471862,62.9926407 2.63603897,61.363961 C1.00735931,59.7352814 0,57.4852814 0,55 L0,55 L0,9 C0,6.51471863 1.00735931,4.26471863 2.63603897,2.63603897 C4.26471862,1.00735931 6.51471862,0 9,0 L9,0 L55,0 Z" id="rectangle" stroke="#000000" stroke-width="2" fill="#FFFFFF"></path>
            <path d="M48.7619048,10 L15.2380953,10 C12.3466667,10 10,12.3466667 10,15.2380952 L10,48.7619048 C10,51.6533333 12.3466667,54 15.2380953,54 L48.7619048,54 C51.6533333,54 54,51.6533333 54,48.7619048 L54,15.2380952 C54,12.3466667 51.6533333,10 48.7619048,10 Z M25.2638095,44.3828571 L24.0695238,42.6647619 L39.5847619,32 L24.0695238,21.3352381 L25.2638095,19.6171429 L43.2828572,32 L25.2638095,44.3828571 Z" id="greater_than" fill="#000000"></path>
        </g>
    </g>
</svg>
        </div>
        <div style="font-family: 'IBM Plex Mono', monospace, courier; color: black; font-size: 11px; display: inline-block; vertical-align: middle;">
            <div>col_vals_gt()</div>
        </div>
<pre><code>    &lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;item_revenue&lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;0.1&lt;/td&gt;
&lt;td style=&quot;height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;&quot; class=&quot;gt_row gt_center&quot;&gt;&lt;svg width=&quot;25px&quot; height=&quot;25px&quot; viewBox=&quot;0 0 25 25&quot; version=&quot;1.1&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot; style=&quot;vertical-align: middle;&quot;&gt;
&lt;g id=&quot;unchanged&quot; stroke=&quot;none&quot; stroke-width=&quot;1&quot; fill=&quot;none&quot; fill-rule=&quot;evenodd&quot;&gt;
    &lt;g id=&quot;unchanged&quot; transform=&quot;translate(0.500000, 0.570147)&quot;&gt;
        &lt;rect id=&quot;Rectangle&quot; x=&quot;0.125132506&quot; y=&quot;0&quot; width=&quot;23.749735&quot; height=&quot;23.7894737&quot;&gt;&lt;/rect&gt;
        &lt;path d=&quot;M5.80375046,8.18194736 C3.77191832,8.18194736 2.11875046,9.83495328 2.11875046,11.8669474 C2.11875046,13.8989414 3.77191832,15.5519474 5.80375046,15.5519474 C7.8355826,15.5519474 9.48875046,13.8989414 9.48875046,11.8669474 C9.48875046,9.83495328 7.83552863,8.18194736 5.80375046,8.18194736 Z M5.80375046,14.814915 C4.17821997,14.814915 2.85578285,13.4924778 2.85578285,11.8669474 C2.85578285,10.2414169 4.17821997,8.91897975 5.80375046,8.91897975 C7.42928095,8.91897975 8.75171807,10.2414169 8.75171807,11.8669474 C8.75171807,13.4924778 7.42928095,14.814915 5.80375046,14.814915 Z&quot; id=&quot;Shape&quot; fill=&quot;#000000&quot; fill-rule=&quot;nonzero&quot;&gt;&lt;/path&gt;
        &lt;path d=&quot;M13.9638189,8.699335 C13.9364621,8.70430925 13.9091059,8.71176968 13.8842359,8.71923074 C13.7822704,8.73663967 13.6877654,8.77643115 13.6056956,8.83860518 L10.2433156,11.3852598 C10.0766886,11.5046343 9.97720993,11.6986181 9.97720993,11.9025491 C9.97720993,12.1064807 10.0766886,12.3004639 10.2433156,12.4198383 L13.6056956,14.966493 C13.891697,15.1803725 14.2970729,15.1231721 14.5109517,14.8371707 C14.7248313,14.5511692 14.6676309,14.145794 14.3816294,13.9319145 L12.5313257,12.5392127 L21.8812495,12.5392127 L21.8812495,11.2658854 L12.5313257,11.2658854 L14.3816294,9.87318364 C14.6377872,9.71650453 14.7497006,9.40066014 14.6477351,9.11714553 C14.5482564,8.83363156 14.262255,8.65954352 13.9638189,8.699335 Z&quot; id=&quot;arrow&quot; fill=&quot;#000000&quot; transform=&quot;translate(15.929230, 11.894737) rotate(-180.000000) translate(-15.929230, -11.894737) &quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
&lt;/g&gt;
</code></pre>
<p></svg></td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color:#4CA64C;">✓</span></td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_right">2000</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">1440<br />0.72</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">560<br />0.28</td>
<td style="height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color: #AAAAAA;">●</span></td>
<td style="height: 40px; background-color: #FCFCFC;" class="gt_row gt_center"><span style="color: #EBBC14;">●</span></td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color: #FF3300;">●</span></td>
<td style="height: 40px;" class="gt_row gt_center"><a href="data:text/csv;base64,X3Jvd19udW1fLHBsYXllcl9pZCxzZXNzaW9uX2lkLHNlc3Npb25fc3RhcnQsdGltZSxpdGVtX3R5cGUsaXRlbV9uYW1lLGl0ZW1fcmV2ZW51ZSxzZXNzaW9uX2R1cmF0aW9uLHN0YXJ0X2RheSxhY3F1aXNpdGlvbixjb3VudHJ5CjUsRUNQQU5PSVhMWkhGODk2LEVDUEFOT0lYTFpIRjg5Ni1oZHU5amtscywyMDE1LTAxLTAxVDExOjUwOjAyLjAwMDAwMCswMDAwLDIwMTUtMDEtMDFUMTE6NTU6MjAuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAzLDM1LjIsMjAxNS0wMS0wMSxnb29nbGUsR2VybWFueQo2LEVDUEFOT0lYTFpIRjg5NixFQ1BBTk9JWExaSEY4OTYtaGR1OWprbHMsMjAxNS0wMS0wMVQxMTo1MDowMi4wMDAwMDArMDAwMCwyMDE1LTAxLTAxVDEyOjA4OjU2LjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDcsMzUuMiwyMDE1LTAxLTAxLGdvb2dsZSxHZXJtYW55CjcsRUNQQU5PSVhMWkhGODk2LEVDUEFOT0lYTFpIRjg5Ni1oZHU5amtscywyMDE1LTAxLTAxVDExOjUwOjAyLjAwMDAwMCswMDAwLDIwMTUtMDEtMDFUMTI6MTQ6MDguMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4wOCwzNS4yLDIwMTUtMDEtMDEsZ29vZ2xlLEdlcm1hbnkKMTAsRlhXVU9SR1lOSkFFMjcxLEZYV1VPUkdZTkpBRTI3MS1ldDdiczYzOSwyMDE1LTAxLTAxVDE1OjE3OjE4LjAwMDAwMCswMDAwLDIwMTUtMDEtMDFUMTU6MTk6MzYuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA4LDMwLjcsMjAxNS0wMS0wMSxvcmdhbmljLENhbmFkYQoxMyxGWFdVT1JHWU5KQUUyNzEsRlhXVU9SR1lOSkFFMjcxLWV0N2JzNjM5LDIwMTUtMDEtMDFUMTU6MTc6MTguMDAwMDAwKzAwMDAsMjAxNS0wMS0wMVQxNTo0Mzo0Mi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDQsMzAuNywyMDE1LTAxLTAxLG9yZ2FuaWMsQ2FuYWRhCjE2LENQWlZNR1dRU0lPSDEzMixDUFpWTUdXUVNJT0gxMzItZnlzOXg2MnYsMjAxNS0wMS0wMVQxNTo1MjoyNC4wMDAwMDArMDAwMCwyMDE1LTAxLTAxVDE2OjA2OjEyLjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDc3LDEzLjgsMjAxNS0wMS0wMSxjcm9zc3Byb21vLFNvdXRoIEtvcmVhCjE4LEZYV1VPUkdZTkpBRTI3MSxGWFdVT1JHWU5KQUUyNzEtN3djZGVhaXAsMjAxNS0wMS0wMVQyMjoxNzoyNy4wMDAwMDArMDAwMCwyMDE1LTAxLTAxVDIyOjIyOjU3LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wOCwxMy4xLDIwMTUtMDEtMDEsb3JnYW5pYyxDYW5hZGEKMjEsQ1BaVk1HV1FTSU9IMTMyLENQWlZNR1dRU0lPSDEzMi05M2pxbm01ZCwyMDE1LTAxLTAxVDIyOjQyOjMzLjAwMDAwMCswMDAwLDIwMTUtMDEtMDFUMjI6NDQ6MTUuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyOCwyMC43LDIwMTUtMDEtMDEsY3Jvc3Nwcm9tbyxTb3V0aCBLb3JlYQoyNyxRSkdWT0JMQVRJSFc0NTcsUUpHVk9CTEFUSUhXNDU3LThheGg1MWJ2LDIwMTUtMDEtMDJUMDE6MDI6MDYuMDAwMDAwKzAwMDAsMjAxNS0wMS0wMlQwMToyNjowNi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDg4LDMwLjUsMjAxNS0wMS0wMixvdGhlcl9jYW1wYWlnbixTd2VkZW4KMjksRUNQQU5PSVhMWkhGODk2LEVDUEFOT0lYTFpIRjg5Ni14ZWIxbWk0ciwyMDE1LTAxLTAyVDAyOjQxOjU3LjAwMDAwMCswMDAwLDIwMTUtMDEtMDJUMDI6NTA6MjcuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyLDI4LjMsMjAxNS0wMS0wMSxnb29nbGUsR2VybWFueQozMyxFQ1BBTk9JWExaSEY4OTYsRUNQQU5PSVhMWkhGODk2LXhlYjFtaTRyLDIwMTUtMDEtMDJUMDI6NDE6NTcuMDAwMDAwKzAwMDAsMjAxNS0wMS0wMlQwMzowNDoxNS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDMsMjguMywyMDE1LTAxLTAxLGdvb2dsZSxHZXJtYW55CjM5LEZYV1VPUkdZTkpBRTI3MSxGWFdVT1JHWU5KQUUyNzEtOGszamJzeG8sMjAxNS0wMS0wMlQwMzo1MDoyNy4wMDAwMDArMDAwMCwyMDE1LTAxLTAyVDA0OjA0OjIxLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNSwxNS41LDIwMTUtMDEtMDEsb3JnYW5pYyxDYW5hZGEKNDAsRlhXVU9SR1lOSkFFMjcxLEZYV1VPUkdZTkpBRTI3MS16ODM0a3RmcCwyMDE1LTAxLTAyVDA4OjQyOjQwLjAwMDAwMCswMDAwLDIwMTUtMDEtMDJUMDg6NDU6NTIuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAzLDM3LjAsMjAxNS0wMS0wMSxvcmdhbmljLENhbmFkYQo0MSxGWFdVT1JHWU5KQUUyNzEsRlhXVU9SR1lOSkFFMjcxLXo4MzRrdGZwLDIwMTUtMDEtMDJUMDg6NDI6NDAuMDAwMDAwKzAwMDAsMjAxNS0wMS0wMlQwOTowMDoxNi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDcsMzcuMCwyMDE1LTAxLTAxLG9yZ2FuaWMsQ2FuYWRhCjQzLEZYV1VPUkdZTkpBRTI3MSxGWFdVT1JHWU5KQUUyNzEtejgzNGt0ZnAsMjAxNS0wMS0wMlQwODo0Mjo0MC4wMDAwMDArMDAwMCwyMDE1LTAxLTAyVDA5OjA5OjI4LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wOCwzNy4wLDIwMTUtMDEtMDEsb3JnYW5pYyxDYW5hZGEKNDUsRlhXVU9SR1lOSkFFMjcxLEZYV1VPUkdZTkpBRTI3MS16ODM0a3RmcCwyMDE1LTAxLTAyVDA4OjQyOjQwLjAwMDAwMCswMDAwLDIwMTUtMDEtMDJUMDk6MTU6NDAuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjEsMzcuMCwyMDE1LTAxLTAxLG9yZ2FuaWMsQ2FuYWRhCjQ5LEZYV1VPUkdZTkpBRTI3MSxGWFdVT1JHWU5KQUUyNzEtM2w5Y3Y4YnMsMjAxNS0wMS0wMlQxMjoyOTo0MC4wMDAwMDArMDAwMCwyMDE1LTAxLTAyVDEyOjM1OjA0LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMywzMy4yLDIwMTUtMDEtMDEsb3JnYW5pYyxDYW5hZGEKNTAsRlhXVU9SR1lOSkFFMjcxLEZYV1VPUkdZTkpBRTI3MS0zbDljdjhicywyMDE1LTAxLTAyVDEyOjI5OjQwLjAwMDAwMCswMDAwLDIwMTUtMDEtMDJUMTI6Mzk6MzQuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyLDMzLjIsMjAxNS0wMS0wMSxvcmdhbmljLENhbmFkYQo1MixGWFdVT1JHWU5KQUUyNzEsRlhXVU9SR1lOSkFFMjcxLTNsOWN2OGJzLDIwMTUtMDEtMDJUMTI6Mjk6NDAuMDAwMDAwKzAwMDAsMjAxNS0wMS0wMlQxMjo1OTowNC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDgsMzMuMiwyMDE1LTAxLTAxLG9yZ2FuaWMsQ2FuYWRhCjU0LENQWlZNR1dRU0lPSDEzMixDUFpWTUdXUVNJT0gxMzItNTlmNmtvaXEsMjAxNS0wMS0wMlQxNTozNzowOC4wMDAwMDArMDAwMCwyMDE1LTAxLTAyVDE1OjUwOjA4LjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDk4LDE1LjUsMjAxNS0wMS0wMSxjcm9zc3Byb21vLFNvdXRoIEtvcmVhCjY3LEZYV1VPUkdZTkpBRTI3MSxGWFdVT1JHWU5KQUUyNzEtNXNtMTJyNHYsMjAxNS0wMS0wM1QwNTo1ODoyOS4wMDAwMDArMDAwMCwyMDE1LTAxLTAzVDA2OjE5OjQ3LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNCwzMC42LDIwMTUtMDEtMDEsb3JnYW5pYyxDYW5hZGEKNjksRlhXVU9SR1lOSkFFMjcxLEZYV1VPUkdZTkpBRTI3MS01c20xMnI0diwyMDE1LTAxLTAzVDA1OjU4OjI5LjAwMDAwMCswMDAwLDIwMTUtMDEtMDNUMDY6MjU6NTkuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA5LDMwLjYsMjAxNS0wMS0wMSxvcmdhbmljLENhbmFkYQo3MCxFQ1BBTk9JWExaSEY4OTYsRUNQQU5PSVhMWkhGODk2LWVvYndnbDRuLDIwMTUtMDEtMDNUMDY6MTE6MTAuMDAwMDAwKzAwMDAsMjAxNS0wMS0wM1QwNjoxNjoyOC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDcsMTAuNiwyMDE1LTAxLTAxLGdvb2dsZSxHZXJtYW55CjczLFFKR1ZPQkxBVElIVzQ1NyxRSkdWT0JMQVRJSFc0NTcteXp2NHBkYXcsMjAxNS0wMS0wM1QxNDozMDoxNy4wMDAwMDArMDAwMCwyMDE1LTAxLTAzVDE0OjM1OjU5LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMzMsMTIuMCwyMDE1LTAxLTAyLG90aGVyX2NhbXBhaWduLFN3ZWRlbgo3NixGS1JDSEVMWVRQQlE2MzEsRktSQ0hFTFlUUEJRNjMxLWc1amt3YXVyLDIwMTUtMDEtMDNUMjE6MzQ6NTEuMDAwMDAwKzAwMDAsMjAxNS0wMS0wM1QyMTozODozOS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDMsMTMuOSwyMDE1LTAxLTAzLG9yZ2FuaWMsTWV4aWNvCjg1LEVRVUROR1pJQ01BSzQ4MixFUVVETkdaSUNNQUs0ODItOHVheTl3NzUsMjAxNS0wMS0wNFQwMToyMTowMy4wMDAwMDArMDAwMCwyMDE1LTAxLTA0VDAxOjQwOjM5LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wOCwyNi44LDIwMTUtMDEtMDQsZ29vZ2xlLEdlcm1hbnkKOTEsRUNQQU5PSVhMWkhGODk2LEVDUEFOT0lYTFpIRjg5Ni03ejloc2FncSwyMDE1LTAxLTA0VDAzOjE1OjM0LjAwMDAwMCswMDAwLDIwMTUtMDEtMDRUMDM6MzI6NTguMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAzLDM1LjEsMjAxNS0wMS0wMSxnb29nbGUsR2VybWFueQo5MyxFQ1BBTk9JWExaSEY4OTYsRUNQQU5PSVhMWkhGODk2LTd6OWhzYWdxLDIwMTUtMDEtMDRUMDM6MTU6MzQuMDAwMDAwKzAwMDAsMjAxNS0wMS0wNFQwMzo0MzoyOC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDIsMzUuMSwyMDE1LTAxLTAxLGdvb2dsZSxHZXJtYW55Cjk4LFBNRkhWTkNVRVlMVDkxMyxQTUZIVk5DVUVZTFQ5MTMtbzhnd3hjMWQsMjAxNS0wMS0wNFQwNToxNDozOC4wMDAwMDArMDAwMCwyMDE1LTAxLTA0VDA1OjIwOjU2LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNywxNS4zLDIwMTUtMDEtMDQsb3JnYW5pYyxBdXN0cmlhCjk5LFBNRkhWTkNVRVlMVDkxMyxQTUZIVk5DVUVZTFQ5MTMtbzhnd3hjMWQsMjAxNS0wMS0wNFQwNToxNDozOC4wMDAwMDArMDAwMCwyMDE1LTAxLTA0VDA1OjIyOjM4LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNCwxNS4zLDIwMTUtMDEtMDQsb3JnYW5pYyxBdXN0cmlhCjEwMCxQTUZIVk5DVUVZTFQ5MTMsUE1GSFZOQ1VFWUxUOTEzLW84Z3d4YzFkLDIwMTUtMDEtMDRUMDU6MTQ6MzguMDAwMDAwKzAwMDAsMjAxNS0wMS0wNFQwNToyNToyNi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDMsMTUuMywyMDE1LTAxLTA0LG9yZ2FuaWMsQXVzdHJpYQoxMDIsSllFQkNMTlVaVFhRNDU3LEpZRUJDTE5VWlRYUTQ1Ny01cnZubzFoNywyMDE1LTAxLTA0VDA5OjE1OjAwLjAwMDAwMCswMDAwLDIwMTUtMDEtMDRUMDk6MzA6MzYuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4wNDUsMzAuMiwyMDE1LTAxLTA0LG90aGVyX2NhbXBhaWduLEVneXB0CjEwMyxKWUVCQ0xOVVpUWFE0NTcsSllFQkNMTlVaVFhRNDU3LTVydm5vMWg3LDIwMTUtMDEtMDRUMDk6MTU6MDAuMDAwMDAwKzAwMDAsMjAxNS0wMS0wNFQwOTo0NDoxOC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDUsMzAuMiwyMDE1LTAxLTA0LG90aGVyX2NhbXBhaWduLEVneXB0CjEwOCxRSkdWT0JMQVRJSFc0NTcsUUpHVk9CTEFUSUhXNDU3LW45dzFrNDI3LDIwMTUtMDEtMDRUMTY6NDE6MjMuMDAwMDAwKzAwMDAsMjAxNS0wMS0wNFQxNjo0Njo1OS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDc3LDM3LjEsMjAxNS0wMS0wMixvdGhlcl9jYW1wYWlnbixTd2VkZW4KMTIwLFpQVElITlNWRllBUTE0NixaUFRJSE5TVkZZQVExNDYtemZramhxM2ksMjAxNS0wMS0wNVQwMTo1Mzo0MC4wMDAwMDArMDAwMCwyMDE1LTAxLTA1VDAyOjAxOjUyLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNDIsMjAuMCwyMDE1LTAxLTA0LGZhY2Vib29rLE1leGljbwoxMjEsWlBUSUhOU1ZGWUFRMTQ2LFpQVElITlNWRllBUTE0Ni16ZmtqaHEzaSwyMDE1LTAxLTA1VDAxOjUzOjQwLjAwMDAwMCswMDAwLDIwMTUtMDEtMDVUMDI6MDU6MDQuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA0MiwyMC4wLDIwMTUtMDEtMDQsZmFjZWJvb2ssTWV4aWNvCjEyMixFUVVETkdaSUNNQUs0ODIsRVFVRE5HWklDTUFLNDgyLTRrdjU4OWVtLDIwMTUtMDEtMDVUMDI6MjA6MTYuMDAwMDAwKzAwMDAsMjAxNS0wMS0wNVQwMjoyMzozNC4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjA3LDI5LjgsMjAxNS0wMS0wNCxnb29nbGUsR2VybWFueQoxMjUsRVFVRE5HWklDTUFLNDgyLEVRVUROR1pJQ01BSzQ4Mi00a3Y1ODllbSwyMDE1LTAxLTA1VDAyOjIwOjE2LjAwMDAwMCswMDAwLDIwMTUtMDEtMDVUMDI6NDA6MzQuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA1LDI5LjgsMjAxNS0wMS0wNCxnb29nbGUsR2VybWFueQoxMzEsRktSQ0hFTFlUUEJRNjMxLEZLUkNIRUxZVFBCUTYzMS1qN284MWQyeCwyMDE1LTAxLTA1VDA4OjUzOjQ4LjAwMDAwMCswMDAwLDIwMTUtMDEtMDVUMDk6MjE6NDguMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4wOTYsMjkuNywyMDE1LTAxLTAzLG9yZ2FuaWMsTWV4aWNvCjEzNixFQ1BBTk9JWExaSEY4OTYsRUNQQU5PSVhMWkhGODk2LXpqN3B4bmN0LDIwMTUtMDEtMDVUMDk6MTM6MDMuMDAwMDAwKzAwMDAsMjAxNS0wMS0wNVQwOTozMjo0NS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMSwyOC4xLDIwMTUtMDEtMDEsZ29vZ2xlLEdlcm1hbnkKMTM4LFpMUVhPQkFUVlBVTjM0NixaTFFYT0JBVFZQVU4zNDYtcDM5bmVzNXEsMjAxNS0wMS0wNVQxMDo1OToxMi4wMDAwMDArMDAwMCwyMDE1LTAxLTA1VDExOjExOjAwLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMzYsMTguOCwyMDE1LTAxLTA1LG9yZ2FuaWMsTm9yd2F5CjE0MCxaTFFYT0JBVFZQVU4zNDYsWkxRWE9CQVRWUFVOMzQ2LWE4eDRqNXFsLDIwMTUtMDEtMDVUMTI6MDg6MTkuMDAwMDAwKzAwMDAsMjAxNS0wMS0wNVQxMjoxMDo0OS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDI3LDE3LjcsMjAxNS0wMS0wNSxvcmdhbmljLE5vcndheQoxNDgsWlBUSUhOU1ZGWUFRMTQ2LFpQVElITlNWRllBUTE0Ni1wNTh5ZW51MywyMDE1LTAxLTA1VDIyOjQyOjQ3LjAwMDAwMCswMDAwLDIwMTUtMDEtMDVUMjM6MDg6MTcuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyNCwzMy4yLDIwMTUtMDEtMDQsZmFjZWJvb2ssTWV4aWNvCjE1MSxHQVlJQkxVQ09FREo3MzIsR0FZSUJMVUNPRURKNzMyLWlrenF5YnUyLDIwMTUtMDEtMDZUMDE6MTE6MDkuMDAwMDAwKzAwMDAsMjAxNS0wMS0wNlQwMTozODo1MS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDUsMzIuNSwyMDE1LTAxLTAzLG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwoxNTMsVlBESktTWlJZUVhFMTIzLFZQREpLU1pSWVFYRTEyMy1wZWt4OGZ6MSwyMDE1LTAxLTA2VDAzOjUwOjMwLjAwMDAwMCswMDAwLDIwMTUtMDEtMDZUMDQ6MDA6MDYuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAzLDM0LjUsMjAxNS0wMS0wNixnb29nbGUsQXVzdHJhbGlhCjE1NixJQ0JBVVpLR1NRUEYxNDUsSUNCQVVaS0dTUVBGMTQ1LXh1ejduNXlwLDIwMTUtMDEtMDZUMDY6MTg6NDguMDAwMDAwKzAwMDAsMjAxNS0wMS0wNlQwNjoyNToyNC4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjA4LDIzLjMsMjAxNS0wMS0wNixnb29nbGUsU291dGggQWZyaWNhCjE2MSxES09BWEVMU0ZQV0M3MjMsREtPQVhFTFNGUFdDNzIzLTI0OW1yemV2LDIwMTUtMDEtMDZUMDk6MjQ6MzUuMDAwMDAwKzAwMDAsMjAxNS0wMS0wNlQwOTozMjoyMy4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDY2LDM0LjYsMjAxNS0wMS0wNSxmYWNlYm9vayxKYXBhbgoxNjUsSllFQkNMTlVaVFhRNDU3LEpZRUJDTE5VWlRYUTQ1Ny0yNzRjejh3cSwyMDE1LTAxLTA2VDA5OjM2OjIzLjAwMDAwMCswMDAwLDIwMTUtMDEtMDZUMTA6MDM6NDcuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4wOTUsMzMuNCwyMDE1LTAxLTA0LG90aGVyX2NhbXBhaWduLEVneXB0CjE3MCxJQ0JBVVpLR1NRUEYxNDUsSUNCQVVaS0dTUVBGMTQ1LWtiaHl2NHByLDIwMTUtMDEtMDZUMTU6MDI6MzkuMDAwMDAwKzAwMDAsMjAxNS0wMS0wNlQxNToxNDowMy4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjA4NCwyMy4zLDIwMTUtMDEtMDYsZ29vZ2xlLFNvdXRoIEFmcmljYQoxODksUE1GSFZOQ1VFWUxUOTEzLFBNRkhWTkNVRVlMVDkxMy1ycHduYXV2MSwyMDE1LTAxLTA2VDIzOjAxOjU4LjAwMDAwMCswMDAwLDIwMTUtMDEtMDZUMjM6MDI6MDQuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA4LDE3LjYsMjAxNS0wMS0wNCxvcmdhbmljLEF1c3RyaWEKMTk3LEVRVUROR1pJQ01BSzQ4MixFUVVETkdaSUNNQUs0ODIta3h2Y21xZnIsMjAxNS0wMS0wNlQyMzozMDozMC4wMDAwMDArMDAwMCwyMDE1LTAxLTA2VDIzOjQ1OjU0LjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMSwxNy40LDIwMTUtMDEtMDQsZ29vZ2xlLEdlcm1hbnkKMjAwLFpQVElITlNWRllBUTE0NixaUFRJSE5TVkZZQVExNDYtc2MzbWJ1MmUsMjAxNS0wMS0wNlQyMzo0NDo1MS4wMDAwMDArMDAwMCwyMDE1LTAxLTA2VDIzOjQ4OjMzLjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDcyLDI3LjMsMjAxNS0wMS0wNCxmYWNlYm9vayxNZXhpY28KMjAzLFpQVElITlNWRllBUTE0NixaUFRJSE5TVkZZQVExNDYtc2MzbWJ1MmUsMjAxNS0wMS0wNlQyMzo0NDo1MS4wMDAwMDArMDAwMCwyMDE1LTAxLTA3VDAwOjA5OjI3LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNiwyNy4zLDIwMTUtMDEtMDQsZmFjZWJvb2ssTWV4aWNvCjIxMixWUERKS1NaUllRWEUxMjMsVlBESktTWlJZUVhFMTIzLWQ0eWdjenI5LDIwMTUtMDEtMDdUMDE6MTc6MjkuMDAwMDAwKzAwMDAsMjAxNS0wMS0wN1QwMToyMzoyOS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDIsMzUuMiwyMDE1LTAxLTA2LGdvb2dsZSxBdXN0cmFsaWEKMjE1LEhLSlBPTVFXTFZESTY3NCxIS0pQT01RV0xWREk2NzQta2hiaWYzeGUsMjAxNS0wMS0wN1QwMzo0ODozOC4wMDAwMDArMDAwMCwyMDE1LTAxLTA3VDAzOjUwOjAyLjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDksMzUuMiwyMDE1LTAxLTA2LG90aGVyX2NhbXBhaWduLFNwYWluCjIxNyxIS0pQT01RV0xWREk2NzQsSEtKUE9NUVdMVkRJNjc0LWtoYmlmM3hlLDIwMTUtMDEtMDdUMDM6NDg6MzguMDAwMDAwKzAwMDAsMjAxNS0wMS0wN1QwMzo1Mzo1Ni4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjA5LDM1LjIsMjAxNS0wMS0wNixvdGhlcl9jYW1wYWlnbixTcGFpbgoyMTksR1NRSlhJT0tZTUVBNzEyLEdTUUpYSU9LWU1FQTcxMi00NXpldWxwZCwyMDE1LTAxLTA3VDA0OjQ2OjEyLjAwMDAwMCswMDAwLDIwMTUtMDEtMDdUMDQ6NTA6MzYuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAzLDM1LjIsMjAxNS0wMS0wNyxnb29nbGUsR2VybWFueQoyMjUsUUpHVk9CTEFUSUhXNDU3LFFKR1ZPQkxBVElIVzQ1Ny1jMzE3YWx3aiwyMDE1LTAxLTA3VDA1OjUzOjM2LjAwMDAwMCswMDAwLDIwMTUtMDEtMDdUMDU6NTg6NDIuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA3NywxNC4yLDIwMTUtMDEtMDIsb3RoZXJfY2FtcGFpZ24sU3dlZGVuCjIzMCxKWUVCQ0xOVVpUWFE0NTcsSllFQkNMTlVaVFhRNDU3LTl0cWlsc3c4LDIwMTUtMDEtMDdUMDc6MTU6NTMuMDAwMDAwKzAwMDAsMjAxNS0wMS0wN1QwNzozMTo0MS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDMsMzcuMywyMDE1LTAxLTA0LG90aGVyX2NhbXBhaWduLEVneXB0CjIzMixKWUVCQ0xOVVpUWFE0NTcsSllFQkNMTlVaVFhRNDU3LTl0cWlsc3c4LDIwMTUtMDEtMDdUMDc6MTU6NTMuMDAwMDAwKzAwMDAsMjAxNS0wMS0wN1QwNzo0Njo1OS4wMDAwMDArMDAwMCxhZCxhZF8xNXNlYywwLjA4LDM3LjMsMjAxNS0wMS0wNCxvdGhlcl9jYW1wYWlnbixFZ3lwdAoyMzMsSllFQkNMTlVaVFhRNDU3LEpZRUJDTE5VWlRYUTQ1Ny03b3o2NXdmYiwyMDE1LTAxLTA3VDA4OjI0OjAxLjAwMDAwMCswMDAwLDIwMTUtMDEtMDdUMDg6MzQ6MDEuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyLDIxLjAsMjAxNS0wMS0wNCxvdGhlcl9jYW1wYWlnbixFZ3lwdAoyMzUsSllFQkNMTlVaVFhRNDU3LEpZRUJDTE5VWlRYUTQ1Ny03b3o2NXdmYiwyMDE1LTAxLTA3VDA4OjI0OjAxLjAwMDAwMCswMDAwLDIwMTUtMDEtMDdUMDg6MzQ6MzEuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4wNSwyMS4wLDIwMTUtMDEtMDQsb3RoZXJfY2FtcGFpZ24sRWd5cHQKMjM2LEpZRUJDTE5VWlRYUTQ1NyxKWUVCQ0xOVVpUWFE0NTctN296NjV3ZmIsMjAxNS0wMS0wN1QwODoyNDowMS4wMDAwMDArMDAwMCwyMDE1LTAxLTA3VDA4OjM0OjQzLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMzUsMjEuMCwyMDE1LTAxLTA0LG90aGVyX2NhbXBhaWduLEVneXB0CjIzOCxRSkdWT0JMQVRJSFc0NTcsUUpHVk9CTEFUSUhXNDU3LW9qd21zcTgzLDIwMTUtMDEtMDdUMDg6Mjk6NDUuMDAwMDAwKzAwMDAsMjAxNS0wMS0wN1QwODozNjoyMS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDk5LDE3LjcsMjAxNS0wMS0wMixvdGhlcl9jYW1wYWlnbixTd2VkZW4KMjM5LFFKR1ZPQkxBVElIVzQ1NyxRSkdWT0JMQVRJSFc0NTctb2p3bXNxODMsMjAxNS0wMS0wN1QwODoyOTo0NS4wMDAwMDArMDAwMCwyMDE1LTAxLTA3VDA4OjQyOjU3LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wOTksMTcuNywyMDE1LTAxLTAyLG90aGVyX2NhbXBhaWduLFN3ZWRlbgoyNDYsTERTVUhDUkFZS01PMTc5LExEU1VIQ1JBWUtNTzE3OS00aWh0b3F5dSwyMDE1LTAxLTA3VDEyOjE4OjMwLjAwMDAwMCswMDAwLDIwMTUtMDEtMDdUMTI6MzQ6MDAuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA1NCwyNi4yLDIwMTUtMDEtMDcsb3RoZXJfY2FtcGFpZ24sUG9ydHVnYWwKMjUwLEtCRVFaR0ZTUlBISjQ3OSxLQkVRWkdGU1JQSEo0NzktNzY1amZ1bWssMjAxNS0wMS0wN1QxMjo0NToxMC4wMDAwMDArMDAwMCwyMDE1LTAxLTA3VDEyOjU0OjEwLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMjEsMjIuMSwyMDE1LTAxLTA3LG9yZ2FuaWMsUnVzc2lhCjI1MixLQkVRWkdGU1JQSEo0NzksS0JFUVpHRlNSUEhKNDc5LTc2NWpmdW1rLDIwMTUtMDEtMDdUMTI6NDU6MTAuMDAwMDAwKzAwMDAsMjAxNS0wMS0wN1QxMjo1NjoyMi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDMsMjIuMSwyMDE1LTAxLTA3LG9yZ2FuaWMsUnVzc2lhCjI1MyxLSUxXWllIUlNKRUczMTYsS0lMV1pZSFJTSkVHMzE2LW90OWJ2bGFkLDIwMTUtMDEtMDdUMTM6NDg6MzQuMDAwMDAwKzAwMDAsMjAxNS0wMS0wN1QxNDowNTo1Mi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDg4LDMwLjgsMjAxNS0wMS0wNCxvcmdhbmljLERlbm1hcmsKMjU0LFBaQk5SS1NNVUxIWDIxMyxQWkJOUktTTVVMSFgyMTMta29zdjhobGUsMjAxNS0wMS0wN1QxMzo0OToxOS4wMDAwMDArMDAwMCwyMDE1LTAxLTA3VDE0OjA0OjAxLjAwMDAwMCswMDAwLGFkLGFkXzE1c2VjLDAuMDU2LDIyLjIsMjAxNS0wMS0wNyxvcmdhbmljLEluZGlhCjI1NSxQWkJOUktTTVVMSFgyMTMsUFpCTlJLU01VTEhYMjEzLWtvc3Y4aGxlLDIwMTUtMDEtMDdUMTM6NDk6MTkuMDAwMDAwKzAwMDAsMjAxNS0wMS0wN1QxNDowNTozMS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDA0LDIyLjIsMjAxNS0wMS0wNyxvcmdhbmljLEluZGlhCjI2MixPTUNWVUFJS1NEVFI2NTEsT01DVlVBSUtTRFRSNjUxLWJkbTNvODI2LDIwMTUtMDEtMDdUMTM6NTM6NDYuMDAwMDAwKzAwMDAsMjAxNS0wMS0wN1QxNDoxNTo1Mi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDMsMzUuNiwyMDE1LTAxLTA3LG90aGVyX2NhbXBhaWduLFVuaXRlZCBTdGF0ZXMKMjgwLFZQREpLU1pSWVFYRTEyMyxWUERKS1NaUllRWEUxMjMtYWwzOG1pcmUsMjAxNS0wMS0wN1QxNzoyMDowNy4wMDAwMDArMDAwMCwyMDE1LTAxLTA3VDE3OjI0OjA3LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNiwzMC4zLDIwMTUtMDEtMDYsZ29vZ2xlLEF1c3RyYWxpYQoyODQsVlBESktTWlJZUVhFMTIzLFZQREpLU1pSWVFYRTEyMy1hbDM4bWlyZSwyMDE1LTAxLTA3VDE3OjIwOjA3LjAwMDAwMCswMDAwLDIwMTUtMDEtMDdUMTc6MzQ6MTkuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA1LDMwLjMsMjAxNS0wMS0wNixnb29nbGUsQXVzdHJhbGlhCjI4NSxWUERKS1NaUllRWEUxMjMsVlBESktTWlJZUVhFMTIzLWFsMzhtaXJlLDIwMTUtMDEtMDdUMTc6MjA6MDcuMDAwMDAwKzAwMDAsMjAxNS0wMS0wN1QxNzo0ODowNy4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDgsMzAuMywyMDE1LTAxLTA2LGdvb2dsZSxBdXN0cmFsaWEKMjg3LFBaQk5SS1NNVUxIWDIxMyxQWkJOUktTTVVMSFgyMTMtanhud2FoNHYsMjAxNS0wMS0wN1QxNzo1NToyMi4wMDAwMDArMDAwMCwyMDE1LTAxLTA3VDE3OjU4OjQ2LjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDMsMzAuOSwyMDE1LTAxLTA3LG9yZ2FuaWMsSW5kaWEKMjg4LFBaQk5SS1NNVUxIWDIxMyxQWkJOUktTTVVMSFgyMTMtanhud2FoNHYsMjAxNS0wMS0wN1QxNzo1NToyMi4wMDAwMDArMDAwMCwyMDE1LTAxLTA3VDE4OjEyOjA0LjAwMDAwMCswMDAwLGFkLGFkXzE1c2VjLDAuMDQsMzAuOSwyMDE1LTAxLTA3LG9yZ2FuaWMsSW5kaWEKMjg5LFBaQk5SS1NNVUxIWDIxMyxQWkJOUktTTVVMSFgyMTMtanhud2FoNHYsMjAxNS0wMS0wN1QxNzo1NToyMi4wMDAwMDArMDAwMCwyMDE1LTAxLTA3VDE4OjIyOjI4LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMiwzMC45LDIwMTUtMDEtMDcsb3JnYW5pYyxJbmRpYQoyOTEsUFpCTlJLU01VTEhYMjEzLFBaQk5SS1NNVUxIWDIxMy1qeG53YWg0diwyMDE1LTAxLTA3VDE3OjU1OjIyLjAwMDAwMCswMDAwLDIwMTUtMDEtMDdUMTg6MjQ6MjguMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAxNCwzMC45LDIwMTUtMDEtMDcsb3JnYW5pYyxJbmRpYQoyOTQsU0ZKQ1pPVEtHQUlENjQ1LFNGSkNaT1RLR0FJRDY0NS1pYmRtd3Y5NywyMDE1LTAxLTA3VDE4OjI3OjQ2LjAwMDAwMCswMDAwLDIwMTUtMDEtMDdUMTg6Mzc6NTguMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4wNywzMC4wLDIwMTUtMDEtMDYsZ29vZ2xlLEZyYW5jZQozMDAsSUNCQVVaS0dTUVBGMTQ1LElDQkFVWktHU1FQRjE0NS1wYTRkbXFpMywyMDE1LTAxLTA3VDIwOjI2OjQxLjAwMDAwMCswMDAwLDIwMTUtMDEtMDdUMjA6MzI6MDUuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4wNTYsMTkuOSwyMDE1LTAxLTA2LGdvb2dsZSxTb3V0aCBBZnJpY2EKMzAxLElDQkFVWktHU1FQRjE0NSxJQ0JBVVpLR1NRUEYxNDUtcGE0ZG1xaTMsMjAxNS0wMS0wN1QyMDoyNjo0MS4wMDAwMDArMDAwMCwyMDE1LTAxLTA3VDIwOjQxOjM1LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMjIsMTkuOSwyMDE1LTAxLTA2LGdvb2dsZSxTb3V0aCBBZnJpY2EKMzAyLFpQVElITlNWRllBUTE0NixaUFRJSE5TVkZZQVExNDYteHQzNzZlZmQsMjAxNS0wMS0wN1QyMDo1Mzo0Mi4wMDAwMDArMDAwMCwyMDE1LTAxLTA3VDIxOjAwOjM2LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNTQsMzEuMywyMDE1LTAxLTA0LGZhY2Vib29rLE1leGljbwozMDYsS0JFUVpHRlNSUEhKNDc5LEtCRVFaR0ZTUlBISjQ3OS02eHp5bmp2ZCwyMDE1LTAxLTA3VDIyOjM3OjM3LjAwMDAwMCswMDAwLDIwMTUtMDEtMDdUMjI6NDM6NTUuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyNywyNy40LDIwMTUtMDEtMDcsb3JnYW5pYyxSdXNzaWEKMzA4LEtCRVFaR0ZTUlBISjQ3OSxLQkVRWkdGU1JQSEo0NzktNnh6eW5qdmQsMjAxNS0wMS0wN1QyMjozNzozNy4wMDAwMDArMDAwMCwyMDE1LTAxLTA3VDIyOjU4OjEzLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMDksMjcuNCwyMDE1LTAxLTA3LG9yZ2FuaWMsUnVzc2lhCjMxMyxHQVlJQkxVQ09FREo3MzIsR0FZSUJMVUNPRURKNzMyLTlpZmd0dmFyLDIwMTUtMDEtMDdUMjI6NTY6MzkuMDAwMDAwKzAwMDAsMjAxNS0wMS0wN1QyMzoyMjo1MS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDQsMzQuNSwyMDE1LTAxLTAzLG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwozMTcsSlZCWkNQS1hIRk1VNDkxLEpWQlpDUEtYSEZNVTQ5MS1ib3dnZjd0biwyMDE1LTAxLTA3VDIzOjIyOjI4LjAwMDAwMCswMDAwLDIwMTUtMDEtMDdUMjM6Mjc6NDAuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA5LDIxLjEsMjAxNS0wMS0wNyxvcmdhbmljLFVuaXRlZCBTdGF0ZXMKMzE4LEpWQlpDUEtYSEZNVTQ5MSxKVkJaQ1BLWEhGTVU0OTEtYm93Z2Y3dG4sMjAxNS0wMS0wN1QyMzoyMjoyOC4wMDAwMDArMDAwMCwyMDE1LTAxLTA3VDIzOjI4OjA0LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNywyMS4xLDIwMTUtMDEtMDcsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjMyMSxKVkJaQ1BLWEhGTVU0OTEsSlZCWkNQS1hIRk1VNDkxLWJvd2dmN3RuLDIwMTUtMDEtMDdUMjM6MjI6MjguMDAwMDAwKzAwMDAsMjAxNS0wMS0wN1QyMzozNzoyMi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDMsMjEuMSwyMDE1LTAxLTA3LG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwozMjIsUFpCTlJLU01VTEhYMjEzLFBaQk5SS1NNVUxIWDIxMy1zaXh1OG82aiwyMDE1LTAxLTA4VDAwOjM2OjEzLjAwMDAwMCswMDAwLDIwMTUtMDEtMDhUMDA6Mzk6MDcuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyLDEyLjAsMjAxNS0wMS0wNyxvcmdhbmljLEluZGlhCjMyMyxQWkJOUktTTVVMSFgyMTMsUFpCTlJLU01VTEhYMjEzLXNpeHU4bzZqLDIwMTUtMDEtMDhUMDA6MzY6MTMuMDAwMDAwKzAwMDAsMjAxNS0wMS0wOFQwMDozOToyNS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDIyLDEyLjAsMjAxNS0wMS0wNyxvcmdhbmljLEluZGlhCjMyOSxFUVVETkdaSUNNQUs0ODIsRVFVRE5HWklDTUFLNDgyLXkzZG96d3ZzLDIwMTUtMDEtMDhUMDI6Mjg6MzguMDAwMDAwKzAwMDAsMjAxNS0wMS0wOFQwMjo0NDo1Ni4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjA5LDI5LjMsMjAxNS0wMS0wNCxnb29nbGUsR2VybWFueQozMzEsRVFVRE5HWklDTUFLNDgyLEVRVUROR1pJQ01BSzQ4Mi15M2Rvend2cywyMDE1LTAxLTA4VDAyOjI4OjM4LjAwMDAwMCswMDAwLDIwMTUtMDEtMDhUMDI6NTU6MzguMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA2LDI5LjMsMjAxNS0wMS0wNCxnb29nbGUsR2VybWFueQozMzgsUE1GSFZOQ1VFWUxUOTEzLFBNRkhWTkNVRVlMVDkxMy16eGV5cGFzbSwyMDE1LTAxLTA4VDA1OjA5OjA0LjAwMDAwMCswMDAwLDIwMTUtMDEtMDhUMDU6MTY6NDAuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4wNyw5LjgsMjAxNS0wMS0wNCxvcmdhbmljLEF1c3RyaWEKMzM5LFZQREpLU1pSWVFYRTEyMyxWUERKS1NaUllRWEUxMjMtNTMyeGJ1dnksMjAxNS0wMS0wOFQwNTowOTo0MS4wMDAwMDArMDAwMCwyMDE1LTAxLTA4VDA1OjEzOjU5LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNiwxNy44LDIwMTUtMDEtMDYsZ29vZ2xlLEF1c3RyYWxpYQozNDgsSUNCQVVaS0dTUVBGMTQ1LElDQkFVWktHU1FQRjE0NS1mbGFveWRqNSwyMDE1LTAxLTA4VDEyOjQ4OjEzLjAwMDAwMCswMDAwLDIwMTUtMDEtMDhUMTM6MDg6MjUuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAxNDk5LDI3LjksMjAxNS0wMS0wNixnb29nbGUsU291dGggQWZyaWNhCjM1MCxQWkJOUktTTVVMSFgyMTMsUFpCTlJLU01VTEhYMjEzLW0ybjZ0azFpLDIwMTUtMDEtMDhUMTQ6MTA6MTguMDAwMDAwKzAwMDAsMjAxNS0wMS0wOFQxNDoxNjozMC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDEsMzQuMiwyMDE1LTAxLTA3LG9yZ2FuaWMsSW5kaWEKMzUzLFBaQk5SS1NNVUxIWDIxMyxQWkJOUktTTVVMSFgyMTMtbTJuNnRrMWksMjAxNS0wMS0wOFQxNDoxMDoxOC4wMDAwMDArMDAwMCwyMDE1LTAxLTA4VDE0OjM4OjA2LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMDYsMzQuMiwyMDE1LTAxLTA3LG9yZ2FuaWMsSW5kaWEKMzU0LFBaQk5SS1NNVUxIWDIxMyxQWkJOUktTTVVMSFgyMTMtbTJuNnRrMWksMjAxNS0wMS0wOFQxNDoxMDoxOC4wMDAwMDArMDAwMCwyMDE1LTAxLTA4VDE0OjM4OjA2LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMjQsMzQuMiwyMDE1LTAxLTA3LG9yZ2FuaWMsSW5kaWEKMzYxLEtCRVFaR0ZTUlBISjQ3OSxLQkVRWkdGU1JQSEo0NzktbTVpcHF3MmIsMjAxNS0wMS0wOFQxNTowNzo0NS4wMDAwMDArMDAwMCwyMDE1LTAxLTA4VDE1OjE1OjQ1LjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDMsOS4yLDIwMTUtMDEtMDcsb3JnYW5pYyxSdXNzaWEKMzYyLEtCRVFaR0ZTUlBISjQ3OSxLQkVRWkdGU1JQSEo0NzktZjJlNXJkYWIsMjAxNS0wMS0wOFQxNjoxMTowOC4wMDAwMDArMDAwMCwyMDE1LTAxLTA4VDE2OjE1OjIwLjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDU0LDMzLjEsMjAxNS0wMS0wNyxvcmdhbmljLFJ1c3NpYQozNjUsS0JFUVpHRlNSUEhKNDc5LEtCRVFaR0ZTUlBISjQ3OS1mMmU1cmRhYiwyMDE1LTAxLTA4VDE2OjExOjA4LjAwMDAwMCswMDAwLDIwMTUtMDEtMDhUMTY6MzU6MDIuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAxOCwzMy4xLDIwMTUtMDEtMDcsb3JnYW5pYyxSdXNzaWEKMzY5LFZQREpLU1pSWVFYRTEyMyxWUERKS1NaUllRWEUxMjMtOW5hZzRocGksMjAxNS0wMS0wOFQxODowNDo1Ni4wMDAwMDArMDAwMCwyMDE1LTAxLTA4VDE4OjE0OjQ0LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNCwzNy45LDIwMTUtMDEtMDYsZ29vZ2xlLEF1c3RyYWxpYQozNzEsVlBESktTWlJZUVhFMTIzLFZQREpLU1pSWVFYRTEyMy05bmFnNGhwaSwyMDE1LTAxLTA4VDE4OjA0OjU2LjAwMDAwMCswMDAwLDIwMTUtMDEtMDhUMTg6MjM6NTAuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA1LDM3LjksMjAxNS0wMS0wNixnb29nbGUsQXVzdHJhbGlhCjM3NyxHU1FKWElPS1lNRUE3MTIsR1NRSlhJT0tZTUVBNzEyLTVtNHZzOWtjLDIwMTUtMDEtMDhUMjA6MDg6NTIuMDAwMDAwKzAwMDAsMjAxNS0wMS0wOFQyMDoxMToyOC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDIsMzEuNiwyMDE1LTAxLTA3LGdvb2dsZSxHZXJtYW55CjM5NCxPTUNWVUFJS1NEVFI2NTEsT01DVlVBSUtTRFRSNjUxLTE0YWV1aWRrLDIwMTUtMDEtMDlUMDE6MTg6NDMuMDAwMDAwKzAwMDAsMjAxNS0wMS0wOVQwMTo0MDowMS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDQsMjQuNiwyMDE1LTAxLTA3LG90aGVyX2NhbXBhaWduLFVuaXRlZCBTdGF0ZXMKMzk1LEdTUUpYSU9LWU1FQTcxMixHU1FKWElPS1lNRUE3MTIteXVnZjZhZGgsMjAxNS0wMS0wOVQwMTo1ODo1Mi4wMDAwMDArMDAwMCwyMDE1LTAxLTA5VDAyOjExOjUyLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNywyNy43LDIwMTUtMDEtMDcsZ29vZ2xlLEdlcm1hbnkKNDAxLFFEVVpKSUVUQ0FHVzY1NCxRRFVaSklFVENBR1c2NTQtZ21pNmJvZjEsMjAxNS0wMS0wOVQwMzowNDowNS4wMDAwMDArMDAwMCwyMDE1LTAxLTA5VDAzOjEwOjA1LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNiwxMS4zLDIwMTUtMDEtMDcsZmFjZWJvb2ssU3dpdHplcmxhbmQKNDAzLEtCRVFaR0ZTUlBISjQ3OSxLQkVRWkdGU1JQSEo0NzktN3BhZWtvYzIsMjAxNS0wMS0wOVQwMzowNDo0MS4wMDAwMDArMDAwMCwyMDE1LTAxLTA5VDAzOjE3OjU5LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMywxOC41LDIwMTUtMDEtMDcsb3JnYW5pYyxSdXNzaWEKNDA2LFpQVElITlNWRllBUTE0NixaUFRJSE5TVkZZQVExNDYtNW80N2QyaWwsMjAxNS0wMS0wOVQwNToxMDozMS4wMDAwMDArMDAwMCwyMDE1LTAxLTA5VDA1OjI0OjQ5LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMjQsMzguNywyMDE1LTAxLTA0LGZhY2Vib29rLE1leGljbwo0MTEsUU5MVlJERU9YRllKODkyLFFOTFZSREVPWEZZSjg5Mi1zZjd3ZWh6OSwyMDE1LTAxLTA5VDA3OjI3OjE0LjAwMDAwMCswMDAwLDIwMTUtMDEtMDlUMDc6Mjk6MzIuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAzLDguMSwyMDE1LTAxLTA5LGNyb3NzcHJvbW8sQXVzdHJhbGlhCjQxMixTRkpDWk9US0dBSUQ2NDUsU0ZKQ1pPVEtHQUlENjQ1LWtsNnMyOXV3LDIwMTUtMDEtMDlUMDg6MTg6MTQuMDAwMDAwKzAwMDAsMjAxNS0wMS0wOVQwODoyNzo0NC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDQsMjkuOCwyMDE1LTAxLTA2LGdvb2dsZSxGcmFuY2UKNDE3LEVRVUROR1pJQ01BSzQ4MixFUVVETkdaSUNNQUs0ODItdXB2M2Q4NWgsMjAxNS0wMS0wOVQwODoyMjowMC4wMDAwMDArMDAwMCwyMDE1LTAxLTA5VDA4OjI2OjU0LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMiwzOC45LDIwMTUtMDEtMDQsZ29vZ2xlLEdlcm1hbnkKNDI2LFFOTFZSREVPWEZZSjg5MixRTkxWUkRFT1hGWUo4OTItY3Z3dGpmbzIsMjAxNS0wMS0wOVQxMzo1NDoyOS4wMDAwMDArMDAwMCwyMDE1LTAxLTA5VDEzOjU2OjU5LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMywyOC41LDIwMTUtMDEtMDksY3Jvc3Nwcm9tbyxBdXN0cmFsaWEKNDI4LFFOTFZSREVPWEZZSjg5MixRTkxWUkRFT1hGWUo4OTItY3Z3dGpmbzIsMjAxNS0wMS0wOVQxMzo1NDoyOS4wMDAwMDArMDAwMCwyMDE1LTAxLTA5VDE0OjIxOjI5LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNiwyOC41LDIwMTUtMDEtMDksY3Jvc3Nwcm9tbyxBdXN0cmFsaWEKNDM0LEdGTFlKSEFQTVpXRDYzMSxHRkxZSkhBUE1aV0Q2MzEtd2R6Mzd2Y3QsMjAxNS0wMS0wOVQxNTo1MDoxOC4wMDAwMDArMDAwMCwyMDE1LTAxLTA5VDE1OjUwOjQyLjAwMDAwMCswMDAwLGFkLGFkXzE1c2VjLDAuMDYyLDMwLjksMjAxNS0wMS0wOSxvcmdhbmljLEluZGlhCjQzNSxHRkxZSkhBUE1aV0Q2MzEsR0ZMWUpIQVBNWldENjMxLXdkejM3dmN0LDIwMTUtMDEtMDlUMTU6NTA6MTguMDAwMDAwKzAwMDAsMjAxNS0wMS0wOVQxNTo1MzowNi4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjAyNCwzMC45LDIwMTUtMDEtMDksb3JnYW5pYyxJbmRpYQo0MzYsR0ZMWUpIQVBNWldENjMxLEdGTFlKSEFQTVpXRDYzMS13ZHozN3ZjdCwyMDE1LTAxLTA5VDE1OjUwOjE4LjAwMDAwMCswMDAwLDIwMTUtMDEtMDlUMTU6NTg6MTIuMDAwMDAwKzAwMDAsYWQsYWRfMTVzZWMsMC4wNTQsMzAuOSwyMDE1LTAxLTA5LG9yZ2FuaWMsSW5kaWEKNDM3LEdGTFlKSEFQTVpXRDYzMSxHRkxZSkhBUE1aV0Q2MzEtd2R6Mzd2Y3QsMjAxNS0wMS0wOVQxNTo1MDoxOC4wMDAwMDArMDAwMCwyMDE1LTAxLTA5VDE2OjEyOjA2LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMTQsMzAuOSwyMDE1LTAxLTA5LG9yZ2FuaWMsSW5kaWEKNDM4LEdGTFlKSEFQTVpXRDYzMSxHRkxZSkhBUE1aV0Q2MzEtd2R6Mzd2Y3QsMjAxNS0wMS0wOVQxNTo1MDoxOC4wMDAwMDArMDAwMCwyMDE1LTAxLTA5VDE2OjE3OjM2LjAwMDAwMCswMDAwLGFkLGFkXzE1c2VjLDAuMDUsMzAuOSwyMDE1LTAxLTA5LG9yZ2FuaWMsSW5kaWEKNDQxLE5NUlVXSEFZSlBCUTgyNCxOTVJVV0hBWUpQQlE4MjQtdm9mM2c5eXQsMjAxNS0wMS0wOVQxODoyNzowMS4wMDAwMDArMDAwMCwyMDE1LTAxLTA5VDE4OjQwOjQ5LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNDksMzguMSwyMDE1LTAxLTA4LG9yZ2FuaWMsSG9uZyBLb25nCjQ0NCxaUFRJSE5TVkZZQVExNDYsWlBUSUhOU1ZGWUFRMTQ2LTcydWNzdmtvLDIwMTUtMDEtMDlUMTg6NTI6MTEuMDAwMDAwKzAwMDAsMjAxNS0wMS0wOVQxODo1MjoyOS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDM2LDM2LjgsMjAxNS0wMS0wNCxmYWNlYm9vayxNZXhpY28KNDQ3LFpQVElITlNWRllBUTE0NixaUFRJSE5TVkZZQVExNDYtNzJ1Y3N2a28sMjAxNS0wMS0wOVQxODo1MjoxMS4wMDAwMDArMDAwMCwyMDE1LTAxLTA5VDE5OjIxOjM1LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMzYsMzYuOCwyMDE1LTAxLTA0LGZhY2Vib29rLE1leGljbwo0NDksTERTVUhDUkFZS01PMTc5LExEU1VIQ1JBWUtNTzE3OS1uNWJmZ2p1OCwyMDE1LTAxLTA5VDIwOjIxOjM0LjAwMDAwMCswMDAwLDIwMTUtMDEtMDlUMjA6MjM6MTYuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA1NCwzNS4zLDIwMTUtMDEtMDcsb3RoZXJfY2FtcGFpZ24sUG9ydHVnYWwKNDUwLExEU1VIQ1JBWUtNTzE3OSxMRFNVSENSQVlLTU8xNzktbjViZmdqdTgsMjAxNS0wMS0wOVQyMDoyMTozNC4wMDAwMDArMDAwMCwyMDE1LTAxLTA5VDIwOjM1OjQwLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNzIsMzUuMywyMDE1LTAxLTA3LG90aGVyX2NhbXBhaWduLFBvcnR1Z2FsCjQ2MixMRFNVSENSQVlLTU8xNzksTERTVUhDUkFZS01PMTc5LTR4a282OWVpLDIwMTUtMDEtMDlUMjM6NTQ6MTcuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMFQwMDowMjoyMy4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDE4LDIwLjMsMjAxNS0wMS0wNyxvdGhlcl9jYW1wYWlnbixQb3J0dWdhbAo0NjUsTERTVUhDUkFZS01PMTc5LExEU1VIQ1JBWUtNTzE3OS00eGtvNjllaSwyMDE1LTAxLTA5VDIzOjU0OjE3LjAwMDAwMCswMDAwLDIwMTUtMDEtMTBUMDA6MTE6NDEuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA3MiwyMC4zLDIwMTUtMDEtMDcsb3RoZXJfY2FtcGFpZ24sUG9ydHVnYWwKNDY2LFFKR1ZPQkxBVElIVzQ1NyxRSkdWT0JMQVRJSFc0NTctN29obGcyNmksMjAxNS0wMS0xMFQwMDo0OTozMS4wMDAwMDArMDAwMCwyMDE1LTAxLTEwVDAwOjUwOjEzLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wODgsMTkuNSwyMDE1LTAxLTAyLG90aGVyX2NhbXBhaWduLFN3ZWRlbgo0NjgsUUpHVk9CTEFUSUhXNDU3LFFKR1ZPQkxBVElIVzQ1Ny03b2hsZzI2aSwyMDE1LTAxLTEwVDAwOjQ5OjMxLjAwMDAwMCswMDAwLDIwMTUtMDEtMTBUMDE6MDg6NTUuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA4OCwxOS41LDIwMTUtMDEtMDIsb3RoZXJfY2FtcGFpZ24sU3dlZGVuCjQ2OSxHU1FKWElPS1lNRUE3MTIsR1NRSlhJT0tZTUVBNzEyLTN4cTd3ZzFsLDIwMTUtMDEtMTBUMDA6NTc6MzEuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMFQwMDo1OTowNy4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjA4LDM5LjgsMjAxNS0wMS0wNyxnb29nbGUsR2VybWFueQo0NzEsR1NRSlhJT0tZTUVBNzEyLEdTUUpYSU9LWU1FQTcxMi0zeHE3d2cxbCwyMDE1LTAxLTEwVDAwOjU3OjMxLjAwMDAwMCswMDAwLDIwMTUtMDEtMTBUMDE6Mjg6MzcuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4wOCwzOS44LDIwMTUtMDEtMDcsZ29vZ2xlLEdlcm1hbnkKNDcyLFJNT1NXSEpHRUxDSTY3NSxSTU9TV0hKR0VMQ0k2NzUtejl5bnVzcHIsMjAxNS0wMS0xMFQwNDowOTo1MC4wMDAwMDArMDAwMCwyMDE1LTAxLTEwVDA0OjE4OjU2LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNSwyNy4yLDIwMTUtMDEtMTAsb3RoZXJfY2FtcGFpZ24sRnJhbmNlCjQ3NCxSTU9TV0hKR0VMQ0k2NzUsUk1PU1dISkdFTENJNjc1LXo5eW51c3ByLDIwMTUtMDEtMTBUMDQ6MDk6NTAuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMFQwNDoyODozOC4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjEsMjcuMiwyMDE1LTAxLTEwLG90aGVyX2NhbXBhaWduLEZyYW5jZQo0NzUsUk1PU1dISkdFTENJNjc1LFJNT1NXSEpHRUxDSTY3NS16OXludXNwciwyMDE1LTAxLTEwVDA0OjA5OjUwLjAwMDAwMCswMDAwLDIwMTUtMDEtMTBUMDQ6Mjk6NTYuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjEsMjcuMiwyMDE1LTAxLTEwLG90aGVyX2NhbXBhaWduLEZyYW5jZQo0ODIsVVpRRkhEQkVNWVBWNTk0LFVaUUZIREJFTVlQVjU5NC1ha2NwenR1bywyMDE1LTAxLTEwVDA1OjQ4OjQ2LjAwMDAwMCswMDAwLDIwMTUtMDEtMTBUMDU6NDg6NTguMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA3Miw4LjEsMjAxNS0wMS0xMCxnb29nbGUsU3dpdHplcmxhbmQKNDgzLEdBWUlCTFVDT0VESjczMixHQVlJQkxVQ09FREo3MzItOHVuYzE3MmwsMjAxNS0wMS0xMFQwNjoyMTozNS4wMDAwMDArMDAwMCwyMDE1LTAxLTEwVDA2OjM3OjU5LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMywzNC44LDIwMTUtMDEtMDMsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjQ5MyxMRFNVSENSQVlLTU8xNzksTERTVUhDUkFZS01PMTc5LW1hdzdxZXIxLDIwMTUtMDEtMTBUMDc6MzU6NTcuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMFQwNzo1MTozOS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDcyLDI2LjQsMjAxNS0wMS0wNyxvdGhlcl9jYW1wYWlnbixQb3J0dWdhbAo0OTYsTERTVUhDUkFZS01PMTc5LExEU1VIQ1JBWUtNTzE3OS1tYXc3cWVyMSwyMDE1LTAxLTEwVDA3OjM1OjU3LjAwMDAwMCswMDAwLDIwMTUtMDEtMTBUMDc6NTU6MzMuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA1NCwyNi40LDIwMTUtMDEtMDcsb3RoZXJfY2FtcGFpZ24sUG9ydHVnYWwKNTAzLE1YQ09WRVlJQUtGSDU5NCxNWENPVkVZSUFLRkg1OTQtdGRrZXVnMmIsMjAxNS0wMS0xMFQwOToyODoyNi4wMDAwMDArMDAwMCwyMDE1LTAxLTEwVDA5OjU4OjUwLjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDg0LDMyLjEsMjAxNS0wMS0xMCxvcmdhbmljLENoaW5hCjUwNSxWTFFIWUpDS0JPSU43MjksVkxRSFlKQ0tCT0lONzI5LTkxdDVka2ZtLDIwMTUtMDEtMTBUMDk6NTM6MDIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMFQwOTo1NjoyNi4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjA4NCwyMy4yLDIwMTUtMDEtMTAsb3JnYW5pYyxKYXBhbgo1MDgsS0JFUVpHRlNSUEhKNDc5LEtCRVFaR0ZTUlBISjQ3OS0xMmdvM3R6NywyMDE1LTAxLTEwVDEwOjMwOjA0LjAwMDAwMCswMDAwLDIwMTUtMDEtMTBUMTA6NDQ6NTIuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAzLDM3LjgsMjAxNS0wMS0wNyxvcmdhbmljLFJ1c3NpYQo1MTYsR0ZMWUpIQVBNWldENjMxLEdGTFlKSEFQTVpXRDYzMS12cHdmajNjYSwyMDE1LTAxLTEwVDEyOjM0OjQ1LjAwMDAwMCswMDAwLDIwMTUtMDEtMTBUMTI6NDg6MzkuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4wMjYsMjEuNCwyMDE1LTAxLTA5LG9yZ2FuaWMsSW5kaWEKNTE3LEdGTFlKSEFQTVpXRDYzMSxHRkxZSkhBUE1aV0Q2MzEtdnB3ZmozY2EsMjAxNS0wMS0xMFQxMjozNDo0NS4wMDAwMDArMDAwMCwyMDE1LTAxLTEwVDEyOjQ5OjUxLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMDQsMjEuNCwyMDE1LTAxLTA5LG9yZ2FuaWMsSW5kaWEKNTE4LEdGTFlKSEFQTVpXRDYzMSxHRkxZSkhBUE1aV0Q2MzEtdnB3ZmozY2EsMjAxNS0wMS0xMFQxMjozNDo0NS4wMDAwMDArMDAwMCwyMDE1LTAxLTEwVDEyOjU1OjUxLjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDE2LDIxLjQsMjAxNS0wMS0wOSxvcmdhbmljLEluZGlhCjUxOSxQWkJOUktTTVVMSFgyMTMsUFpCTlJLU01VTEhYMjEzLXZ0bHkzNWZjLDIwMTUtMDEtMTBUMTQ6MDY6MzYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMFQxNDowOToxOC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDA2LDI2LjMsMjAxNS0wMS0wNyxvcmdhbmljLEluZGlhCjUyMCxQWkJOUktTTVVMSFgyMTMsUFpCTlJLU01VTEhYMjEzLXZ0bHkzNWZjLDIwMTUtMDEtMTBUMTQ6MDY6MzYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMFQxNDoxNDoxOC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDE2LDI2LjMsMjAxNS0wMS0wNyxvcmdhbmljLEluZGlhCjUyMyxQWkJOUktTTVVMSFgyMTMsUFpCTlJLU01VTEhYMjEzLXZ0bHkzNWZjLDIwMTUtMDEtMTBUMTQ6MDY6MzYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMFQxNDoyNTowMC4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjA0NCwyNi4zLDIwMTUtMDEtMDcsb3JnYW5pYyxJbmRpYQo1MjQsUFpCTlJLU01VTEhYMjEzLFBaQk5SS1NNVUxIWDIxMy12dGx5MzVmYywyMDE1LTAxLTEwVDE0OjA2OjM2LjAwMDAwMCswMDAwLDIwMTUtMDEtMTBUMTQ6MzE6NTQuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAwNiwyNi4zLDIwMTUtMDEtMDcsb3JnYW5pYyxJbmRpYQo1MjYsRVFVRE5HWklDTUFLNDgyLEVRVUROR1pJQ01BSzQ4Mi1pNWtyZzluZiwyMDE1LTAxLTEwVDE0OjEyOjA5LjAwMDAwMCswMDAwLDIwMTUtMDEtMTBUMTQ6MjA6MDkuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAzLDEwLjYsMjAxNS0wMS0wNCxnb29nbGUsR2VybWFueQo1MjcsSllFQkNMTlVaVFhRNDU3LEpZRUJDTE5VWlRYUTQ1Ny1mZ3Btcnd4biwyMDE1LTAxLTEwVDE1OjA1OjIwLjAwMDAwMCswMDAwLDIwMTUtMDEtMTBUMTU6MTI6MzIuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyLDI1LjMsMjAxNS0wMS0wNCxvdGhlcl9jYW1wYWlnbixFZ3lwdAo1MjgsSllFQkNMTlVaVFhRNDU3LEpZRUJDTE5VWlRYUTQ1Ny1mZ3Btcnd4biwyMDE1LTAxLTEwVDE1OjA1OjIwLjAwMDAwMCswMDAwLDIwMTUtMDEtMTBUMTU6MjE6NDQuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAzNSwyNS4zLDIwMTUtMDEtMDQsb3RoZXJfY2FtcGFpZ24sRWd5cHQKNTI5LEpZRUJDTE5VWlRYUTQ1NyxKWUVCQ0xOVVpUWFE0NTctZmdwbXJ3eG4sMjAxNS0wMS0xMFQxNTowNToyMC4wMDAwMDArMDAwMCwyMDE1LTAxLTEwVDE1OjI0OjIwLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMiwyNS4zLDIwMTUtMDEtMDQsb3RoZXJfY2FtcGFpZ24sRWd5cHQKNTM1LE9NQ1ZVQUlLU0RUUjY1MSxPTUNWVUFJS1NEVFI2NTEtYzlubTJidGwsMjAxNS0wMS0xMFQxNToyOTowMi4wMDAwMDArMDAwMCwyMDE1LTAxLTEwVDE1OjU4OjIwLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4xLDM0LjEsMjAxNS0wMS0wNyxvdGhlcl9jYW1wYWlnbixVbml0ZWQgU3RhdGVzCjUzNixPTUNWVUFJS1NEVFI2NTEsT01DVlVBSUtTRFRSNjUxLWM5bm0yYnRsLDIwMTUtMDEtMTBUMTU6Mjk6MDIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMFQxNjowMjoyNi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDQsMzQuMSwyMDE1LTAxLTA3LG90aGVyX2NhbXBhaWduLFVuaXRlZCBTdGF0ZXMKNTQyLFFKR1ZPQkxBVElIVzQ1NyxRSkdWT0JMQVRJSFc0NTctbjN4bGFic3osMjAxNS0wMS0xMFQxNTo0OTo1NC4wMDAwMDArMDAwMCwyMDE1LTAxLTEwVDE1OjU1OjM2LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wOTksMjQuOSwyMDE1LTAxLTAyLG90aGVyX2NhbXBhaWduLFN3ZWRlbgo1NDMsUUpHVk9CTEFUSUhXNDU3LFFKR1ZPQkxBVElIVzQ1Ny1uM3hsYWJzeiwyMDE1LTAxLTEwVDE1OjQ5OjU0LjAwMDAwMCswMDAwLDIwMTUtMDEtMTBUMTY6MDU6MjQuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA0NCwyNC45LDIwMTUtMDEtMDIsb3RoZXJfY2FtcGFpZ24sU3dlZGVuCjU0NCxRSkdWT0JMQVRJSFc0NTcsUUpHVk9CTEFUSUhXNDU3LW4zeGxhYnN6LDIwMTUtMDEtMTBUMTU6NDk6NTQuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMFQxNjowOTo0OC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDMzLDI0LjksMjAxNS0wMS0wMixvdGhlcl9jYW1wYWlnbixTd2VkZW4KNTQ1LFFKR1ZPQkxBVElIVzQ1NyxRSkdWT0JMQVRJSFc0NTctbjN4bGFic3osMjAxNS0wMS0xMFQxNTo0OTo1NC4wMDAwMDArMDAwMCwyMDE1LTAxLTEwVDE2OjEzOjEyLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNDQsMjQuOSwyMDE1LTAxLTAyLG90aGVyX2NhbXBhaWduLFN3ZWRlbgo1NDgsWlBUSUhOU1ZGWUFRMTQ2LFpQVElITlNWRllBUTE0Ni1vNDg1enJlYSwyMDE1LTAxLTEwVDE2OjA4OjM0LjAwMDAwMCswMDAwLDIwMTUtMDEtMTBUMTY6MTk6NDYuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA1NCwxNy41LDIwMTUtMDEtMDQsZmFjZWJvb2ssTWV4aWNvCjU1NCxKVkJaQ1BLWEhGTVU0OTEsSlZCWkNQS1hIRk1VNDkxLW45d3MydGwxLDIwMTUtMDEtMTBUMTg6NDg6MDYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMFQxOTowNToxOC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDUsMzQuMSwyMDE1LTAxLTA3LG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwo1NTUsSUNCQVVaS0dTUVBGMTQ1LElDQkFVWktHU1FQRjE0NS1lZ3h0aThkcCwyMDE1LTAxLTEwVDE4OjQ5OjM3LjAwMDAwMCswMDAwLDIwMTUtMDEtMTBUMTg6NTM6NTUuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA0OSwzNy4wLDIwMTUtMDEtMDYsZ29vZ2xlLFNvdXRoIEFmcmljYQo1NTYsSUNCQVVaS0dTUVBGMTQ1LElDQkFVWktHU1FQRjE0NS1lZ3h0aThkcCwyMDE1LTAxLTEwVDE4OjQ5OjM3LjAwMDAwMCswMDAwLDIwMTUtMDEtMTBUMTk6MTI6NTUuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA4NDksMzcuMCwyMDE1LTAxLTA2LGdvb2dsZSxTb3V0aCBBZnJpY2EKNTU4LElDQkFVWktHU1FQRjE0NSxJQ0JBVVpLR1NRUEYxNDUtZWd4dGk4ZHAsMjAxNS0wMS0xMFQxODo0OTozNy4wMDAwMDArMDAwMCwyMDE1LTAxLTEwVDE5OjIwOjI1LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNzksMzcuMCwyMDE1LTAxLTA2LGdvb2dsZSxTb3V0aCBBZnJpY2EKNTYwLFFOTFZSREVPWEZZSjg5MixRTkxWUkRFT1hGWUo4OTItNnVjN3RoMjUsMjAxNS0wMS0xMFQxOTo0MjoyOC4wMDAwMDArMDAwMCwyMDE1LTAxLTEwVDE5OjU1OjI4LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMiwyNS4xLDIwMTUtMDEtMDksY3Jvc3Nwcm9tbyxBdXN0cmFsaWEKNTY0LFFOTFZSREVPWEZZSjg5MixRTkxWUkRFT1hGWUo4OTItNnVjN3RoMjUsMjAxNS0wMS0xMFQxOTo0MjoyOC4wMDAwMDArMDAwMCwyMDE1LTAxLTEwVDIwOjA0OjU4LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wOSwyNS4xLDIwMTUtMDEtMDksY3Jvc3Nwcm9tbyxBdXN0cmFsaWEKNTY1LFBaQk5SS1NNVUxIWDIxMyxQWkJOUktTTVVMSFgyMTMteTcyMWZ1dGEsMjAxNS0wMS0xMFQxOTo1NDoxMS4wMDAwMDArMDAwMCwyMDE1LTAxLTEwVDIwOjEyOjI5LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMDQsMzkuOCwyMDE1LTAxLTA3LG9yZ2FuaWMsSW5kaWEKNTY2LFBaQk5SS1NNVUxIWDIxMyxQWkJOUktTTVVMSFgyMTMteTcyMWZ1dGEsMjAxNS0wMS0xMFQxOTo1NDoxMS4wMDAwMDArMDAwMCwyMDE1LTAxLTEwVDIwOjI3OjI5LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMiwzOS44LDIwMTUtMDEtMDcsb3JnYW5pYyxJbmRpYQo1NzEsQkZOTFVSSVNKWFRINjQ3LEJGTkxVUklTSlhUSDY0Ny0zYmNtdGVwZywyMDE1LTAxLTEwVDIxOjAwOjMxLjAwMDAwMCswMDAwLDIwMTUtMDEtMTBUMjE6MTE6MDcuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyLDM0LjAsMjAxNS0wMS0xMCxvcmdhbmljLEluZGlhCjU3MixCRk5MVVJJU0pYVEg2NDcsQkZOTFVSSVNKWFRINjQ3LTNiY210ZXBnLDIwMTUtMDEtMTBUMjE6MDA6MzEuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMFQyMToxNjo0My4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDA0LDM0LjAsMjAxNS0wMS0xMCxvcmdhbmljLEluZGlhCjU3MyxCRk5MVVJJU0pYVEg2NDcsQkZOTFVSSVNKWFRINjQ3LTNiY210ZXBnLDIwMTUtMDEtMTBUMjE6MDA6MzEuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMFQyMToxODo0My4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDA0LDM0LjAsMjAxNS0wMS0xMCxvcmdhbmljLEluZGlhCjU3NCxCRk5MVVJJU0pYVEg2NDcsQkZOTFVSSVNKWFRINjQ3LTNiY210ZXBnLDIwMTUtMDEtMTBUMjE6MDA6MzEuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMFQyMToyMTo0OS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDE0LDM0LjAsMjAxNS0wMS0xMCxvcmdhbmljLEluZGlhCjU4MCxSTU9TV0hKR0VMQ0k2NzUsUk1PU1dISkdFTENJNjc1LWQ3c2JndTlhLDIwMTUtMDEtMTBUMjM6MjQ6MjAuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMFQyMzozODowMi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDIsMjQuMCwyMDE1LTAxLTEwLG90aGVyX2NhbXBhaWduLEZyYW5jZQo1ODIsTkFPSlJETUNTRUJJMjgxLE5BT0pSRE1DU0VCSTI4MS1kemU3a3NwdSwyMDE1LTAxLTExVDAwOjI0OjM1LjAwMDAwMCswMDAwLDIwMTUtMDEtMTFUMDA6MzA6MjkuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA4MSwzMC45LDIwMTUtMDEtMTEsb3JnYW5pYyxOb3J3YXkKNTg0LE5BT0pSRE1DU0VCSTI4MSxOQU9KUkRNQ1NFQkkyODEtZHplN2tzcHUsMjAxNS0wMS0xMVQwMDoyNDozNS4wMDAwMDArMDAwMCwyMDE1LTAxLTExVDAwOjQ2OjU5LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNDUsMzAuOSwyMDE1LTAxLTExLG9yZ2FuaWMsTm9yd2F5CjU5NSxHU1FKWElPS1lNRUE3MTIsR1NRSlhJT0tZTUVBNzEyLWk1N3Y0ZmJ4LDIwMTUtMDEtMTFUMDM6MDg6NDYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMVQwMzoxNzoyMi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDgsMTAuOCwyMDE1LTAxLTA3LGdvb2dsZSxHZXJtYW55CjYwMSxHU1FKWElPS1lNRUE3MTIsR1NRSlhJT0tZTUVBNzEyLWx5a2FzeG83LDIwMTUtMDEtMTFUMDU6MTY6NDYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMVQwNToxNzozNC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDUsMjAuMSwyMDE1LTAxLTA3LGdvb2dsZSxHZXJtYW55CjYwNyxDSEtVUkFCVEZaREUzNzIsQ0hLVVJBQlRGWkRFMzcyLXo5eWJoam9xLDIwMTUtMDEtMTFUMDU6NDc6NDMuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMVQwNjowNTo0OS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDg4LDI1LjAsMjAxNS0wMS0xMSxvcmdhbmljLERlbm1hcmsKNjA4LENIS1VSQUJURlpERTM3MixDSEtVUkFCVEZaREUzNzItejl5Ymhqb3EsMjAxNS0wMS0xMVQwNTo0Nzo0My4wMDAwMDArMDAwMCwyMDE1LTAxLTExVDA2OjA4OjMxLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wODgsMjUuMCwyMDE1LTAxLTExLG9yZ2FuaWMsRGVubWFyawo2MTEsUk1PU1dISkdFTENJNjc1LFJNT1NXSEpHRUxDSTY3NS04dWx3ZGt2dCwyMDE1LTAxLTExVDA2OjE1OjM2LjAwMDAwMCswMDAwLDIwMTUtMDEtMTFUMDY6MTU6NTQuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyLDkuNCwyMDE1LTAxLTEwLG90aGVyX2NhbXBhaWduLEZyYW5jZQo2MTcsSUNCQVVaS0dTUVBGMTQ1LElDQkFVWktHU1FQRjE0NS1iaDFhbmx5NSwyMDE1LTAxLTExVDA2OjQ1OjI0LjAwMDAwMCswMDAwLDIwMTUtMDEtMTFUMDc6MDU6MjQuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA0MSwyOS4zLDIwMTUtMDEtMDYsZ29vZ2xlLFNvdXRoIEFmcmljYQo2MTgsSlZCWkNQS1hIRk1VNDkxLEpWQlpDUEtYSEZNVTQ5MS0xdGFlZzZpeSwyMDE1LTAxLTExVDA3OjA5OjM0LjAwMDAwMCswMDAwLDIwMTUtMDEtMTFUMDc6MTQ6MjIuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyLDcuOSwyMDE1LTAxLTA3LG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwo2MjMsS0daQ09KSFBGVFFWNzUzLEtHWkNPSkhQRlRRVjc1My1mZTRiZDN4bSwyMDE1LTAxLTExVDA3OjQ0OjI3LjAwMDAwMCswMDAwLDIwMTUtMDEtMTFUMDc6NDU6MjcuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjEsMjIuNiwyMDE1LTAxLTExLG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwo2MjUsT01DVlVBSUtTRFRSNjUxLE9NQ1ZVQUlLU0RUUjY1MS15eDVqbzR2NywyMDE1LTAxLTExVDA5OjA0OjUyLjAwMDAwMCswMDAwLDIwMTUtMDEtMTFUMDk6MDc6NDAuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA2LDM4LjUsMjAxNS0wMS0wNyxvdGhlcl9jYW1wYWlnbixVbml0ZWQgU3RhdGVzCjYyOSxPTUNWVUFJS1NEVFI2NTEsT01DVlVBSUtTRFRSNjUxLXl4NWpvNHY3LDIwMTUtMDEtMTFUMDk6MDQ6NTIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMVQwOTozMjo0Ni4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDksMzguNSwyMDE1LTAxLTA3LG90aGVyX2NhbXBhaWduLFVuaXRlZCBTdGF0ZXMKNjM0LEFVV0ZEUlpNWFZKSDkyOCxBVVdGRFJaTVhWSkg5MjgtNG42Z3h2ZW8sMjAxNS0wMS0xMVQxMDoxNzoyMi4wMDAwMDArMDAwMCwyMDE1LTAxLTExVDEwOjE4OjU4LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMiwxMy42LDIwMTUtMDEtMTEsZ29vZ2xlLEluZGlhCjYzNixRTkxWUkRFT1hGWUo4OTIsUU5MVlJERU9YRllKODkyLTQ1Y3Z0YXgzLDIwMTUtMDEtMTFUMTA6NTI6MDYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMVQxMDo1OTo1NC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMSwyMS4yLDIwMTUtMDEtMDksY3Jvc3Nwcm9tbyxBdXN0cmFsaWEKNjM4LFFOTFZSREVPWEZZSjg5MixRTkxWUkRFT1hGWUo4OTItNDVjdnRheDMsMjAxNS0wMS0xMVQxMDo1MjowNi4wMDAwMDArMDAwMCwyMDE1LTAxLTExVDExOjA5OjQyLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNywyMS4yLDIwMTUtMDEtMDksY3Jvc3Nwcm9tbyxBdXN0cmFsaWEKNjM5LEJGTkxVUklTSlhUSDY0NyxCRk5MVVJJU0pYVEg2NDctZnVjcTFlbTgsMjAxNS0wMS0xMVQxMTowMjowOS4wMDAwMDArMDAwMCwyMDE1LTAxLTExVDExOjE0OjM5LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMiw0MC43LDIwMTUtMDEtMTAsb3JnYW5pYyxJbmRpYQo2NDAsQkZOTFVSSVNKWFRINjQ3LEJGTkxVUklTSlhUSDY0Ny1mdWNxMWVtOCwyMDE1LTAxLTExVDExOjAyOjA5LjAwMDAwMCswMDAwLDIwMTUtMDEtMTFUMTE6MTg6MDkuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4wNDYsNDAuNywyMDE1LTAxLTEwLG9yZ2FuaWMsSW5kaWEKNjQyLEJGTkxVUklTSlhUSDY0NyxCRk5MVVJJU0pYVEg2NDctZnVjcTFlbTgsMjAxNS0wMS0xMVQxMTowMjowOS4wMDAwMDArMDAwMCwyMDE1LTAxLTExVDExOjM0OjUxLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMDgsNDAuNywyMDE1LTAxLTEwLG9yZ2FuaWMsSW5kaWEKNjQzLFFOTFZSREVPWEZZSjg5MixRTkxWUkRFT1hGWUo4OTItaTJrZ3hqNW0sMjAxNS0wMS0xMVQxMjoxMzo0My4wMDAwMDArMDAwMCwyMDE1LTAxLTExVDEyOjI3OjEzLjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDgsMzguOCwyMDE1LTAxLTA5LGNyb3NzcHJvbW8sQXVzdHJhbGlhCjY0NixNWENPVkVZSUFLRkg1OTQsTVhDT1ZFWUlBS0ZINTk0LW16ODV2bmM2LDIwMTUtMDEtMTFUMTQ6MTA6NDMuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMVQxNDoxNTo0My4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDU0LDI2LjgsMjAxNS0wMS0xMCxvcmdhbmljLENoaW5hCjY0OCxNWENPVkVZSUFLRkg1OTQsTVhDT1ZFWUlBS0ZINTk0LW16ODV2bmM2LDIwMTUtMDEtMTFUMTQ6MTA6NDMuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMVQxNDozMjozMS4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjA2LDI2LjgsMjAxNS0wMS0xMCxvcmdhbmljLENoaW5hCjY1NCxRSkdWT0JMQVRJSFc0NTcsUUpHVk9CTEFUSUhXNDU3LTUzbGtmYTZ2LDIwMTUtMDEtMTFUMTQ6MzU6MjIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMVQxNDozNzoxMC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDMzLDIxLjksMjAxNS0wMS0wMixvdGhlcl9jYW1wYWlnbixTd2VkZW4KNjc1LEdGTFlKSEFQTVpXRDYzMSxHRkxZSkhBUE1aV0Q2MzEta3E3dGptb2UsMjAxNS0wMS0xMVQxODoyMzoyMi4wMDAwMDArMDAwMCwyMDE1LTAxLTExVDE4OjI2OjQ2LjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDI2LDEyLjIsMjAxNS0wMS0wOSxvcmdhbmljLEluZGlhCjY3NyxJQ0JBVVpLR1NRUEYxNDUsSUNCQVVaS0dTUVBGMTQ1LXp1bzJqOTU0LDIwMTUtMDEtMTFUMTk6MDQ6MzYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMVQxOToxMjoyNC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDQ5LDguMSwyMDE1LTAxLTA2LGdvb2dsZSxTb3V0aCBBZnJpY2EKNjgwLEZYV0ROS0lVTUpZUjQ3MSxGWFdETktJVU1KWVI0NzEtZXBtY3hoMzUsMjAxNS0wMS0xMVQyMDowMzoyNS4wMDAwMDArMDAwMCwyMDE1LTAxLTExVDIwOjA3OjAxLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wOSwxOS40LDIwMTUtMDEtMTAsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjY4NixSTU9TV0hKR0VMQ0k2NzUsUk1PU1dISkdFTENJNjc1LXVxZzRvN2V2LDIwMTUtMDEtMTFUMjE6Mzc6MjcuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMVQyMTozOToyMS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDksOC4yLDIwMTUtMDEtMTAsb3RoZXJfY2FtcGFpZ24sRnJhbmNlCjY4OSxQWkJOUktTTVVMSFgyMTMsUFpCTlJLU01VTEhYMjEzLW44ZWw2cHV3LDIwMTUtMDEtMTFUMjI6MDg6MjQuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMVQyMjoyNDozMC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDA0LDI4LjYsMjAxNS0wMS0wNyxvcmdhbmljLEluZGlhCjY5MCxQWkJOUktTTVVMSFgyMTMsUFpCTlJLU01VTEhYMjEzLW44ZWw2cHV3LDIwMTUtMDEtMTFUMjI6MDg6MjQuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMVQyMjoyODowMC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDE2LDI4LjYsMjAxNS0wMS0wNyxvcmdhbmljLEluZGlhCjY5MSxQWkJOUktTTVVMSFgyMTMsUFpCTlJLU01VTEhYMjEzLW44ZWw2cHV3LDIwMTUtMDEtMTFUMjI6MDg6MjQuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMVQyMjozMjo1NC4wMDAwMDArMDAwMCxhZCxhZF8xNXNlYywwLjA0NiwyOC42LDIwMTUtMDEtMDcsb3JnYW5pYyxJbmRpYQo2OTIsUFpCTlJLU01VTEhYMjEzLFBaQk5SS1NNVUxIWDIxMy1uOGVsNnB1dywyMDE1LTAxLTExVDIyOjA4OjI0LjAwMDAwMCswMDAwLDIwMTUtMDEtMTFUMjI6MzU6NTQuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyNCwyOC42LDIwMTUtMDEtMDcsb3JnYW5pYyxJbmRpYQo2OTQsS0lMV1pZSFJTSkVHMzE2LEtJTFdaWUhSU0pFRzMxNi1oOXQ3ZjV2MiwyMDE1LTAxLTExVDIyOjIwOjQ2LjAwMDAwMCswMDAwLDIwMTUtMDEtMTFUMjI6MzQ6NDAuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA5OSwyOS4yLDIwMTUtMDEtMDQsb3JnYW5pYyxEZW5tYXJrCjY5NyxFUVVETkdaSUNNQUs0ODIsRVFVRE5HWklDTUFLNDgyLWh4ajF3NjRiLDIwMTUtMDEtMTFUMjI6NTg6MTcuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMVQyMzoxMjoyMy4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjA3LDE5LjQsMjAxNS0wMS0wNCxnb29nbGUsR2VybWFueQo2OTgsR0ZMWUpIQVBNWldENjMxLEdGTFlKSEFQTVpXRDYzMS1wZDZqczE1bSwyMDE1LTAxLTExVDIzOjI4OjA5LjAwMDAwMCswMDAwLDIwMTUtMDEtMTFUMjM6MzE6NTEuMDAwMDAwKzAwMDAsYWQsYWRfMTVzZWMsMC4wNDIsOS4wLDIwMTUtMDEtMDksb3JnYW5pYyxJbmRpYQo3MDEsR1NRSlhJT0tZTUVBNzEyLEdTUUpYSU9LWU1FQTcxMi0ycXhudHN3YywyMDE1LTAxLTEyVDAwOjI1OjEzLjAwMDAwMCswMDAwLDIwMTUtMDEtMTJUMDA6NDY6NTUuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA1LDMzLjMsMjAxNS0wMS0wNyxnb29nbGUsR2VybWFueQo3MDksSlZCWkNQS1hIRk1VNDkxLEpWQlpDUEtYSEZNVTQ5MS10ZnI5bTJsdiwyMDE1LTAxLTEyVDAzOjI5OjMxLjAwMDAwMCswMDAwLDIwMTUtMDEtMTJUMDM6Mzk6MDcuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA0LDI0LjQsMjAxNS0wMS0wNyxvcmdhbmljLFVuaXRlZCBTdGF0ZXMKNzEwLEpWQlpDUEtYSEZNVTQ5MSxKVkJaQ1BLWEhGTVU0OTEtdGZyOW0ybHYsMjAxNS0wMS0xMlQwMzoyOTozMS4wMDAwMDArMDAwMCwyMDE1LTAxLTEyVDAzOjQxOjA3LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNSwyNC40LDIwMTUtMDEtMDcsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjcxMSxBVVdGRFJaTVhWSkg5MjgsQVVXRkRSWk1YVkpIOTI4LW14cmI4bGQzLDIwMTUtMDEtMTJUMDQ6MzA6MTIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMlQwNDozMTo0OC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDEyLDE5LjQsMjAxNS0wMS0xMSxnb29nbGUsSW5kaWEKNzEzLEFVV0ZEUlpNWFZKSDkyOCxBVVdGRFJaTVhWSkg5MjgtbXhyYjhsZDMsMjAxNS0wMS0xMlQwNDozMDoxMi4wMDAwMDArMDAwMCwyMDE1LTAxLTEyVDA0OjQ0OjAwLjAwMDAwMCswMDAwLGFkLGFkXzE1c2VjLDAuMDY0LDE5LjQsMjAxNS0wMS0xMSxnb29nbGUsSW5kaWEKNzE2LElDQkFVWktHU1FQRjE0NSxJQ0JBVVpLR1NRUEYxNDUtOHlzZ2p2bTYsMjAxNS0wMS0xMlQwNToyMDowMS4wMDAwMDArMDAwMCwyMDE1LTAxLTEyVDA1OjMzOjU1LjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDgsMTcuNCwyMDE1LTAxLTA2LGdvb2dsZSxTb3V0aCBBZnJpY2EKNzE5LE1YQ09WRVlJQUtGSDU5NCxNWENPVkVZSUFLRkg1OTQtb25jbDN1cDEsMjAxNS0wMS0xMlQwNTo0MjozNy4wMDAwMDArMDAwMCwyMDE1LTAxLTEyVDA1OjQyOjQzLjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDksMjMuNSwyMDE1LTAxLTEwLG9yZ2FuaWMsQ2hpbmEKNzI1LE9NQ1ZVQUlLU0RUUjY1MSxPTUNWVUFJS1NEVFI2NTEtcnR1MXdwbWUsMjAxNS0wMS0xMlQwNjowMzo0Mi4wMDAwMDArMDAwMCwyMDE1LTAxLTEyVDA2OjMwOjAwLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNywyOS41LDIwMTUtMDEtMDcsb3RoZXJfY2FtcGFpZ24sVW5pdGVkIFN0YXRlcwo3MjcsSUNCQVVaS0dTUVBGMTQ1LElDQkFVWktHU1FQRjE0NS1rdnVoM2N6cywyMDE1LTAxLTEyVDA4OjA0OjM2LjAwMDAwMCswMDAwLDIwMTUtMDEtMTJUMDg6MTI6MTguMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA4NDksMTMuOSwyMDE1LTAxLTA2LGdvb2dsZSxTb3V0aCBBZnJpY2EKNzI5LE1YQ09WRVlJQUtGSDU5NCxNWENPVkVZSUFLRkg1OTQtcHphNmllY24sMjAxNS0wMS0xMlQwODoxNjowMi4wMDAwMDArMDAwMCwyMDE1LTAxLTEyVDA4OjE2OjA4LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMzYsMzYuNiwyMDE1LTAxLTEwLG9yZ2FuaWMsQ2hpbmEKNzMwLE1YQ09WRVlJQUtGSDU5NCxNWENPVkVZSUFLRkg1OTQtcHphNmllY24sMjAxNS0wMS0xMlQwODoxNjowMi4wMDAwMDArMDAwMCwyMDE1LTAxLTEyVDA4OjM2OjMyLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNjYsMzYuNiwyMDE1LTAxLTEwLG9yZ2FuaWMsQ2hpbmEKNzMyLE1YQ09WRVlJQUtGSDU5NCxNWENPVkVZSUFLRkg1OTQtcHphNmllY24sMjAxNS0wMS0xMlQwODoxNjowMi4wMDAwMDArMDAwMCwyMDE1LTAxLTEyVDA4OjQyOjA4LjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDU0LDM2LjYsMjAxNS0wMS0xMCxvcmdhbmljLENoaW5hCjczMyxKVkJaQ1BLWEhGTVU0OTEsSlZCWkNQS1hIRk1VNDkxLWV3Mml0NnBsLDIwMTUtMDEtMTJUMDg6MTg6NTkuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMlQwODoyMToxMS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDgsMzAuMSwyMDE1LTAxLTA3LG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwo3MzUsSlZCWkNQS1hIRk1VNDkxLEpWQlpDUEtYSEZNVTQ5MS1ldzJpdDZwbCwyMDE1LTAxLTEyVDA4OjE4OjU5LjAwMDAwMCswMDAwLDIwMTUtMDEtMTJUMDg6MzM6MTcuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA2LDMwLjEsMjAxNS0wMS0wNyxvcmdhbmljLFVuaXRlZCBTdGF0ZXMKNzM3LFBMUUVTQk5HVURLSjE1NCxQTFFFU0JOR1VES0oxNTQtcDUzMml2eTEsMjAxNS0wMS0xMlQwODo0ODowNi4wMDAwMDArMDAwMCwyMDE1LTAxLTEyVDA4OjUzOjA2LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMTIsMzYuMCwyMDE1LTAxLTEyLGZhY2Vib29rLEphcGFuCjczOCxQTFFFU0JOR1VES0oxNTQsUExRRVNCTkdVREtKMTU0LXA1MzJpdnkxLDIwMTUtMDEtMTJUMDg6NDg6MDYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMlQwODo1OTo0OC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDU0LDM2LjAsMjAxNS0wMS0xMixmYWNlYm9vayxKYXBhbgo3MzksUExRRVNCTkdVREtKMTU0LFBMUUVTQk5HVURLSjE1NC1wNTMyaXZ5MSwyMDE1LTAxLTEyVDA4OjQ4OjA2LjAwMDAwMCswMDAwLDIwMTUtMDEtMTJUMDk6MTc6MDAuMDAwMDAwKzAwMDAsYWQsYWRfMTVzZWMsMC4wOTYsMzYuMCwyMDE1LTAxLTEyLGZhY2Vib29rLEphcGFuCjc0MCxQTFFFU0JOR1VES0oxNTQsUExRRVNCTkdVREtKMTU0LXA1MzJpdnkxLDIwMTUtMDEtMTJUMDg6NDg6MDYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMlQwOToxNzoyNC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDMsMzYuMCwyMDE1LTAxLTEyLGZhY2Vib29rLEphcGFuCjc0MixWTFFIWUpDS0JPSU43MjksVkxRSFlKQ0tCT0lONzI5LTV6cnZveG55LDIwMTUtMDEtMTJUMDg6NDk6NDUuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMlQwODo1NDozOS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDM2LDExLjEsMjAxNS0wMS0xMCxvcmdhbmljLEphcGFuCjc0MyxDSEtVUkFCVEZaREUzNzIsQ0hLVVJBQlRGWkRFMzcyLWV1c25oY3Z3LDIwMTUtMDEtMTJUMTA6MDU6MDUuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMlQxMDoxNDoxNy4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDk5LDM2LjksMjAxNS0wMS0xMSxvcmdhbmljLERlbm1hcmsKNzUxLFFEVVpKSUVUQ0FHVzY1NCxRRFVaSklFVENBR1c2NTQteHZxNTR3bzcsMjAxNS0wMS0xMlQxMDo0Njo0NS4wMDAwMDArMDAwMCwyMDE1LTAxLTEyVDEwOjQ3OjAzLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNzIsMTguNSwyMDE1LTAxLTA3LGZhY2Vib29rLFN3aXR6ZXJsYW5kCjc1OCxHU1FKWElPS1lNRUE3MTIsR1NRSlhJT0tZTUVBNzEyLTlpMnJrNmFjLDIwMTUtMDEtMTJUMTM6Mzk6MDAuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMlQxMzo0NTozMC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDUsMTUuMSwyMDE1LTAxLTA3LGdvb2dsZSxHZXJtYW55Cjc1OSxOQU9KUkRNQ1NFQkkyODEsTkFPSlJETUNTRUJJMjgxLTR4aXA4Z3ZuLDIwMTUtMDEtMTJUMTQ6NTU6MTMuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMlQxNTowMTowMS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDI3LDE4LjgsMjAxNS0wMS0xMSxvcmdhbmljLE5vcndheQo3NjgsQVVXRkRSWk1YVkpIOTI4LEFVV0ZEUlpNWFZKSDkyOC13OWZoazNweiwyMDE1LTAxLTEyVDE3OjI3OjQ1LjAwMDAwMCswMDAwLDIwMTUtMDEtMTJUMTc6MzA6MTUuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAwOCwxMS41LDIwMTUtMDEtMTEsZ29vZ2xlLEluZGlhCjc2OSxBVVdGRFJaTVhWSkg5MjgsQVVXRkRSWk1YVkpIOTI4LXc5ZmhrM3B6LDIwMTUtMDEtMTJUMTc6Mjc6NDUuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMlQxNzozMzozOS4wMDAwMDArMDAwMCxhZCxhZF8xNXNlYywwLjA3OCwxMS41LDIwMTUtMDEtMTEsZ29vZ2xlLEluZGlhCjc3NixDSEtVUkFCVEZaREUzNzIsQ0hLVVJBQlRGWkRFMzcyLXF2dXc0OWc2LDIwMTUtMDEtMTJUMTg6MTk6NDkuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMlQxODoyODo0OS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDk5LDE0LjgsMjAxNS0wMS0xMSxvcmdhbmljLERlbm1hcmsKNzgwLE5BT0pSRE1DU0VCSTI4MSxOQU9KUkRNQ1NFQkkyODEtMm03dXcxODksMjAxNS0wMS0xMlQxOTo1MTo0OS4wMDAwMDArMDAwMCwyMDE1LTAxLTEyVDIwOjI2OjA3LjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDk5LDM4LjksMjAxNS0wMS0xMSxvcmdhbmljLE5vcndheQo3ODksVVpRRkhEQkVNWVBWNTk0LFVaUUZIREJFTVlQVjU5NC1rZnNyZWw2ZCwyMDE1LTAxLTEyVDIyOjM4OjE3LjAwMDAwMCswMDAwLDIwMTUtMDEtMTJUMjI6NTY6NDcuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA4NCwyNS41LDIwMTUtMDEtMTAsZ29vZ2xlLFN3aXR6ZXJsYW5kCjc5MyxHQVlJQkxVQ09FREo3MzIsR0FZSUJMVUNPRURKNzMyLW1kOWVweTc4LDIwMTUtMDEtMTJUMjI6NDQ6MDQuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMlQyMzoxMzo1Mi4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjA4LDMxLjEsMjAxNS0wMS0wMyxvcmdhbmljLFVuaXRlZCBTdGF0ZXMKODAxLEZYV0ROS0lVTUpZUjQ3MSxGWFdETktJVU1KWVI0NzEtaWhreWRqbTYsMjAxNS0wMS0xMlQyMzoyOToxMS4wMDAwMDArMDAwMCwyMDE1LTAxLTEzVDAwOjAxOjE3LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMywzNS43LDIwMTUtMDEtMTAsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjgwNyxWTFFIWUpDS0JPSU43MjksVkxRSFlKQ0tCT0lONzI5LXRlMmE3NGxpLDIwMTUtMDEtMTNUMDA6MTc6MDAuMDAwMDAwKzAwMDAsMjAxNS0wMS0xM1QwMDozNjo0OC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDE4LDI1LjQsMjAxNS0wMS0xMCxvcmdhbmljLEphcGFuCjgwOSxKVkJaQ1BLWEhGTVU0OTEsSlZCWkNQS1hIRk1VNDkxLWV3Znp4YWI1LDIwMTUtMDEtMTNUMDA6NDQ6MDEuMDAwMDAwKzAwMDAsMjAxNS0wMS0xM1QwMDo0Nzo1NS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDgsMjUuMiwyMDE1LTAxLTA3LG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwo4MTAsSlZCWkNQS1hIRk1VNDkxLEpWQlpDUEtYSEZNVTQ5MS1ld2Z6eGFiNSwyMDE1LTAxLTEzVDAwOjQ0OjAxLjAwMDAwMCswMDAwLDIwMTUtMDEtMTNUMDA6NTE6MzEuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA1LDI1LjIsMjAxNS0wMS0wNyxvcmdhbmljLFVuaXRlZCBTdGF0ZXMKODExLEpWQlpDUEtYSEZNVTQ5MSxKVkJaQ1BLWEhGTVU0OTEtZXdmenhhYjUsMjAxNS0wMS0xM1QwMDo0NDowMS4wMDAwMDArMDAwMCwyMDE1LTAxLTEzVDAwOjU3OjAxLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNiwyNS4yLDIwMTUtMDEtMDcsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjgxOCxSTU9TV0hKR0VMQ0k2NzUsUk1PU1dISkdFTENJNjc1LTdxenNyeGhhLDIwMTUtMDEtMTNUMDI6MDY6MDkuMDAwMDAwKzAwMDAsMjAxNS0wMS0xM1QwMjoyNzowOS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDUsMjQuNywyMDE1LTAxLTEwLG90aGVyX2NhbXBhaWduLEZyYW5jZQo4MTksUk1PU1dISkdFTENJNjc1LFJNT1NXSEpHRUxDSTY3NS03cXpzcnhoYSwyMDE1LTAxLTEzVDAyOjA2OjA5LjAwMDAwMCswMDAwLDIwMTUtMDEtMTNUMDI6MzA6MTUuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA2LDI0LjcsMjAxNS0wMS0xMCxvdGhlcl9jYW1wYWlnbixGcmFuY2UKODIwLE9NQ1ZVQUlLU0RUUjY1MSxPTUNWVUFJS1NEVFI2NTEtdm9rcjQ1ODIsMjAxNS0wMS0xM1QwMjoxMTo0Mi4wMDAwMDArMDAwMCwyMDE1LTAxLTEzVDAyOjEyOjI0LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4xLDI2LjMsMjAxNS0wMS0wNyxvdGhlcl9jYW1wYWlnbixVbml0ZWQgU3RhdGVzCjgyNSxPTUNWVUFJS1NEVFI2NTEsT01DVlVBSUtTRFRSNjUxLXZva3I0NTgyLDIwMTUtMDEtMTNUMDI6MTE6NDIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xM1QwMjozMTo1NC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDgsMjYuMywyMDE1LTAxLTA3LG90aGVyX2NhbXBhaWduLFVuaXRlZCBTdGF0ZXMKODI3LE9NQ1ZVQUlLU0RUUjY1MSxPTUNWVUFJS1NEVFI2NTEtdm9rcjQ1ODIsMjAxNS0wMS0xM1QwMjoxMTo0Mi4wMDAwMDArMDAwMCwyMDE1LTAxLTEzVDAyOjM2OjAwLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wOSwyNi4zLDIwMTUtMDEtMDcsb3RoZXJfY2FtcGFpZ24sVW5pdGVkIFN0YXRlcwo4MzAsRlhXRE5LSVVNSllSNDcxLEZYV0ROS0lVTUpZUjQ3MS1wamwzYm5pNSwyMDE1LTAxLTEzVDA0OjEzOjIyLjAwMDAwMCswMDAwLDIwMTUtMDEtMTNUMDQ6MjU6MjIuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAzLDIwLjIsMjAxNS0wMS0xMCxvcmdhbmljLFVuaXRlZCBTdGF0ZXMKODM0LE5BT0pSRE1DU0VCSTI4MSxOQU9KUkRNQ1NFQkkyODEtZWhpMW4yM3YsMjAxNS0wMS0xM1QwNDo1ODoyMC4wMDAwMDArMDAwMCwyMDE1LTAxLTEzVDA1OjA1OjI2LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wODEsMTQuMiwyMDE1LTAxLTExLG9yZ2FuaWMsTm9yd2F5CjgzNSxOQU9KUkRNQ1NFQkkyODEsTkFPSlJETUNTRUJJMjgxLWVoaTFuMjN2LDIwMTUtMDEtMTNUMDQ6NTg6MjAuMDAwMDAwKzAwMDAsMjAxNS0wMS0xM1QwNTowNzowMi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDksMTQuMiwyMDE1LTAxLTExLG9yZ2FuaWMsTm9yd2F5Cjg0NixSTU9TV0hKR0VMQ0k2NzUsUk1PU1dISkdFTENJNjc1LXJ6bzI4andxLDIwMTUtMDEtMTNUMDg6Mjc6MzQuMDAwMDAwKzAwMDAsMjAxNS0wMS0xM1QwODozNzozNC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDQsMjUuNCwyMDE1LTAxLTEwLG90aGVyX2NhbXBhaWduLEZyYW5jZQo4NDcsUk1PU1dISkdFTENJNjc1LFJNT1NXSEpHRUxDSTY3NS1yem8yOGp3cSwyMDE1LTAxLTEzVDA4OjI3OjM0LjAwMDAwMCswMDAwLDIwMTUtMDEtMTNUMDg6Mzc6NDAuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyLDI1LjQsMjAxNS0wMS0xMCxvdGhlcl9jYW1wYWlnbixGcmFuY2UKODQ5LFJNT1NXSEpHRUxDSTY3NSxSTU9TV0hKR0VMQ0k2NzUtcnpvMjhqd3EsMjAxNS0wMS0xM1QwODoyNzozNC4wMDAwMDArMDAwMCwyMDE1LTAxLTEzVDA4OjQ5OjUyLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNSwyNS40LDIwMTUtMDEtMTAsb3RoZXJfY2FtcGFpZ24sRnJhbmNlCjg1MixCRk5MVVJJU0pYVEg2NDcsQkZOTFVSSVNKWFRINjQ3LWh4MjlrdDQ4LDIwMTUtMDEtMTNUMDg6NTk6MjkuMDAwMDAwKzAwMDAsMjAxNS0wMS0xM1QwOTowNzoxMS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDI0LDI0LjQsMjAxNS0wMS0xMCxvcmdhbmljLEluZGlhCjg1MyxCRk5MVVJJU0pYVEg2NDcsQkZOTFVSSVNKWFRINjQ3LWh4MjlrdDQ4LDIwMTUtMDEtMTNUMDg6NTk6MjkuMDAwMDAwKzAwMDAsMjAxNS0wMS0xM1QwOToxNDoxMS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDE4LDI0LjQsMjAxNS0wMS0xMCxvcmdhbmljLEluZGlhCjg1NCxCRk5MVVJJU0pYVEg2NDcsQkZOTFVSSVNKWFRINjQ3LWh4MjlrdDQ4LDIwMTUtMDEtMTNUMDg6NTk6MjkuMDAwMDAwKzAwMDAsMjAxNS0wMS0xM1QwOToxNDoxNy4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDA0LDI0LjQsMjAxNS0wMS0xMCxvcmdhbmljLEluZGlhCjg1OCxHQVlJQkxVQ09FREo3MzIsR0FZSUJMVUNPRURKNzMyLWxiOWtyNWlzLDIwMTUtMDEtMTNUMDk6MzU6MzEuMDAwMDAwKzAwMDAsMjAxNS0wMS0xM1QwOTo1Njo0OS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDksMjQuNSwyMDE1LTAxLTAzLG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwo4NTksQ0hLVVJBQlRGWkRFMzcyLENIS1VSQUJURlpERTM3Mi1hNnYyd29zbCwyMDE1LTAxLTEzVDA5OjUyOjQyLjAwMDAwMCswMDAwLDIwMTUtMDEtMTNUMDk6NTc6NDguMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA2NiwyMi42LDIwMTUtMDEtMTEsb3JnYW5pYyxEZW5tYXJrCjg2MyxVWlFGSERCRU1ZUFY1OTQsVVpRRkhEQkVNWVBWNTk0LXYyOWJwcjRpLDIwMTUtMDEtMTNUMTA6NTU6NDIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xM1QxMTowODowNi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDcyLDEzLjksMjAxNS0wMS0xMCxnb29nbGUsU3dpdHplcmxhbmQKODY0LFFEVVpKSUVUQ0FHVzY1NCxRRFVaSklFVENBR1c2NTQtdDgxMjk0cmosMjAxNS0wMS0xM1QxMToyMTo1MS4wMDAwMDArMDAwMCwyMDE1LTAxLTEzVDExOjQ1OjAzLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMzYsMjQuMCwyMDE1LTAxLTA3LGZhY2Vib29rLFN3aXR6ZXJsYW5kCjg3NSxOQU9KUkRNQ1NFQkkyODEsTkFPSlJETUNTRUJJMjgxLWMxdnVzM2FxLDIwMTUtMDEtMTNUMTQ6MzQ6MjUuMDAwMDAwKzAwMDAsMjAxNS0wMS0xM1QxNTowMTozMS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDU0LDM1LjYsMjAxNS0wMS0xMSxvcmdhbmljLE5vcndheQo4OTQsV0VQS1lOUlhERlVUNTcyLFdFUEtZTlJYREZVVDU3Mi0xd2x0OXppeSwyMDE1LTAxLTEzVDE2OjQxOjE2LjAwMDAwMCswMDAwLDIwMTUtMDEtMTNUMTY6NTI6MzQuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA1NCwyNS42LDIwMTUtMDEtMTMsY3Jvc3Nwcm9tbyxDaGluYQo4OTYsSlVZQkZNUEVSTERXMzk0LEpVWUJGTVBFUkxEVzM5NC02czh2ZmwyeCwyMDE1LTAxLTEzVDE4OjQ1OjQ1LjAwMDAwMCswMDAwLDIwMTUtMDEtMTNUMTg6NTI6NDUuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4wOSwxOS45LDIwMTUtMDEtMTMsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjkwMCxHU1FKWElPS1lNRUE3MTIsR1NRSlhJT0tZTUVBNzEyLTNxODJ2a2c5LDIwMTUtMDEtMTNUMTk6MTY6NTEuMDAwMDAwKzAwMDAsMjAxNS0wMS0xM1QxOTo0NzozMy4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDYsMzQuMCwyMDE1LTAxLTA3LGdvb2dsZSxHZXJtYW55CjkxMSxXRVBLWU5SWERGVVQ1NzIsV0VQS1lOUlhERlVUNTcyLTZtOXdrNzRvLDIwMTUtMDEtMTNUMjI6MjY6NDguMDAwMDAwKzAwMDAsMjAxNS0wMS0xM1QyMjo0NToxOC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDY2LDI2LjQsMjAxNS0wMS0xMyxjcm9zc3Byb21vLENoaW5hCjkxMyxaUFRJSE5TVkZZQVExNDYsWlBUSUhOU1ZGWUFRMTQ2LWpjM2Q3bnJxLDIwMTUtMDEtMTNUMjI6NDM6MDMuMDAwMDAwKzAwMDAsMjAxNS0wMS0xM1QyMjo1Mzo1Ny4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDQ4LDIzLjIsMjAxNS0wMS0wNCxmYWNlYm9vayxNZXhpY28KOTE1LFBaQk5SS1NNVUxIWDIxMyxQWkJOUktTTVVMSFgyMTMtYmx3ZDN4N3EsMjAxNS0wMS0xM1QyMzoyMzoyNy4wMDAwMDArMDAwMCwyMDE1LTAxLTEzVDIzOjMzOjQ1LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMjQsMjQuNiwyMDE1LTAxLTA3LG9yZ2FuaWMsSW5kaWEKOTE3LFBaQk5SS1NNVUxIWDIxMyxQWkJOUktTTVVMSFgyMTMtYmx3ZDN4N3EsMjAxNS0wMS0xM1QyMzoyMzoyNy4wMDAwMDArMDAwMCwyMDE1LTAxLTEzVDIzOjQwOjMzLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMTgsMjQuNiwyMDE1LTAxLTA3LG9yZ2FuaWMsSW5kaWEKOTE4LFBaQk5SS1NNVUxIWDIxMyxQWkJOUktTTVVMSFgyMTMtYmx3ZDN4N3EsMjAxNS0wMS0xM1QyMzoyMzoyNy4wMDAwMDArMDAwMCwyMDE1LTAxLTEzVDIzOjQxOjI3LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMTgsMjQuNiwyMDE1LTAxLTA3LG9yZ2FuaWMsSW5kaWEKOTE5LFdCS0ZZSlhDWk5VSDU2MyxXQktGWUpYQ1pOVUg1NjMtbnpzcHI2dXQsMjAxNS0wMS0xM1QyMzoyODo1OC4wMDAwMDArMDAwMCwyMDE1LTAxLTEzVDIzOjM2OjI4LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNCwzMC43LDIwMTUtMDEtMTMsb3JnYW5pYyxDYW5hZGEKOTIxLFdCS0ZZSlhDWk5VSDU2MyxXQktGWUpYQ1pOVUg1NjMtbnpzcHI2dXQsMjAxNS0wMS0xM1QyMzoyODo1OC4wMDAwMDArMDAwMCwyMDE1LTAxLTEzVDIzOjUwOjM0LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4xLDMwLjcsMjAxNS0wMS0xMyxvcmdhbmljLENhbmFkYQo5MjQsWElBSEJOS0VDR1JPNTk4LFhJQUhCTktFQ0dSTzU5OC1sNXVmOWlwMywyMDE1LTAxLTE0VDAwOjM4OjQxLjAwMDAwMCswMDAwLDIwMTUtMDEtMTRUMDA6NDY6MjMuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyLDIwLjAsMjAxNS0wMS0xNCxnb29nbGUsRWd5cHQKOTI2LFhJQUhCTktFQ0dSTzU5OCxYSUFIQk5LRUNHUk81OTgtbDV1ZjlpcDMsMjAxNS0wMS0xNFQwMDozODo0MS4wMDAwMDArMDAwMCwyMDE1LTAxLTE0VDAwOjU4OjA1LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNTUsMjAuMCwyMDE1LTAxLTE0LGdvb2dsZSxFZ3lwdAo5MzQsTVhDT1ZFWUlBS0ZINTk0LE1YQ09WRVlJQUtGSDU5NC1pNzUyNDlmMywyMDE1LTAxLTE0VDAxOjMwOjIzLjAwMDAwMCswMDAwLDIwMTUtMDEtMTRUMDE6NDg6MTEuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4wNzIsMjEuMywyMDE1LTAxLTEwLG9yZ2FuaWMsQ2hpbmEKOTM1LEpVQkRWRkhDTlFXVDE5OCxKVUJEVkZIQ05RV1QxOTgtNXdrYnNkb2ksMjAxNS0wMS0xNFQwMjoxMDo0MC4wMDAwMDArMDAwMCwyMDE1LTAxLTE0VDAyOjE0OjQwLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMzIsMzcuMywyMDE1LTAxLTE0LG9yZ2FuaWMsUGhpbGlwcGluZXMKOTM2LEpVQkRWRkhDTlFXVDE5OCxKVUJEVkZIQ05RV1QxOTgtNXdrYnNkb2ksMjAxNS0wMS0xNFQwMjoxMDo0MC4wMDAwMDArMDAwMCwyMDE1LTAxLTE0VDAyOjI4OjQwLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMjgsMzcuMywyMDE1LTAxLTE0LG9yZ2FuaWMsUGhpbGlwcGluZXMKOTM3LEpVWUJGTVBFUkxEVzM5NCxKVVlCRk1QRVJMRFczOTQtODdsMnRiaHMsMjAxNS0wMS0xNFQwMjozMDozMC4wMDAwMDArMDAwMCwyMDE1LTAxLTE0VDAyOjM4OjM2LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4xLDE3LjgsMjAxNS0wMS0xMyxvcmdhbmljLFVuaXRlZCBTdGF0ZXMKOTQyLE1UQ0lXS09WQVNZUDkyNSxNVENJV0tPVkFTWVA5MjUtNHpxdWs1ZnIsMjAxNS0wMS0xNFQwMjo0NToyMC4wMDAwMDArMDAwMCwyMDE1LTAxLTE0VDAyOjUzOjI2LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMiwxMS41LDIwMTUtMDEtMTQsb3JnYW5pYyxHZXJtYW55Cjk0OSxaUFRJSE5TVkZZQVExNDYsWlBUSUhOU1ZGWUFRMTQ2LTFiNmloN3ZnLDIwMTUtMDEtMTRUMDI6NDg6NTYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNFQwMzoyMToxNC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDEyLDM0LjksMjAxNS0wMS0wNCxmYWNlYm9vayxNZXhpY28KOTUwLEpZRUJDTE5VWlRYUTQ1NyxKWUVCQ0xOVVpUWFE0NTctYnRvdjZpdzQsMjAxNS0wMS0xNFQwMjo1MzozNy4wMDAwMDArMDAwMCwyMDE1LTAxLTE0VDAyOjU3OjE5LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMzUsOC44LDIwMTUtMDEtMDQsb3RoZXJfY2FtcGFpZ24sRWd5cHQKOTUyLEpWQlpDUEtYSEZNVTQ5MSxKVkJaQ1BLWEhGTVU0OTEtc2F6bnVrZmksMjAxNS0wMS0xNFQwMjo1ODowOS4wMDAwMDArMDAwMCwyMDE1LTAxLTE0VDAzOjA1OjA5LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNSwzNS43LDIwMTUtMDEtMDcsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjk1NSxKVkJaQ1BLWEhGTVU0OTEsSlZCWkNQS1hIRk1VNDkxLXNhem51a2ZpLDIwMTUtMDEtMTRUMDI6NTg6MDkuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNFQwMzoxNToxNS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDgsMzUuNywyMDE1LTAxLTA3LG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwo5NTcsWElBSEJOS0VDR1JPNTk4LFhJQUhCTktFQ0dSTzU5OC1qbGhkbnM4aSwyMDE1LTAxLTE0VDA0OjMyOjE1LjAwMDAwMCswMDAwLDIwMTUtMDEtMTRUMDQ6MzQ6MzMuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAxNSwxNC4xLDIwMTUtMDEtMTQsZ29vZ2xlLEVneXB0Cjk1OCxYSUFIQk5LRUNHUk81OTgsWElBSEJOS0VDR1JPNTk4LWpsaGRuczhpLDIwMTUtMDEtMTRUMDQ6MzI6MTUuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNFQwNDo0NDowMy4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjA1LDE0LjEsMjAxNS0wMS0xNCxnb29nbGUsRWd5cHQKOTYwLEVGTE5QR1RSWlZBQzc2NSxFRkxOUEdUUlpWQUM3NjUtdHM0OW0zcTcsMjAxNS0wMS0xNFQwNDozMzoyOC4wMDAwMDArMDAwMCwyMDE1LTAxLTE0VDA0OjQ3OjQwLjAwMDAwMCswMDAwLGFkLGFkXzE1c2VjLDAuMDU4LDIwLjcsMjAxNS0wMS0xNCxvdGhlcl9jYW1wYWlnbixSdXNzaWEKOTYxLEVGTE5QR1RSWlZBQzc2NSxFRkxOUEdUUlpWQUM3NjUtdHM0OW0zcTcsMjAxNS0wMS0xNFQwNDozMzoyOC4wMDAwMDArMDAwMCwyMDE1LTAxLTE0VDA0OjUxOjE2LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMTUsMjAuNywyMDE1LTAxLTE0LG90aGVyX2NhbXBhaWduLFJ1c3NpYQo5NjIsRUZMTlBHVFJaVkFDNzY1LEVGTE5QR1RSWlZBQzc2NS10czQ5bTNxNywyMDE1LTAxLTE0VDA0OjMzOjI4LjAwMDAwMCswMDAwLDIwMTUtMDEtMTRUMDQ6NTE6NDAuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAxNSwyMC43LDIwMTUtMDEtMTQsb3RoZXJfY2FtcGFpZ24sUnVzc2lhCjk2OSxETFRGVlFXWUlYUko1ODksRExURlZRV1lJWFJKNTg5LXNreXY4MnBlLDIwMTUtMDEtMTRUMDQ6Mzk6NDkuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNFQwNDo1Mzo1NS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDU1OSwzMi43LDIwMTUtMDEtMTMsb3JnYW5pYyxTb3V0aCBBZnJpY2EKOTcwLERMVEZWUVdZSVhSSjU4OSxETFRGVlFXWUlYUko1ODktc2t5djgycGUsMjAxNS0wMS0xNFQwNDozOTo0OS4wMDAwMDArMDAwMCwyMDE1LTAxLTE0VDA0OjU1OjMxLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNDEsMzIuNywyMDE1LTAxLTEzLG9yZ2FuaWMsU291dGggQWZyaWNhCjk3MixLR1pDT0pIUEZUUVY3NTMsS0daQ09KSFBGVFFWNzUzLXJpY3p0OHBkLDIwMTUtMDEtMTRUMDU6MDY6MDIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNFQwNToyNDozMi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDgsMzguMSwyMDE1LTAxLTExLG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwo5NzQsSlZCWkNQS1hIRk1VNDkxLEpWQlpDUEtYSEZNVTQ5MS13MXEybGV1OSwyMDE1LTAxLTE0VDA1OjI4OjQ2LjAwMDAwMCswMDAwLDIwMTUtMDEtMTRUMDU6MzM6NDAuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA1LDUuMSwyMDE1LTAxLTA3LG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwo5NzUsV0JLRllKWENaTlVINTYzLFdCS0ZZSlhDWk5VSDU2My15N3JrYm5naiwyMDE1LTAxLTE0VDA2OjM3OjE1LjAwMDAwMCswMDAwLDIwMTUtMDEtMTRUMDY6Mzc6MjEuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAzLDM5LjAsMjAxNS0wMS0xMyxvcmdhbmljLENhbmFkYQo5ODEsVkxRSFlKQ0tCT0lONzI5LFZMUUhZSkNLQk9JTjcyOS0yN3BvZ21qdiwyMDE1LTAxLTE0VDA3OjA0OjMyLjAwMDAwMCswMDAwLDIwMTUtMDEtMTRUMDc6MDg6NTYuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAzLDkuMywyMDE1LTAxLTEwLG9yZ2FuaWMsSmFwYW4KOTg1LEdKQ1hOVFdFQklQUTM2OSxHSkNYTlRXRUJJUFEzNjktM3VvcGNrbnksMjAxNS0wMS0xNFQwNzo1MjoxMy4wMDAwMDArMDAwMCwyMDE1LTAxLTE0VDA4OjExOjQ5LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNiwzNS45LDIwMTUtMDEtMTQsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjk4NyxKVVlCRk1QRVJMRFczOTQsSlVZQkZNUEVSTERXMzk0LWF6bXE3dzlsLDIwMTUtMDEtMTRUMDg6MjE6MTMuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNFQwODo0NToxMy4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDQsMzAuMSwyMDE1LTAxLTEzLG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwo5ODgsUU5MVlJERU9YRllKODkyLFFOTFZSREVPWEZZSjg5Mi01dTN3bjhwNywyMDE1LTAxLTE0VDA4OjIxOjQyLjAwMDAwMCswMDAwLDIwMTUtMDEtMTRUMDg6Mjg6MTguMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA4LDM0LjYsMjAxNS0wMS0wOSxjcm9zc3Byb21vLEF1c3RyYWxpYQo5OTAsUU5MVlJERU9YRllKODkyLFFOTFZSREVPWEZZSjg5Mi01dTN3bjhwNywyMDE1LTAxLTE0VDA4OjIxOjQyLjAwMDAwMCswMDAwLDIwMTUtMDEtMTRUMDg6MzM6MjQuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA5LDM0LjYsMjAxNS0wMS0wOSxjcm9zc3Byb21vLEF1c3RyYWxpYQo5OTcsSERTQU1QVE9MQldDNDM4LEhEU0FNUFRPTEJXQzQzOC12dDh1Y3BtMywyMDE1LTAxLTE0VDA5OjAyOjMxLjAwMDAwMCswMDAwLDIwMTUtMDEtMTRUMDk6MTY6MTkuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA2LDIwLjcsMjAxNS0wMS0xNCxvcmdhbmljLFN3aXR6ZXJsYW5kCjEwMDUsTVRDSVdLT1ZBU1lQOTI1LE1UQ0lXS09WQVNZUDkyNS04YTZ4ZnFvaywyMDE1LTAxLTE0VDEwOjE4OjMyLjAwMDAwMCswMDAwLDIwMTUtMDEtMTRUMTA6MzE6MjAuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA0LDE2LjMsMjAxNS0wMS0xNCxvcmdhbmljLEdlcm1hbnkKMTAwOSxHQVlJQkxVQ09FREo3MzIsR0FZSUJMVUNPRURKNzMyLTdvY3N0MW16LDIwMTUtMDEtMTRUMTE6NDM6NTEuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNFQxMTo0NzozMy4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjEsMzUuMSwyMDE1LTAxLTAzLG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwoxMDE1LE5NUlVXSEFZSlBCUTgyNCxOTVJVV0hBWUpQQlE4MjQtMTQ1Y3I4N3EsMjAxNS0wMS0xNFQxMjowMjoyMy4wMDAwMDArMDAwMCwyMDE1LTAxLTE0VDEyOjMyOjUzLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wODQ5LDMzLjMsMjAxNS0wMS0wOCxvcmdhbmljLEhvbmcgS29uZwoxMDE2LE5NUlVXSEFZSlBCUTgyNCxOTVJVV0hBWUpQQlE4MjQtMTQ1Y3I4N3EsMjAxNS0wMS0xNFQxMjowMjoyMy4wMDAwMDArMDAwMCwyMDE1LTAxLTE0VDEyOjMzOjI5LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wOCwzMy4zLDIwMTUtMDEtMDgsb3JnYW5pYyxIb25nIEtvbmcKMTAxNyxOQU9KUkRNQ1NFQkkyODEsTkFPSlJETUNTRUJJMjgxLWd3YjlvNmRjLDIwMTUtMDEtMTRUMTI6NDk6NDUuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNFQxMjo1MTo1Ny4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDU0LDE1LjgsMjAxNS0wMS0xMSxvcmdhbmljLE5vcndheQoxMDI0LEdBWUlCTFVDT0VESjczMixHQVlJQkxVQ09FREo3MzItbHBrdXdncjQsMjAxNS0wMS0xNFQxNDo1NTozOC4wMDAwMDArMDAwMCwyMDE1LTAxLTE0VDE1OjEyOjAyLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wOCwyOS42LDIwMTUtMDEtMDMsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjEwMjcsQkZOTFVSSVNKWFRINjQ3LEJGTkxVUklTSlhUSDY0Ny16aTk2Y3BuMSwyMDE1LTAxLTE0VDE0OjU5OjQxLjAwMDAwMCswMDAwLDIwMTUtMDEtMTRUMTU6MTY6NDcuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyNCwyNC44LDIwMTUtMDEtMTAsb3JnYW5pYyxJbmRpYQoxMDMwLEJGTkxVUklTSlhUSDY0NyxCRk5MVVJJU0pYVEg2NDctemk5NmNwbjEsMjAxNS0wMS0xNFQxNDo1OTo0MS4wMDAwMDArMDAwMCwyMDE1LTAxLTE0VDE1OjIyOjE3LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMjIsMjQuOCwyMDE1LTAxLTEwLG9yZ2FuaWMsSW5kaWEKMTAzMSxYSUFIQk5LRUNHUk81OTgsWElBSEJOS0VDR1JPNTk4LXVuMWZiejk1LDIwMTUtMDEtMTRUMTY6MDY6MzcuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNFQxNjowOTo0My4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDUsMjcuMiwyMDE1LTAxLTE0LGdvb2dsZSxFZ3lwdAoxMDMyLFhJQUhCTktFQ0dSTzU5OCxYSUFIQk5LRUNHUk81OTgtdW4xZmJ6OTUsMjAxNS0wMS0xNFQxNjowNjozNy4wMDAwMDArMDAwMCwyMDE1LTAxLTE0VDE2OjE3OjE5LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNDUsMjcuMiwyMDE1LTAxLTE0LGdvb2dsZSxFZ3lwdAoxMDMzLFhJQUhCTktFQ0dSTzU5OCxYSUFIQk5LRUNHUk81OTgtdW4xZmJ6OTUsMjAxNS0wMS0xNFQxNjowNjozNy4wMDAwMDArMDAwMCwyMDE1LTAxLTE0VDE2OjI0OjEzLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNCwyNy4yLDIwMTUtMDEtMTQsZ29vZ2xlLEVneXB0CjEwMzQsWElBSEJOS0VDR1JPNTk4LFhJQUhCTktFQ0dSTzU5OC11bjFmYno5NSwyMDE1LTAxLTE0VDE2OjA2OjM3LjAwMDAwMCswMDAwLDIwMTUtMDEtMTRUMTY6MjY6NDMuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAxLDI3LjIsMjAxNS0wMS0xNCxnb29nbGUsRWd5cHQKMTAzNixYSUFIQk5LRUNHUk81OTgsWElBSEJOS0VDR1JPNTk4LXVuMWZiejk1LDIwMTUtMDEtMTRUMTY6MDY6MzcuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNFQxNjoyODowMS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDIsMjcuMiwyMDE1LTAxLTE0LGdvb2dsZSxFZ3lwdAoxMDM5LE9NQ1ZVQUlLU0RUUjY1MSxPTUNWVUFJS1NEVFI2NTEtYmZsNmRpcmosMjAxNS0wMS0xNFQxNjo0MjoxNC4wMDAwMDArMDAwMCwyMDE1LTAxLTE0VDE2OjQ1OjIwLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMywyNS40LDIwMTUtMDEtMDcsb3RoZXJfY2FtcGFpZ24sVW5pdGVkIFN0YXRlcwoxMDQwLE9NQ1ZVQUlLU0RUUjY1MSxPTUNWVUFJS1NEVFI2NTEtYmZsNmRpcmosMjAxNS0wMS0xNFQxNjo0MjoxNC4wMDAwMDArMDAwMCwyMDE1LTAxLTE0VDE2OjU2OjAyLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNiwyNS40LDIwMTUtMDEtMDcsb3RoZXJfY2FtcGFpZ24sVW5pdGVkIFN0YXRlcwoxMDQ5LFJNT1NXSEpHRUxDSTY3NSxSTU9TV0hKR0VMQ0k2NzUtMWJueGRxenAsMjAxNS0wMS0xNFQxNzoyMjo1My4wMDAwMDArMDAwMCwyMDE1LTAxLTE0VDE3OjQzOjExLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNSwyMC4zLDIwMTUtMDEtMTAsb3RoZXJfY2FtcGFpZ24sRnJhbmNlCjEwNTAsUU5MVlJERU9YRllKODkyLFFOTFZSREVPWEZZSjg5Mi1oM2pvY2xnZiwyMDE1LTAxLTE0VDE4OjIxOjE4LjAwMDAwMCswMDAwLDIwMTUtMDEtMTRUMTg6Mjc6MDAuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA1LDkuNCwyMDE1LTAxLTA5LGNyb3NzcHJvbW8sQXVzdHJhbGlhCjEwNTIsUFpCTlJLU01VTEhYMjEzLFBaQk5SS1NNVUxIWDIxMy1meG9pYmpubCwyMDE1LTAxLTE0VDE4OjMzOjU2LjAwMDAwMCswMDAwLDIwMTUtMDEtMTRUMTg6Mzg6NDQuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAxLDEzLjMsMjAxNS0wMS0wNyxvcmdhbmljLEluZGlhCjEwNTMsUFpCTlJLU01VTEhYMjEzLFBaQk5SS1NNVUxIWDIxMy1meG9pYmpubCwyMDE1LTAxLTE0VDE4OjMzOjU2LjAwMDAwMCswMDAwLDIwMTUtMDEtMTRUMTg6NDU6MjYuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAwNiwxMy4zLDIwMTUtMDEtMDcsb3JnYW5pYyxJbmRpYQoxMDY1LE1YQ09WRVlJQUtGSDU5NCxNWENPVkVZSUFLRkg1OTQtNDI5M3pzdTEsMjAxNS0wMS0xNVQwMDoxOTo0Mi4wMDAwMDArMDAwMCwyMDE1LTAxLTE1VDAwOjI0OjE4LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNDgsMjcuNywyMDE1LTAxLTEwLG9yZ2FuaWMsQ2hpbmEKMTA2OSxHSkNYTlRXRUJJUFEzNjksR0pDWE5UV0VCSVBRMzY5LWs2cW9weWJzLDIwMTUtMDEtMTVUMDA6NTQ6NDAuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNVQwMDo1NToxMC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDIsMTkuMywyMDE1LTAxLTE0LG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwoxMDcyLEdKQ1hOVFdFQklQUTM2OSxHSkNYTlRXRUJJUFEzNjktazZxb3B5YnMsMjAxNS0wMS0xNVQwMDo1NDo0MC4wMDAwMDArMDAwMCwyMDE1LTAxLTE1VDAxOjA0OjA0LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4xLDE5LjMsMjAxNS0wMS0xNCxvcmdhbmljLFVuaXRlZCBTdGF0ZXMKMTA3MyxHSkNYTlRXRUJJUFEzNjksR0pDWE5UV0VCSVBRMzY5LWs2cW9weWJzLDIwMTUtMDEtMTVUMDA6NTQ6NDAuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNVQwMTowNDoyOC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMSwxOS4zLDIwMTUtMDEtMTQsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjEwODEsTVRDSVdLT1ZBU1lQOTI1LE1UQ0lXS09WQVNZUDkyNS05ZTZhc2xoMiwyMDE1LTAxLTE1VDAyOjE1OjExLjAwMDAwMCswMDAwLDIwMTUtMDEtMTVUMDI6MzE6MTcuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAzLDM1LjMsMjAxNS0wMS0xNCxvcmdhbmljLEdlcm1hbnkKMTA4MyxNVENJV0tPVkFTWVA5MjUsTVRDSVdLT1ZBU1lQOTI1LTllNmFzbGgyLDIwMTUtMDEtMTVUMDI6MTU6MTEuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNVQwMjozMjo1OS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDYsMzUuMywyMDE1LTAxLTE0LG9yZ2FuaWMsR2VybWFueQoxMDk3LFdOVkJBWUdDTEpJUjUxNyxXTlZCQVlHQ0xKSVI1MTctZzFkYnI1ZnosMjAxNS0wMS0xNVQwMzoyNTo1OS4wMDAwMDArMDAwMCwyMDE1LTAxLTE1VDAzOjUwOjA1LjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDc3LDI4LjgsMjAxNS0wMS0xMyxmYWNlYm9vayxTd2VkZW4KMTA5OSxaTUpMUEdDUklLTkE0NzEsWk1KTFBHQ1JJS05BNDcxLXNqa2ZtYzR5LDIwMTUtMDEtMTVUMDM6Mzk6MzguMDAwMDAwKzAwMDAsMjAxNS0wMS0xNVQwMzo0MzoyNi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDYsMTcuNSwyMDE1LTAxLTEwLG9yZ2FuaWMsRWd5cHQKMTEwMCxaTUpMUEdDUklLTkE0NzEsWk1KTFBHQ1JJS05BNDcxLXNqa2ZtYzR5LDIwMTUtMDEtMTVUMDM6Mzk6MzguMDAwMDAwKzAwMDAsMjAxNS0wMS0xNVQwMzo0NTo1MC4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjA0NSwxNy41LDIwMTUtMDEtMTAsb3JnYW5pYyxFZ3lwdAoxMTAxLFpNSkxQR0NSSUtOQTQ3MSxaTUpMUEdDUklLTkE0NzEtc2prZm1jNHksMjAxNS0wMS0xNVQwMzozOTozOC4wMDAwMDArMDAwMCwyMDE1LTAxLTE1VDAzOjUyOjE0LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMSwxNy41LDIwMTUtMDEtMTAsb3JnYW5pYyxFZ3lwdAoxMTA2LEJGTkxVUklTSlhUSDY0NyxCRk5MVVJJU0pYVEg2NDctZ3N2amI3d2UsMjAxNS0wMS0xNVQwNTowMTo1MC4wMDAwMDArMDAwMCwyMDE1LTAxLTE1VDA1OjA4OjQ0LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMjIsMTMuNSwyMDE1LTAxLTEwLG9yZ2FuaWMsSW5kaWEKMTEwNyxLR1pDT0pIUEZUUVY3NTMsS0daQ09KSFBGVFFWNzUzLXo1NHhvbHdmLDIwMTUtMDEtMTVUMDU6MTU6MzMuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNVQwNToxNzo0NS4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjEsMjEuOCwyMDE1LTAxLTExLG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwoxMTA4LEtHWkNPSkhQRlRRVjc1MyxLR1pDT0pIUEZUUVY3NTMtejU0eG9sd2YsMjAxNS0wMS0xNVQwNToxNTozMy4wMDAwMDArMDAwMCwyMDE1LTAxLTE1VDA1OjI2OjA5LjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDksMjEuOCwyMDE1LTAxLTExLG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwoxMTEwLERMVEZWUVdZSVhSSjU4OSxETFRGVlFXWUlYUko1ODktbm9oZmFlMzcsMjAxNS0wMS0xNVQwNToxNjowNC4wMDAwMDArMDAwMCwyMDE1LTAxLTE1VDA1OjIyOjQ2LjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDk4LDEzLjAsMjAxNS0wMS0xMyxvcmdhbmljLFNvdXRoIEFmcmljYQoxMTExLERMVEZWUVdZSVhSSjU4OSxETFRGVlFXWUlYUko1ODktbm9oZmFlMzcsMjAxNS0wMS0xNVQwNToxNjowNC4wMDAwMDArMDAwMCwyMDE1LTAxLTE1VDA1OjI1OjM0LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNDEsMTMuMCwyMDE1LTAxLTEzLG9yZ2FuaWMsU291dGggQWZyaWNhCjExMjIsUU5MVlJERU9YRllKODkyLFFOTFZSREVPWEZZSjg5Mi05bGt0M3JvOCwyMDE1LTAxLTE1VDA2OjQ1OjM0LjAwMDAwMCswMDAwLDIwMTUtMDEtMTVUMDY6NTQ6MzQuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA5LDM1LjksMjAxNS0wMS0wOSxjcm9zc3Byb21vLEF1c3RyYWxpYQoxMTI3LFFEVVpKSUVUQ0FHVzY1NCxRRFVaSklFVENBR1c2NTQteWR3cmx2NnEsMjAxNS0wMS0xNVQwNjo0Njo1MS4wMDAwMDArMDAwMCwyMDE1LTAxLTE1VDA3OjIzOjM5LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wODQsMzguNiwyMDE1LTAxLTA3LGZhY2Vib29rLFN3aXR6ZXJsYW5kCjExMzAsVkxRSFlKQ0tCT0lONzI5LFZMUUhZSkNLQk9JTjcyOS02c2Z5d3Y3bSwyMDE1LTAxLTE1VDA4OjE4OjIwLjAwMDAwMCswMDAwLDIwMTUtMDEtMTVUMDg6MjE6MDIuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAxMiwzNC4wLDIwMTUtMDEtMTAsb3JnYW5pYyxKYXBhbgoxMTM1LFhJQUhCTktFQ0dSTzU5OCxYSUFIQk5LRUNHUk81OTgtbnE3dWVyd3osMjAxNS0wMS0xNVQwOTo1NzozMS4wMDAwMDArMDAwMCwyMDE1LTAxLTE1VDEwOjAwOjQzLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMiwzMC41LDIwMTUtMDEtMTQsZ29vZ2xlLEVneXB0CjExMzYsWElBSEJOS0VDR1JPNTk4LFhJQUhCTktFQ0dSTzU5OC1ucTd1ZXJ3eiwyMDE1LTAxLTE1VDA5OjU3OjMxLjAwMDAwMCswMDAwLDIwMTUtMDEtMTVUMTA6MDE6MTkuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAzNSwzMC41LDIwMTUtMDEtMTQsZ29vZ2xlLEVneXB0CjExMzcsWElBSEJOS0VDR1JPNTk4LFhJQUhCTktFQ0dSTzU5OC1ucTd1ZXJ3eiwyMDE1LTAxLTE1VDA5OjU3OjMxLjAwMDAwMCswMDAwLDIwMTUtMDEtMTVUMTA6MDM6MDEuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4wNiwzMC41LDIwMTUtMDEtMTQsZ29vZ2xlLEVneXB0CjExMzgsWElBSEJOS0VDR1JPNTk4LFhJQUhCTktFQ0dSTzU5OC1ucTd1ZXJ3eiwyMDE1LTAxLTE1VDA5OjU3OjMxLjAwMDAwMCswMDAwLDIwMTUtMDEtMTVUMTA6MTY6MTMuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA1LDMwLjUsMjAxNS0wMS0xNCxnb29nbGUsRWd5cHQKMTEzOSxYSUFIQk5LRUNHUk81OTgsWElBSEJOS0VDR1JPNTk4LW5xN3Vlcnd6LDIwMTUtMDEtMTVUMDk6NTc6MzEuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNVQxMDoyMToyNS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDMsMzAuNSwyMDE1LTAxLTE0LGdvb2dsZSxFZ3lwdAoxMTQxLFdFUEtZTlJYREZVVDU3MixXRVBLWU5SWERGVVQ1NzItZHo3MTZpOHMsMjAxNS0wMS0xNVQxMDoxNzo1NC4wMDAwMDArMDAwMCwyMDE1LTAxLTE1VDEwOjE4OjM2LjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDc4LDM5LjUsMjAxNS0wMS0xMyxjcm9zc3Byb21vLENoaW5hCjExNDMsV0VQS1lOUlhERlVUNTcyLFdFUEtZTlJYREZVVDU3Mi1kejcxNmk4cywyMDE1LTAxLTE1VDEwOjE3OjU0LjAwMDAwMCswMDAwLDIwMTUtMDEtMTVUMTA6MjY6MDAuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA0MiwzOS41LDIwMTUtMDEtMTMsY3Jvc3Nwcm9tbyxDaGluYQoxMTQ4LE9NQ1ZVQUlLU0RUUjY1MSxPTUNWVUFJS1NEVFI2NTEteDFndTZmZWEsMjAxNS0wMS0xNVQxMDoyMjo1NS4wMDAwMDArMDAwMCwyMDE1LTAxLTE1VDEwOjM2OjA3LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNywyOS43LDIwMTUtMDEtMDcsb3RoZXJfY2FtcGFpZ24sVW5pdGVkIFN0YXRlcwoxMTUzLEpWQlpDUEtYSEZNVTQ5MSxKVkJaQ1BLWEhGTVU0OTEtanN1YXp5dnAsMjAxNS0wMS0xNVQxMDozNzozOS4wMDAwMDArMDAwMCwyMDE1LTAxLTE1VDEwOjUxOjIxLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wOCwzOC40LDIwMTUtMDEtMDcsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjExNTcsSlZCWkNQS1hIRk1VNDkxLEpWQlpDUEtYSEZNVTQ5MS1qc3Vhenl2cCwyMDE1LTAxLTE1VDEwOjM3OjM5LjAwMDAwMCswMDAwLDIwMTUtMDEtMTVUMTE6MTE6MjcuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4wOSwzOC40LDIwMTUtMDEtMDcsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjExNTksWElBSEJOS0VDR1JPNTk4LFhJQUhCTktFQ0dSTzU5OC1hZzE5anQ4ZiwyMDE1LTAxLTE1VDExOjM0OjQyLjAwMDAwMCswMDAwLDIwMTUtMDEtMTVUMTE6Mzg6NDguMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAxLDE1LjksMjAxNS0wMS0xNCxnb29nbGUsRWd5cHQKMTE2MCxYSUFIQk5LRUNHUk81OTgsWElBSEJOS0VDR1JPNTk4LWFnMTlqdDhmLDIwMTUtMDEtMTVUMTE6MzQ6NDIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNVQxMTo0MDo1NC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDM1LDE1LjksMjAxNS0wMS0xNCxnb29nbGUsRWd5cHQKMTE2NixPQU5DSVZZWEpNUkw1OTcsT0FOQ0lWWVhKTVJMNTk3LWVpeTFmdDVhLDIwMTUtMDEtMTVUMTE6NTA6NDQuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNVQxMjoxMToyMC4wMDAwMDArMDAwMCxhZCxhZF8yMHNlYywwLjA5OCwzOC44LDIwMTUtMDEtMTUsb3RoZXJfY2FtcGFpZ24sSW5kaWEKMTE2NyxPQU5DSVZZWEpNUkw1OTcsT0FOQ0lWWVhKTVJMNTk3LWVpeTFmdDVhLDIwMTUtMDEtMTVUMTE6NTA6NDQuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNVQxMjoyNTo0NC4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjAzNCwzOC44LDIwMTUtMDEtMTUsb3RoZXJfY2FtcGFpZ24sSW5kaWEKMTE3NCxPQU5DSVZZWEpNUkw1OTcsT0FOQ0lWWVhKTVJMNTk3LWJyaTl1cGgxLDIwMTUtMDEtMTVUMTM6MjQ6MjcuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNVQxMzoyNDo1MS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDA0LDE3LjcsMjAxNS0wMS0xNSxvdGhlcl9jYW1wYWlnbixJbmRpYQoxMTc1LE9BTkNJVllYSk1STDU5NyxPQU5DSVZZWEpNUkw1OTctYnJpOXVwaDEsMjAxNS0wMS0xNVQxMzoyNDoyNy4wMDAwMDArMDAwMCwyMDE1LTAxLTE1VDEzOjI4OjE1LjAwMDAwMCswMDAwLGFkLGFkXzE1c2VjLDAuMDgsMTcuNywyMDE1LTAxLTE1LG90aGVyX2NhbXBhaWduLEluZGlhCjExNzgsSlZCWkNQS1hIRk1VNDkxLEpWQlpDUEtYSEZNVTQ5MS0zZWh5N2RxOSwyMDE1LTAxLTE1VDE2OjM3OjQ5LjAwMDAwMCswMDAwLDIwMTUtMDEtMTVUMTY6NDU6MjUuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA3LDguMCwyMDE1LTAxLTA3LG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwoxMTg0LE1UQ0lXS09WQVNZUDkyNSxNVENJV0tPVkFTWVA5MjUteXNwZGlrcWosMjAxNS0wMS0xNVQxNzowNjozMy4wMDAwMDArMDAwMCwyMDE1LTAxLTE1VDE3OjA4OjI3LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNSwzMS4wLDIwMTUtMDEtMTQsb3JnYW5pYyxHZXJtYW55CjExODYsTVRDSVdLT1ZBU1lQOTI1LE1UQ0lXS09WQVNZUDkyNS15c3BkaWtxaiwyMDE1LTAxLTE1VDE3OjA2OjMzLjAwMDAwMCswMDAwLDIwMTUtMDEtMTVUMTc6MTE6MjEuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA0LDMxLjAsMjAxNS0wMS0xNCxvcmdhbmljLEdlcm1hbnkKMTE4OCxETFRGVlFXWUlYUko1ODksRExURlZRV1lJWFJKNTg5LXI0a2J4MXl0LDIwMTUtMDEtMTVUMTg6NDg6NTIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNVQxOTowMzo0MC4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjA3NywxNy44LDIwMTUtMDEtMTMsb3JnYW5pYyxTb3V0aCBBZnJpY2EKMTE5MyxHSkNYTlRXRUJJUFEzNjksR0pDWE5UV0VCSVBRMzY5LTVpa212ZmIxLDIwMTUtMDEtMTVUMjA6NTI6NTAuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNVQyMDo1NDoyNi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDIsMzMuMiwyMDE1LTAxLTE0LG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwoxMTk0LEdKQ1hOVFdFQklQUTM2OSxHSkNYTlRXRUJJUFEzNjktNWlrbXZmYjEsMjAxNS0wMS0xNVQyMDo1Mjo1MC4wMDAwMDArMDAwMCwyMDE1LTAxLTE1VDIxOjAyOjMyLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wOSwzMy4yLDIwMTUtMDEtMTQsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjExOTksVkxRSFlKQ0tCT0lONzI5LFZMUUhZSkNLQk9JTjcyOS05ZXZqb3djdCwyMDE1LTAxLTE1VDIxOjU1OjIxLjAwMDAwMCswMDAwLDIwMTUtMDEtMTVUMjI6MDg6NTcuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAxOCwzNy4yLDIwMTUtMDEtMTAsb3JnYW5pYyxKYXBhbgoxMjAzLFpNSkxQR0NSSUtOQTQ3MSxaTUpMUEdDUklLTkE0NzEtaGk5dXI2eWIsMjAxNS0wMS0xNVQyMjo0OToyMC4wMDAwMDArMDAwMCwyMDE1LTAxLTE1VDIzOjE3OjIwLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNDUsMzkuMCwyMDE1LTAxLTEwLG9yZ2FuaWMsRWd5cHQKMTIxMCxSWVpIQUpFWE1CSUY3MjQsUllaSEFKRVhNQklGNzI0LXFwaWhtcng1LDIwMTUtMDEtMTZUMDE6MTg6MTIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNlQwMToyNTo1NC4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjA4MSwxNC4wLDIwMTUtMDEtMTUsZ29vZ2xlLFBvcnR1Z2FsCjEyMjIsSlZCWkNQS1hIRk1VNDkxLEpWQlpDUEtYSEZNVTQ5MS0yb3p1eWxrdywyMDE1LTAxLTE2VDAyOjU1OjM1LjAwMDAwMCswMDAwLDIwMTUtMDEtMTZUMDM6MjA6NTMuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA1LDM4LjIsMjAxNS0wMS0wNyxvcmdhbmljLFVuaXRlZCBTdGF0ZXMKMTIyNixYSUFIQk5LRUNHUk81OTgsWElBSEJOS0VDR1JPNTk4LTc0YXRtaXhnLDIwMTUtMDEtMTZUMDM6NDI6MzkuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNlQwMzo0NjowOS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDMsMTYuOCwyMDE1LTAxLTE0LGdvb2dsZSxFZ3lwdAoxMjI5LEJGTkxVUklTSlhUSDY0NyxCRk5MVVJJU0pYVEg2NDctZmRhc3d5cWcsMjAxNS0wMS0xNlQwMzo0NzoxNC4wMDAwMDArMDAwMCwyMDE1LTAxLTE2VDAzOjUyOjMyLjAwMDAwMCswMDAwLGFkLGFkXzIwc2VjLDAuMDg0LDEyLjEsMjAxNS0wMS0xMCxvcmdhbmljLEluZGlhCjEyMzAsQkZOTFVSSVNKWFRINjQ3LEJGTkxVUklTSlhUSDY0Ny1mZGFzd3lxZywyMDE1LTAxLTE2VDAzOjQ3OjE0LjAwMDAwMCswMDAwLDIwMTUtMDEtMTZUMDM6NTU6MDIuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAxOCwxMi4xLDIwMTUtMDEtMTAsb3JnYW5pYyxJbmRpYQoxMjM1LE9NQ1ZVQUlLU0RUUjY1MSxPTUNWVUFJS1NEVFI2NTEtcTVtNnZyNHgsMjAxNS0wMS0xNlQwNzoyODowMC4wMDAwMDArMDAwMCwyMDE1LTAxLTE2VDA3OjUwOjAwLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4xLDM2LjksMjAxNS0wMS0wNyxvdGhlcl9jYW1wYWlnbixVbml0ZWQgU3RhdGVzCjEyMzYsT01DVlVBSUtTRFRSNjUxLE9NQ1ZVQUlLU0RUUjY1MS1xNW02dnI0eCwyMDE1LTAxLTE2VDA3OjI4OjAwLjAwMDAwMCswMDAwLDIwMTUtMDEtMTZUMDc6NTM6NDguMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyLDM2LjksMjAxNS0wMS0wNyxvdGhlcl9jYW1wYWlnbixVbml0ZWQgU3RhdGVzCjEyMzcsT01DVlVBSUtTRFRSNjUxLE9NQ1ZVQUlLU0RUUjY1MS1xNW02dnI0eCwyMDE1LTAxLTE2VDA3OjI4OjAwLjAwMDAwMCswMDAwLDIwMTUtMDEtMTZUMDg6MDE6MzAuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA3LDM2LjksMjAxNS0wMS0wNyxvdGhlcl9jYW1wYWlnbixVbml0ZWQgU3RhdGVzCjEyNDMsWlBUSUhOU1ZGWUFRMTQ2LFpQVElITlNWRllBUTE0Ni1vaWwxODI2dSwyMDE1LTAxLTE2VDA3OjQ2OjQxLjAwMDAwMCswMDAwLDIwMTUtMDEtMTZUMDc6NTY6NTMuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4wOTYsMjEuOCwyMDE1LTAxLTA0LGZhY2Vib29rLE1leGljbwoxMjQ0LFpQVElITlNWRllBUTE0NixaUFRJSE5TVkZZQVExNDYtb2lsMTgyNnUsMjAxNS0wMS0xNlQwNzo0Njo0MS4wMDAwMDArMDAwMCwyMDE1LTAxLTE2VDA4OjAzOjUzLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNzIsMjEuOCwyMDE1LTAxLTA0LGZhY2Vib29rLE1leGljbwoxMjQ1LFVQRk1MSUVLV0hZWDk2NCxVUEZNTElFS1dIWVg5NjQteHJvZ21kYmssMjAxNS0wMS0xNlQwODowMzozOS4wMDAwMDArMDAwMCwyMDE1LTAxLTE2VDA4OjA4OjI3LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4xLDMzLjQsMjAxNS0wMS0xNixvcmdhbmljLEdlcm1hbnkKMTI0OCxVUEZNTElFS1dIWVg5NjQsVVBGTUxJRUtXSFlYOTY0LXhyb2dtZGJrLDIwMTUtMDEtMTZUMDg6MDM6MzkuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNlQwODoyMjoyNy4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDMsMzMuNCwyMDE1LTAxLTE2LG9yZ2FuaWMsR2VybWFueQoxMjU1LFFKR1ZPQkxBVElIVzQ1NyxRSkdWT0JMQVRJSFc0NTctdWhqN2Z4dGQsMjAxNS0wMS0xNlQwODoxNjozMy4wMDAwMDArMDAwMCwyMDE1LTAxLTE2VDA4OjI1OjIxLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMzMsMjkuNCwyMDE1LTAxLTAyLG90aGVyX2NhbXBhaWduLFN3ZWRlbgoxMjU2LFFKR1ZPQkxBVElIVzQ1NyxRSkdWT0JMQVRJSFc0NTctdWhqN2Z4dGQsMjAxNS0wMS0xNlQwODoxNjozMy4wMDAwMDArMDAwMCwyMDE1LTAxLTE2VDA4OjI5OjQ1LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMjIsMjkuNCwyMDE1LTAxLTAyLG90aGVyX2NhbXBhaWduLFN3ZWRlbgoxMjU3LFFKR1ZPQkxBVElIVzQ1NyxRSkdWT0JMQVRJSFc0NTctdWhqN2Z4dGQsMjAxNS0wMS0xNlQwODoxNjozMy4wMDAwMDArMDAwMCwyMDE1LTAxLTE2VDA4OjMyOjI3LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wODgsMjkuNCwyMDE1LTAxLTAyLG90aGVyX2NhbXBhaWduLFN3ZWRlbgoxMjY0LFJNT1NXSEpHRUxDSTY3NSxSTU9TV0hKR0VMQ0k2NzUtb2lic3luNGYsMjAxNS0wMS0xNlQwOTozMTo0Mi4wMDAwMDArMDAwMCwyMDE1LTAxLTE2VDA5OjMyOjU0LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wOSwxNi42LDIwMTUtMDEtMTAsb3RoZXJfY2FtcGFpZ24sRnJhbmNlCjEyNjcsTkFPSlJETUNTRUJJMjgxLE5BT0pSRE1DU0VCSTI4MS1ud2Z2ZDRtbywyMDE1LTAxLTE2VDEwOjAwOjEyLjAwMDAwMCswMDAwLDIwMTUtMDEtMTZUMTA6MDA6MzAuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAzNiwxNS40LDIwMTUtMDEtMTEsb3JnYW5pYyxOb3J3YXkKMTI2OSxOQU9KUkRNQ1NFQkkyODEsTkFPSlJETUNTRUJJMjgxLW53ZnZkNG1vLDIwMTUtMDEtMTZUMTA6MDA6MTIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNlQxMDowNDozNi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDI3LDE1LjQsMjAxNS0wMS0xMSxvcmdhbmljLE5vcndheQoxMjc2LE1ZUUdKS09VSVdIRjYxOSxNWVFHSktPVUlXSEY2MTktOW82cDVnaWEsMjAxNS0wMS0xNlQxMDoyMzoxNS4wMDAwMDArMDAwMCwyMDE1LTAxLTE2VDEwOjI5OjIxLjAwMDAwMCswMDAwLGFkLGFkXzE1c2VjLDAuMDc4LDE3LjQsMjAxNS0wMS0xNixvcmdhbmljLEluZGlhCjEyNzcsR0pDWE5UV0VCSVBRMzY5LEdKQ1hOVFdFQklQUTM2OS00cWd0YmhmYywyMDE1LTAxLTE2VDExOjE3OjE0LjAwMDAwMCswMDAwLDIwMTUtMDEtMTZUMTE6MzA6NTYuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyLDI2LjQsMjAxNS0wMS0xNCxvcmdhbmljLFVuaXRlZCBTdGF0ZXMKMTI3OCxHSkNYTlRXRUJJUFEzNjksR0pDWE5UV0VCSVBRMzY5LTRxZ3RiaGZjLDIwMTUtMDEtMTZUMTE6MTc6MTQuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNlQxMTozMTowOC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDQsMjYuNCwyMDE1LTAxLTE0LG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwoxMjgyLEdKQ1hOVFdFQklQUTM2OSxHSkNYTlRXRUJJUFEzNjktNHFndGJoZmMsMjAxNS0wMS0xNlQxMToxNzoxNC4wMDAwMDArMDAwMCwyMDE1LTAxLTE2VDExOjQxOjI2LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4xLDI2LjQsMjAxNS0wMS0xNCxvcmdhbmljLFVuaXRlZCBTdGF0ZXMKMTI4NyxNVENJV0tPVkFTWVA5MjUsTVRDSVdLT1ZBU1lQOTI1LWhzNGk1MnZnLDIwMTUtMDEtMTZUMTI6MjI6MjMuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNlQxMjozMDozNS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMSw0MS4wLDIwMTUtMDEtMTQsb3JnYW5pYyxHZXJtYW55CjEyODksTVRDSVdLT1ZBU1lQOTI1LE1UQ0lXS09WQVNZUDkyNS1oczRpNTJ2ZywyMDE1LTAxLTE2VDEyOjIyOjIzLjAwMDAwMCswMDAwLDIwMTUtMDEtMTZUMTI6NDg6MjMuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjEsNDEuMCwyMDE1LTAxLTE0LG9yZ2FuaWMsR2VybWFueQoxMjkyLFpQVElITlNWRllBUTE0NixaUFRJSE5TVkZZQVExNDYtdThjNG5xNzUsMjAxNS0wMS0xNlQxMjoyMzo1OS4wMDAwMDArMDAwMCwyMDE1LTAxLTE2VDEyOjMxOjIzLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNzIsMTAuMiwyMDE1LTAxLTA0LGZhY2Vib29rLE1leGljbwoxMjk0LFBMUUVTQk5HVURLSjE1NCxQTFFFU0JOR1VES0oxNTQtOHB2dGFsNm4sMjAxNS0wMS0xNlQxMjozNjozOC4wMDAwMDArMDAwMCwyMDE1LTAxLTE2VDEyOjQ2OjAyLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNDIsMzIuNiwyMDE1LTAxLTEyLGZhY2Vib29rLEphcGFuCjEzMDIsV0VQS1lOUlhERlVUNTcyLFdFUEtZTlJYREZVVDU3Mi1haDhiNms5NSwyMDE1LTAxLTE2VDEzOjExOjI2LjAwMDAwMCswMDAwLDIwMTUtMDEtMTZUMTM6MTg6MjAuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA3MiwxMi45LDIwMTUtMDEtMTMsY3Jvc3Nwcm9tbyxDaGluYQoxMzAzLEdKQ1hOVFdFQklQUTM2OSxHSkNYTlRXRUJJUFEzNjktazdweG00NTEsMjAxNS0wMS0xNlQxMzoxOToxMC4wMDAwMDArMDAwMCwyMDE1LTAxLTE2VDEzOjI2OjIyLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNCwzMy40LDIwMTUtMDEtMTQsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjEzMDYsT01DVlVBSUtTRFRSNjUxLE9NQ1ZVQUlLU0RUUjY1MS1xYjRwM3JmdiwyMDE1LTAxLTE2VDEzOjI4OjU2LjAwMDAwMCswMDAwLDIwMTUtMDEtMTZUMTM6Mjk6MzIuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA1LDQwLjQsMjAxNS0wMS0wNyxvdGhlcl9jYW1wYWlnbixVbml0ZWQgU3RhdGVzCjEzMDcsT01DVlVBSUtTRFRSNjUxLE9NQ1ZVQUlLU0RUUjY1MS1xYjRwM3JmdiwyMDE1LTAxLTE2VDEzOjI4OjU2LjAwMDAwMCswMDAwLDIwMTUtMDEtMTZUMTM6NTE6MDIuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA4LDQwLjQsMjAxNS0wMS0wNyxvdGhlcl9jYW1wYWlnbixVbml0ZWQgU3RhdGVzCjEzMTQsR0FZSUJMVUNPRURKNzMyLEdBWUlCTFVDT0VESjczMi05dmEyNHV6ZCwyMDE1LTAxLTE2VDEzOjM1OjE0LjAwMDAwMCswMDAwLDIwMTUtMDEtMTZUMTQ6MDA6NDQuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA0LDI2LjgsMjAxNS0wMS0wMyxvcmdhbmljLFVuaXRlZCBTdGF0ZXMKMTMxNSxQSk9UQk5IWExGUlEyNjUsUEpPVEJOSFhMRlJRMjY1LWJjOWlsaDR3LDIwMTUtMDEtMTZUMTQ6NDc6MzkuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNlQxNDo1Mzo1MS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMSw0MC4wLDIwMTUtMDEtMTYsb3JnYW5pYyxBdXN0cmlhCjEzMTYsUEpPVEJOSFhMRlJRMjY1LFBKT1RCTkhYTEZSUTI2NS1iYzlpbGg0dywyMDE1LTAxLTE2VDE0OjQ3OjM5LjAwMDAwMCswMDAwLDIwMTUtMDEtMTZUMTQ6NTU6MzkuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA3LDQwLjAsMjAxNS0wMS0xNixvcmdhbmljLEF1c3RyaWEKMTMyMSxHSkNYTlRXRUJJUFEzNjksR0pDWE5UV0VCSVBRMzY5LTZidmM1Z3FkLDIwMTUtMDEtMTZUMTU6MzI6MzQuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNlQxNTozMjo1Mi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDIsNS4xLDIwMTUtMDEtMTQsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjEzMjQsUFpCTlJLU01VTEhYMjEzLFBaQk5SS1NNVUxIWDIxMy1vNnh5dXZoOCwyMDE1LTAxLTE2VDE2OjI5OjEwLjAwMDAwMCswMDAwLDIwMTUtMDEtMTZUMTY6MzM6NTguMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyLDE4LjUsMjAxNS0wMS0wNyxvcmdhbmljLEluZGlhCjEzMjUsUFpCTlJLU01VTEhYMjEzLFBaQk5SS1NNVUxIWDIxMy1vNnh5dXZoOCwyMDE1LTAxLTE2VDE2OjI5OjEwLjAwMDAwMCswMDAwLDIwMTUtMDEtMTZUMTY6MzQ6MzQuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAxNiwxOC41LDIwMTUtMDEtMDcsb3JnYW5pYyxJbmRpYQoxMzI4LEtHWkNPSkhQRlRRVjc1MyxLR1pDT0pIUEZUUVY3NTMtd2gzc2U1NjcsMjAxNS0wMS0xNlQxNzozNzoyOC4wMDAwMDArMDAwMCwyMDE1LTAxLTE2VDE3OjU4OjIyLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4xLDM3LjAsMjAxNS0wMS0xMSxvcmdhbmljLFVuaXRlZCBTdGF0ZXMKMTMzNCxIRFNBTVBUT0xCV0M0MzgsSERTQU1QVE9MQldDNDM4LXg2OXRuenJ2LDIwMTUtMDEtMTZUMTk6NDI6MjIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNlQxOTo0OTo0Ni4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDk2LDE1LjksMjAxNS0wMS0xNCxvcmdhbmljLFN3aXR6ZXJsYW5kCjEzNDEsWElBSEJOS0VDR1JPNTk4LFhJQUhCTktFQ0dSTzU5OC1scGk4MnVyaywyMDE1LTAxLTE2VDIwOjM4OjIwLjAwMDAwMCswMDAwLDIwMTUtMDEtMTZUMjA6NTQ6MDguMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyLDQxLjAsMjAxNS0wMS0xNCxnb29nbGUsRWd5cHQKMTM0MyxYSUFIQk5LRUNHUk81OTgsWElBSEJOS0VDR1JPNTk4LWxwaTgydXJrLDIwMTUtMDEtMTZUMjA6Mzg6MjAuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNlQyMTowMjozMi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDIsNDEuMCwyMDE1LTAxLTE0LGdvb2dsZSxFZ3lwdAoxMzQ0LFhJQUhCTktFQ0dSTzU5OCxYSUFIQk5LRUNHUk81OTgtbHBpODJ1cmssMjAxNS0wMS0xNlQyMDozODoyMC4wMDAwMDArMDAwMCwyMDE1LTAxLTE2VDIxOjA3OjQ0LjAwMDAwMCswMDAwLGFkLGFkXzE1c2VjLDAuMDksNDEuMCwyMDE1LTAxLTE0LGdvb2dsZSxFZ3lwdAoxMzQ3LEdBWUlCTFVDT0VESjczMixHQVlJQkxVQ09FREo3MzItZWw1ajM0eHQsMjAxNS0wMS0xNlQyMDo1NjozOS4wMDAwMDArMDAwMCwyMDE1LTAxLTE2VDIxOjA0OjAzLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNywyNS41LDIwMTUtMDEtMDMsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjEzNTEsR0FZSUJMVUNPRURKNzMyLEdBWUlCTFVDT0VESjczMi1lbDVqMzR4dCwyMDE1LTAxLTE2VDIwOjU2OjM5LjAwMDAwMCswMDAwLDIwMTUtMDEtMTZUMjE6MTA6MzMuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjEsMjUuNSwyMDE1LTAxLTAzLG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwoxMzUyLE5BT0pSRE1DU0VCSTI4MSxOQU9KUkRNQ1NFQkkyODEtMW1zeXQ5MmssMjAxNS0wMS0xNlQyMTo1ODo1MC4wMDAwMDArMDAwMCwyMDE1LTAxLTE2VDIyOjA5OjQ0LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNDUsMTUuNSwyMDE1LTAxLTExLG9yZ2FuaWMsTm9yd2F5CjEzNTcsUEpPVEJOSFhMRlJRMjY1LFBKT1RCTkhYTEZSUTI2NS13bXV0cmsyaCwyMDE1LTAxLTE2VDIyOjA2OjIxLjAwMDAwMCswMDAwLDIwMTUtMDEtMTZUMjI6MzI6NTcuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyLDI2LjcsMjAxNS0wMS0xNixvcmdhbmljLEF1c3RyaWEKMTM2MixRTkxWUkRFT1hGWUo4OTIsUU5MVlJERU9YRllKODkyLXJiZnNocDhpLDIwMTUtMDEtMTZUMjM6Mjc6MDUuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNlQyMzo1MzowNS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDksMjcuNCwyMDE1LTAxLTA5LGNyb3NzcHJvbW8sQXVzdHJhbGlhCjEzNjUsSllFQkNMTlVaVFhRNDU3LEpZRUJDTE5VWlRYUTQ1Ny11bHZqa3doOCwyMDE1LTAxLTE2VDIzOjQ2OjE1LjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMDA6MTM6MjEuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4wNiwzNy43LDIwMTUtMDEtMDQsb3RoZXJfY2FtcGFpZ24sRWd5cHQKMTM2OCxETFRGVlFXWUlYUko1ODksRExURlZRV1lJWFJKNTg5LXkzdnNycWxiLDIwMTUtMDEtMTdUMDE6MzA6MTcuMDAwMDAwKzAwMDAsMjAxNS0wMS0xN1QwMTo0MDo1OS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDIxOTgsMzcuMiwyMDE1LTAxLTEzLG9yZ2FuaWMsU291dGggQWZyaWNhCjEzNzYsWkdFVlFKU0tGSUJYMzk4LFpHRVZRSlNLRklCWDM5OC1sd3V5MXhhdiwyMDE1LTAxLTE3VDAxOjU5OjE5LjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMDI6MDM6NDkuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4wOTgsMzMuNiwyMDE1LTAxLTE3LG9yZ2FuaWMsU291dGggS29yZWEKMTM3NyxaR0VWUUpTS0ZJQlgzOTgsWkdFVlFKU0tGSUJYMzk4LWx3dXkxeGF2LDIwMTUtMDEtMTdUMDE6NTk6MTkuMDAwMDAwKzAwMDAsMjAxNS0wMS0xN1QwMjoyMTo1NS4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjA3NywzMy42LDIwMTUtMDEtMTcsb3JnYW5pYyxTb3V0aCBLb3JlYQoxNDAwLFhJQUhCTktFQ0dSTzU5OCxYSUFIQk5LRUNHUk81OTgtZ3J2dTFwNmYsMjAxNS0wMS0xN1QwMzozODozNi4wMDAwMDArMDAwMCwyMDE1LTAxLTE3VDAzOjQyOjEyLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNTUsMTEuMiwyMDE1LTAxLTE0LGdvb2dsZSxFZ3lwdAoxNDA0LFBaQk5SS1NNVUxIWDIxMyxQWkJOUktTTVVMSFgyMTMtMTcyOHFmZG4sMjAxNS0wMS0xN1QwMzozODo0Ni4wMDAwMDArMDAwMCwyMDE1LTAxLTE3VDAzOjQ5OjIyLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMiwyMi41LDIwMTUtMDEtMDcsb3JnYW5pYyxJbmRpYQoxNDA1LFBaQk5SS1NNVUxIWDIxMyxQWkJOUktTTVVMSFgyMTMtMTcyOHFmZG4sMjAxNS0wMS0xN1QwMzozODo0Ni4wMDAwMDArMDAwMCwyMDE1LTAxLTE3VDAzOjUzOjQwLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMjQsMjIuNSwyMDE1LTAxLTA3LG9yZ2FuaWMsSW5kaWEKMTQwNixNWVFHSktPVUlXSEY2MTksTVlRR0pLT1VJV0hGNjE5LTVobnRtaXd5LDIwMTUtMDEtMTdUMDQ6MDM6MTMuMDAwMDAwKzAwMDAsMjAxNS0wMS0xN1QwNDowODoxMy4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDI0LDguMywyMDE1LTAxLTE2LG9yZ2FuaWMsSW5kaWEKMTQwOSxKWUVCQ0xOVVpUWFE0NTcsSllFQkNMTlVaVFhRNDU3LWRtdmt5Mm5oLDIwMTUtMDEtMTdUMDU6MzY6MzcuMDAwMDAwKzAwMDAsMjAxNS0wMS0xN1QwNTo0MjowMS4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjAzNSwxMi40LDIwMTUtMDEtMDQsb3RoZXJfY2FtcGFpZ24sRWd5cHQKMTQxMCxNWVFHSktPVUlXSEY2MTksTVlRR0pLT1VJV0hGNjE5LXRsd2NzeTc2LDIwMTUtMDEtMTdUMDY6MjM6NTguMDAwMDAwKzAwMDAsMjAxNS0wMS0xN1QwNjoyNDoxMC4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjAyOCwxMi4zLDIwMTUtMDEtMTYsb3JnYW5pYyxJbmRpYQoxNDExLE1ZUUdKS09VSVdIRjYxOSxNWVFHSktPVUlXSEY2MTktdGx3Y3N5NzYsMjAxNS0wMS0xN1QwNjoyMzo1OC4wMDAwMDArMDAwMCwyMDE1LTAxLTE3VDA2OjI5OjA0LjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDE0LDEyLjMsMjAxNS0wMS0xNixvcmdhbmljLEluZGlhCjE0MTMsUEpPVEJOSFhMRlJRMjY1LFBKT1RCTkhYTEZSUTI2NS11YXFkeTVldCwyMDE1LTAxLTE3VDA2OjM0OjEyLjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMDY6NDI6MDYuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA4LDIxLjUsMjAxNS0wMS0xNixvcmdhbmljLEF1c3RyaWEKMTQyMCxFS0lIWEJSRkdPQ0Q1NzEsRUtJSFhCUkZHT0NENTcxLW41a2UyYWw3LDIwMTUtMDEtMTdUMDg6MTY6MTYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xN1QwODoxNjo1OC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDgsMzcuMiwyMDE1LTAxLTE3LGFwcGxlLFVuaXRlZCBLaW5nZG9tCjE0MjYsV0JLRllKWENaTlVINTYzLFdCS0ZZSlhDWk5VSDU2My1sbWpudTcxZywyMDE1LTAxLTE3VDA4OjMzOjAwLjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMDg6NDY6NDIuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA1LDE0LjYsMjAxNS0wMS0xMyxvcmdhbmljLENhbmFkYQoxNDM0LEJGTkxVUklTSlhUSDY0NyxCRk5MVVJJU0pYVEg2NDctcWp1Z3BmMm4sMjAxNS0wMS0xN1QwOTo1ODoxOC4wMDAwMDArMDAwMCwyMDE1LTAxLTE3VDA5OjU5OjA2LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMTgsMjkuOCwyMDE1LTAxLTEwLG9yZ2FuaWMsSW5kaWEKMTQzNSxCRk5MVVJJU0pYVEg2NDcsQkZOTFVSSVNKWFRINjQ3LXFqdWdwZjJuLDIwMTUtMDEtMTdUMDk6NTg6MTguMDAwMDAwKzAwMDAsMjAxNS0wMS0xN1QxMDowNTowMC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDE4LDI5LjgsMjAxNS0wMS0xMCxvcmdhbmljLEluZGlhCjE0MzYsQkZOTFVSSVNKWFRINjQ3LEJGTkxVUklTSlhUSDY0Ny1xanVncGYybiwyMDE1LTAxLTE3VDA5OjU4OjE4LjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMTA6MTU6NDguMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyLDI5LjgsMjAxNS0wMS0xMCxvcmdhbmljLEluZGlhCjE0MzgsQkZOTFVSSVNKWFRINjQ3LEJGTkxVUklTSlhUSDY0Ny1xanVncGYybiwyMDE1LTAxLTE3VDA5OjU4OjE4LjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMTA6MjU6MDYuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAwNiwyOS44LDIwMTUtMDEtMTAsb3JnYW5pYyxJbmRpYQoxNDQ0LFhJQUhCTktFQ0dSTzU5OCxYSUFIQk5LRUNHUk81OTgtcW84cm16aWosMjAxNS0wMS0xN1QxMDo0MzoyOC4wMDAwMDArMDAwMCwyMDE1LTAxLTE3VDEwOjU4OjM0LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMywyOC44LDIwMTUtMDEtMTQsZ29vZ2xlLEVneXB0CjE0NDUsWElBSEJOS0VDR1JPNTk4LFhJQUhCTktFQ0dSTzU5OC1xbzhybXppaiwyMDE1LTAxLTE3VDEwOjQzOjI4LjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMTE6MDE6MDQuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAxNSwyOC44LDIwMTUtMDEtMTQsZ29vZ2xlLEVneXB0CjE0NDcsWElBSEJOS0VDR1JPNTk4LFhJQUhCTktFQ0dSTzU5OC1xbzhybXppaiwyMDE1LTAxLTE3VDEwOjQzOjI4LjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMTE6MDg6NTguMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA1LDI4LjgsMjAxNS0wMS0xNCxnb29nbGUsRWd5cHQKMTQ2MSxNVENJV0tPVkFTWVA5MjUsTVRDSVdLT1ZBU1lQOTI1LW51OWR3M2JvLDIwMTUtMDEtMTdUMTI6MDM6MjcuMDAwMDAwKzAwMDAsMjAxNS0wMS0xN1QxMjoyNjowOS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDcsMzAuMCwyMDE1LTAxLTE0LG9yZ2FuaWMsR2VybWFueQoxNDY0LE1UQ0lXS09WQVNZUDkyNSxNVENJV0tPVkFTWVA5MjUtbnU5ZHczYm8sMjAxNS0wMS0xN1QxMjowMzoyNy4wMDAwMDArMDAwMCwyMDE1LTAxLTE3VDEyOjMxOjAzLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMywzMC4wLDIwMTUtMDEtMTQsb3JnYW5pYyxHZXJtYW55CjE0NzYsRUtJSFhCUkZHT0NENTcxLEVLSUhYQlJGR09DRDU3MS02bDFkNXhqcSwyMDE1LTAxLTE3VDEyOjU5OjI0LjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMTM6MDE6MjQuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4wOSwzMy41LDIwMTUtMDEtMTcsYXBwbGUsVW5pdGVkIEtpbmdkb20KMTQ3NyxFS0lIWEJSRkdPQ0Q1NzEsRUtJSFhCUkZHT0NENTcxLTZsMWQ1eGpxLDIwMTUtMDEtMTdUMTI6NTk6MjQuMDAwMDAwKzAwMDAsMjAxNS0wMS0xN1QxMzowMjo0Mi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDYsMzMuNSwyMDE1LTAxLTE3LGFwcGxlLFVuaXRlZCBLaW5nZG9tCjE0NzgsRUtJSFhCUkZHT0NENTcxLEVLSUhYQlJGR09DRDU3MS02bDFkNXhqcSwyMDE1LTAxLTE3VDEyOjU5OjI0LjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMTM6MTk6MTIuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjEsMzMuNSwyMDE1LTAxLTE3LGFwcGxlLFVuaXRlZCBLaW5nZG9tCjE0ODEsVVBGTUxJRUtXSFlYOTY0LFVQRk1MSUVLV0hZWDk2NC0ycW9tOG5leSwyMDE1LTAxLTE3VDE0OjUyOjA5LjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMTQ6NTc6MDkuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAzLDE4LjAsMjAxNS0wMS0xNixvcmdhbmljLEdlcm1hbnkKMTQ4OSxJQ0JBVVpLR1NRUEYxNDUsSUNCQVVaS0dTUVBGMTQ1LWg5dWtuMWZ4LDIwMTUtMDEtMTdUMTY6MDg6NTcuMDAwMDAwKzAwMDAsMjAxNS0wMS0xN1QxNjozMjo0NS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDM0LDI2LjUsMjAxNS0wMS0wNixnb29nbGUsU291dGggQWZyaWNhCjE0OTcsRkdLWFBOSVJKSENZNjI1LEZHS1hQTklSSkhDWTYyNS1vdnd0amh1cywyMDE1LTAxLTE3VDE3OjAwOjMzLjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMTc6MzQ6NDUuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA4LDM3LjksMjAxNS0wMS0xNyxjcm9zc3Byb21vLEhvbmcgS29uZwoxNDk5LElDQkFVWktHU1FQRjE0NSxJQ0JBVVpLR1NRUEYxNDUtOGozb3lzdDQsMjAxNS0wMS0xN1QxNzozODoxNy4wMDAwMDArMDAwMCwyMDE1LTAxLTE3VDE3OjQ2OjIzLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMzQsMTUuOCwyMDE1LTAxLTA2LGdvb2dsZSxTb3V0aCBBZnJpY2EKMTUwMixaUFRJSE5TVkZZQVExNDYsWlBUSUhOU1ZGWUFRMTQ2LW45cGw0MjdzLDIwMTUtMDEtMTdUMTg6Mjg6MjUuMDAwMDAwKzAwMDAsMjAxNS0wMS0xN1QxODozNjo0OS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDcyLDE4LjgsMjAxNS0wMS0wNCxmYWNlYm9vayxNZXhpY28KMTUwNSxaTUpMUEdDUklLTkE0NzEsWk1KTFBHQ1JJS05BNDcxLWN1Njd6aDV0LDIwMTUtMDEtMTdUMTk6MTA6MTYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xN1QxOToxMTo0Ni4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjA4LDMyLjAsMjAxNS0wMS0xMCxvcmdhbmljLEVneXB0CjE1MDcsWk1KTFBHQ1JJS05BNDcxLFpNSkxQR0NSSUtOQTQ3MS1jdTY3emg1dCwyMDE1LTAxLTE3VDE5OjEwOjE2LjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMTk6MzA6MDQuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA1LDMyLjAsMjAxNS0wMS0xMCxvcmdhbmljLEVneXB0CjE1MDksTVRDSVdLT1ZBU1lQOTI1LE1UQ0lXS09WQVNZUDkyNS01d3YzdGEybywyMDE1LTAxLTE3VDE5OjE2OjE5LjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMTk6Mjg6NDkuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA5LDE2LjIsMjAxNS0wMS0xNCxvcmdhbmljLEdlcm1hbnkKMTUxMCxXQktGWUpYQ1pOVUg1NjMsV0JLRllKWENaTlVINTYzLWNqODRnN3NhLDIwMTUtMDEtMTdUMTk6MTY6NTIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xN1QxOToxNzo0Ni4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDQsMjYuNSwyMDE1LTAxLTEzLG9yZ2FuaWMsQ2FuYWRhCjE1MTIsV0JLRllKWENaTlVINTYzLFdCS0ZZSlhDWk5VSDU2My1jajg0ZzdzYSwyMDE1LTAxLTE3VDE5OjE2OjUyLjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMTk6MjA6NDAuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA4LDI2LjUsMjAxNS0wMS0xMyxvcmdhbmljLENhbmFkYQoxNTE5LFZMT1NDS1laQkVUSjY4NCxWTE9TQ0tZWkJFVEo2ODQtejR2NnI3d3UsMjAxNS0wMS0xN1QyMTozMjowNy4wMDAwMDArMDAwMCwyMDE1LTAxLTE3VDIxOjQ3OjE5LjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMSw0MC4yLDIwMTUtMDEtMTcsb3JnYW5pYyxGcmFuY2UKMTUyNSxKVkJaQ1BLWEhGTVU0OTEsSlZCWkNQS1hIRk1VNDkxLXd2dDQxa3hjLDIwMTUtMDEtMTdUMjI6NDE6MjkuMDAwMDAwKzAwMDAsMjAxNS0wMS0xN1QyMzowNjoyMy4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDUsMzQuOSwyMDE1LTAxLTA3LG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwoxNTI2LEpWQlpDUEtYSEZNVTQ5MSxKVkJaQ1BLWEhGTVU0OTEtd3Z0NDFreGMsMjAxNS0wMS0xN1QyMjo0MToyOS4wMDAwMDArMDAwMCwyMDE1LTAxLTE3VDIzOjA5OjA1LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wOCwzNC45LDIwMTUtMDEtMDcsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjE1MjksUFpCTlJLU01VTEhYMjEzLFBaQk5SS1NNVUxIWDIxMy1yaGNhbXp0ZiwyMDE1LTAxLTE3VDIzOjA1OjE2LjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMjM6MDk6MjIuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAxOCwxNi4xLDIwMTUtMDEtMDcsb3JnYW5pYyxJbmRpYQoxNTMwLFBaQk5SS1NNVUxIWDIxMyxQWkJOUktTTVVMSFgyMTMtcmhjYW16dGYsMjAxNS0wMS0xN1QyMzowNToxNi4wMDAwMDArMDAwMCwyMDE1LTAxLTE3VDIzOjExOjM0LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMDgsMTYuMSwyMDE1LTAxLTA3LG9yZ2FuaWMsSW5kaWEKMTUzMyxQWkJOUktTTVVMSFgyMTMsUFpCTlJLU01VTEhYMjEzLXJoY2FtenRmLDIwMTUtMDEtMTdUMjM6MDU6MTYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xN1QyMzoxOTo1Mi4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjAxNiwxNi4xLDIwMTUtMDEtMDcsb3JnYW5pYyxJbmRpYQoxNTM0LFhJQUhCTktFQ0dSTzU5OCxYSUFIQk5LRUNHUk81OTgtaWN5YTFtN3QsMjAxNS0wMS0xN1QyMzozMTo1Ny4wMDAwMDArMDAwMCwyMDE1LTAxLTE3VDIzOjM4OjM5LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNDUsMTUuMywyMDE1LTAxLTE0LGdvb2dsZSxFZ3lwdAoxNTM1LFhJQUhCTktFQ0dSTzU5OCxYSUFIQk5LRUNHUk81OTgtaWN5YTFtN3QsMjAxNS0wMS0xN1QyMzozMTo1Ny4wMDAwMDArMDAwMCwyMDE1LTAxLTE3VDIzOjQ2OjE1LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMjUsMTUuMywyMDE1LTAxLTE0LGdvb2dsZSxFZ3lwdAoxNTM5LEdBWUlCTFVDT0VESjczMixHQVlJQkxVQ09FREo3MzItMXJwaHFkd3osMjAxNS0wMS0xOFQwMDozNDoyOC4wMDAwMDArMDAwMCwyMDE1LTAxLTE4VDAwOjUyOjM0LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4xLDI4LjUsMjAxNS0wMS0wMyxvcmdhbmljLFVuaXRlZCBTdGF0ZXMKMTU0OCxQSk9UQk5IWExGUlEyNjUsUEpPVEJOSFhMRlJRMjY1LTk1dHN5bGkzLDIwMTUtMDEtMThUMDI6MDI6MzIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOFQwMjo0MToxNC4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjA3LDQwLjcsMjAxNS0wMS0xNixvcmdhbmljLEF1c3RyaWEKMTU1MCxXQktGWUpYQ1pOVUg1NjMsV0JLRllKWENaTlVINTYzLXEyZjlnaXlkLDIwMTUtMDEtMThUMDI6NTQ6NTAuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOFQwMjo1OTozOC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDYsMTYuMiwyMDE1LTAxLTEzLG9yZ2FuaWMsQ2FuYWRhCjE1NTMsV0JLRllKWENaTlVINTYzLFdCS0ZZSlhDWk5VSDU2My1xMmY5Z2l5ZCwyMDE1LTAxLTE4VDAyOjU0OjUwLjAwMDAwMCswMDAwLDIwMTUtMDEtMThUMDM6MDM6MDIuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA1LDE2LjIsMjAxNS0wMS0xMyxvcmdhbmljLENhbmFkYQoxNTU1LFdFUEtZTlJYREZVVDU3MixXRVBLWU5SWERGVVQ1NzItbTVqd3ZpdHMsMjAxNS0wMS0xOFQwMzowMzo1OS4wMDAwMDArMDAwMCwyMDE1LTAxLTE4VDAzOjA3OjM1LjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDg0LDMxLjAsMjAxNS0wMS0xMyxjcm9zc3Byb21vLENoaW5hCjE1NTcsV0VQS1lOUlhERlVUNTcyLFdFUEtZTlJYREZVVDU3Mi1tNWp3dml0cywyMDE1LTAxLTE4VDAzOjAzOjU5LjAwMDAwMCswMDAwLDIwMTUtMDEtMThUMDM6MTY6MTcuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4wNzgsMzEuMCwyMDE1LTAxLTEzLGNyb3NzcHJvbW8sQ2hpbmEKMTU1OCxXRVBLWU5SWERGVVQ1NzIsV0VQS1lOUlhERlVUNTcyLW01and2aXRzLDIwMTUtMDEtMThUMDM6MDM6NTkuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOFQwMzoxNjo0MS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDcyLDMxLjAsMjAxNS0wMS0xMyxjcm9zc3Byb21vLENoaW5hCjE1NjEsS0daQ09KSFBGVFFWNzUzLEtHWkNPSkhQRlRRVjc1My1kYnFqM2s4cCwyMDE1LTAxLTE4VDAzOjQxOjU2LjAwMDAwMCswMDAwLDIwMTUtMDEtMThUMDM6NTA6MzguMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA0LDIzLjIsMjAxNS0wMS0xMSxvcmdhbmljLFVuaXRlZCBTdGF0ZXMKMTU2NCxLR1pDT0pIUEZUUVY3NTMsS0daQ09KSFBGVFFWNzUzLWRicWozazhwLDIwMTUtMDEtMThUMDM6NDE6NTYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOFQwNDowMzoyMC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDcsMjMuMiwyMDE1LTAxLTExLG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwoxNTY5LFBKT1RCTkhYTEZSUTI2NSxQSk9UQk5IWExGUlEyNjUtbWlwOHZvMmIsMjAxNS0wMS0xOFQwNDoyNjo0NS4wMDAwMDArMDAwMCwyMDE1LTAxLTE4VDA0OjU0OjI3LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wOCwzNi40LDIwMTUtMDEtMTYsb3JnYW5pYyxBdXN0cmlhCjE1NzIsR0pDWE5UV0VCSVBRMzY5LEdKQ1hOVFdFQklQUTM2OS1hY3Mzd2ZuaywyMDE1LTAxLTE4VDA1OjAwOjAzLjAwMDAwMCswMDAwLDIwMTUtMDEtMThUMDU6MDQ6MzMuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA5LDMzLjMsMjAxNS0wMS0xNCxvcmdhbmljLFVuaXRlZCBTdGF0ZXMKMTU4MixOUE1KSVlIRVRHS1cyOTcsTlBNSklZSEVUR0tXMjk3LXRuaTc4dTllLDIwMTUtMDEtMThUMDU6MjQ6MTguMDAwMDAwKzAwMDAsMjAxNS0wMS0xOFQwNTozODowNi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDIsMTQuMywyMDE1LTAxLTE4LGdvb2dsZSxQaGlsaXBwaW5lcwoxNTkxLFpQVElITlNWRllBUTE0NixaUFRJSE5TVkZZQVExNDYtZmwyOG52Z2MsMjAxNS0wMS0xOFQwNjo0NjowMS4wMDAwMDArMDAwMCwyMDE1LTAxLTE4VDA2OjU3OjEzLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMzYsMjMuOSwyMDE1LTAxLTA0LGZhY2Vib29rLE1leGljbwoxNTkyLFpQVElITlNWRllBUTE0NixaUFRJSE5TVkZZQVExNDYtZmwyOG52Z2MsMjAxNS0wMS0xOFQwNjo0NjowMS4wMDAwMDArMDAwMCwyMDE1LTAxLTE4VDA3OjAwOjU1LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNDgsMjMuOSwyMDE1LTAxLTA0LGZhY2Vib29rLE1leGljbwoxNTk1LEtJTFdaWUhSU0pFRzMxNixLSUxXWllIUlNKRUczMTYteTc4MjRlbmQsMjAxNS0wMS0xOFQwODozODo0Mi4wMDAwMDArMDAwMCwyMDE1LTAxLTE4VDA4OjM5OjEyLjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDk5LDI2LjUsMjAxNS0wMS0wNCxvcmdhbmljLERlbm1hcmsKMTU5OSxSTU9TV0hKR0VMQ0k2NzUsUk1PU1dISkdFTENJNjc1LTh2ZzloNmxtLDIwMTUtMDEtMThUMDg6NTY6MTguMDAwMDAwKzAwMDAsMjAxNS0wMS0xOFQwODo1Njo1NC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDksMzEuOSwyMDE1LTAxLTEwLG90aGVyX2NhbXBhaWduLEZyYW5jZQoxNjA0LERMVEZWUVdZSVhSSjU4OSxETFRGVlFXWUlYUko1ODktNmdqaHl2ZDcsMjAxNS0wMS0xOFQwOTowMDozNi4wMDAwMDArMDAwMCwyMDE1LTAxLTE4VDA5OjEzOjI0LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNzcsMzcuNSwyMDE1LTAxLTEzLG9yZ2FuaWMsU291dGggQWZyaWNhCjE2MDYsRExURlZRV1lJWFJKNTg5LERMVEZWUVdZSVhSSjU4OS02Z2poeXZkNywyMDE1LTAxLTE4VDA5OjAwOjM2LjAwMDAwMCswMDAwLDIwMTUtMDEtMThUMDk6Mzc6MDAuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA3NywzNy41LDIwMTUtMDEtMTMsb3JnYW5pYyxTb3V0aCBBZnJpY2EKMTYwOCxKWUVCQ0xOVVpUWFE0NTcsSllFQkNMTlVaVFhRNDU3LWo3c252bzhpLDIwMTUtMDEtMThUMDk6MTM6MDIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOFQwOToxOTowOC4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjA3LDE4LjgsMjAxNS0wMS0wNCxvdGhlcl9jYW1wYWlnbixFZ3lwdAoxNjA5LEpZRUJDTE5VWlRYUTQ1NyxKWUVCQ0xOVVpUWFE0NTctajdzbnZvOGksMjAxNS0wMS0xOFQwOToxMzowMi4wMDAwMDArMDAwMCwyMDE1LTAxLTE4VDA5OjIzOjU2LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNDUsMTguOCwyMDE1LTAxLTA0LG90aGVyX2NhbXBhaWduLEVneXB0CjE2MTAsSllFQkNMTlVaVFhRNDU3LEpZRUJDTE5VWlRYUTQ1Ny1qN3Nudm84aSwyMDE1LTAxLTE4VDA5OjEzOjAyLjAwMDAwMCswMDAwLDIwMTUtMDEtMThUMDk6Mjg6MzIuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAzNSwxOC44LDIwMTUtMDEtMDQsb3RoZXJfY2FtcGFpZ24sRWd5cHQKMTYyNSxNVENJV0tPVkFTWVA5MjUsTVRDSVdLT1ZBU1lQOTI1LXBjbjhrdDJtLDIwMTUtMDEtMThUMTE6MTQ6MjkuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOFQxMToyMDoxMS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDgsMjUuOSwyMDE1LTAxLTE0LG9yZ2FuaWMsR2VybWFueQoxNjI4LE1UQ0lXS09WQVNZUDkyNSxNVENJV0tPVkFTWVA5MjUtcGNuOGt0Mm0sMjAxNS0wMS0xOFQxMToxNDoyOS4wMDAwMDArMDAwMCwyMDE1LTAxLTE4VDExOjM2OjIzLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNiwyNS45LDIwMTUtMDEtMTQsb3JnYW5pYyxHZXJtYW55CjE2MzQsWkdFVlFKU0tGSUJYMzk4LFpHRVZRSlNLRklCWDM5OC0ycndoMXB2NiwyMDE1LTAxLTE4VDEzOjMzOjMxLjAwMDAwMCswMDAwLDIwMTUtMDEtMThUMTM6NTI6MDEuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA2MywzMC43LDIwMTUtMDEtMTcsb3JnYW5pYyxTb3V0aCBLb3JlYQoxNjM1LFpHRVZRSlNLRklCWDM5OCxaR0VWUUpTS0ZJQlgzOTgtMnJ3aDFwdjYsMjAxNS0wMS0xOFQxMzozMzozMS4wMDAwMDArMDAwMCwyMDE1LTAxLTE4VDEzOjU4OjU1LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMjgsMzAuNywyMDE1LTAxLTE3LG9yZ2FuaWMsU291dGggS29yZWEKMTY0MSxaTUpMUEdDUklLTkE0NzEsWk1KTFBHQ1JJS05BNDcxLW56anViZmdyLDIwMTUtMDEtMThUMTM6NTU6MTAuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOFQxMzo1OToyOC4wMDAwMDArMDAwMCxhZCxhZF8xNXNlYywwLjA4NCw2LjIsMjAxNS0wMS0xMCxvcmdhbmljLEVneXB0CjE2NDQsRkdLWFBOSVJKSENZNjI1LEZHS1hQTklSSkhDWTYyNS1vZ3VmcmFpaiwyMDE1LTAxLTE4VDEzOjU5OjM0LjAwMDAwMCswMDAwLDIwMTUtMDEtMThUMTQ6MTE6NDAuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAzNCwzMi4xLDIwMTUtMDEtMTcsY3Jvc3Nwcm9tbyxIb25nIEtvbmcKMTY1MSxHSkNYTlRXRUJJUFEzNjksR0pDWE5UV0VCSVBRMzY5LXlibmFjcTM0LDIwMTUtMDEtMThUMTQ6MzQ6MDQuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOFQxNDo1ODoyMi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDMsMjkuNiwyMDE1LTAxLTE0LG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwoxNjU1LFJZWkhBSkVYTUJJRjcyNCxSWVpIQUpFWE1CSUY3MjQtcTFqOGNmb3UsMjAxNS0wMS0xOFQxNToxNzozNy4wMDAwMDArMDAwMCwyMDE1LTAxLTE4VDE1OjI5OjQ5LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMzYsMTUuMiwyMDE1LTAxLTE1LGdvb2dsZSxQb3J0dWdhbAoxNjU2LFJZWkhBSkVYTUJJRjcyNCxSWVpIQUpFWE1CSUY3MjQtcTFqOGNmb3UsMjAxNS0wMS0xOFQxNToxNzozNy4wMDAwMDArMDAwMCwyMDE1LTAxLTE4VDE1OjMyOjM3LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wODEsMTUuMiwyMDE1LTAxLTE1LGdvb2dsZSxQb3J0dWdhbAoxNjU5LEVLSUhYQlJGR09DRDU3MSxFS0lIWEJSRkdPQ0Q1NzEtZHZxZ3htNTYsMjAxNS0wMS0xOFQxNToyOToyMi4wMDAwMDArMDAwMCwyMDE1LTAxLTE4VDE1OjM2OjE2LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNSwzNS45LDIwMTUtMDEtMTcsYXBwbGUsVW5pdGVkIEtpbmdkb20KMTY2NCxQTFFFU0JOR1VES0oxNTQsUExRRVNCTkdVREtKMTU0LTNscTZpN29mLDIwMTUtMDEtMThUMTU6NDY6NDEuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOFQxNTo1MToxMS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDQ4LDM1LjIsMjAxNS0wMS0xMixmYWNlYm9vayxKYXBhbgoxNjY4LEhEU0FNUFRPTEJXQzQzOCxIRFNBTVBUT0xCV0M0MzgtZWJhNjI5eHQsMjAxNS0wMS0xOFQxNzozMDoyNi4wMDAwMDArMDAwMCwyMDE1LTAxLTE4VDE3OjM1OjUwLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wODQsMTYuNiwyMDE1LTAxLTE0LG9yZ2FuaWMsU3dpdHplcmxhbmQKMTY3OCxNVENJV0tPVkFTWVA5MjUsTVRDSVdLT1ZBU1lQOTI1LW45Z2xiaDI3LDIwMTUtMDEtMThUMjA6MTA6NDIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOFQyMDoyMDoyNC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMSwyMC42LDIwMTUtMDEtMTQsb3JnYW5pYyxHZXJtYW55CjE2NzksTVRDSVdLT1ZBU1lQOTI1LE1UQ0lXS09WQVNZUDkyNS1uOWdsYmgyNywyMDE1LTAxLTE4VDIwOjEwOjQyLjAwMDAwMCswMDAwLDIwMTUtMDEtMThUMjA6MzA6MDYuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA5LDIwLjYsMjAxNS0wMS0xNCxvcmdhbmljLEdlcm1hbnkKMTY4MSxNVENJV0tPVkFTWVA5MjUsTVRDSVdLT1ZBU1lQOTI1LW45Z2xiaDI3LDIwMTUtMDEtMThUMjA6MTA6NDIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOFQyMDozMDozMC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDIsMjAuNiwyMDE1LTAxLTE0LG9yZ2FuaWMsR2VybWFueQoxNjg2LFhJQUhCTktFQ0dSTzU5OCxYSUFIQk5LRUNHUk81OTgtZXlndHdwbTcsMjAxNS0wMS0xOFQyMjoxNzo1NC4wMDAwMDArMDAwMCwyMDE1LTAxLTE4VDIyOjIzOjM2LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNDUsMzYuMiwyMDE1LTAxLTE0LGdvb2dsZSxFZ3lwdAoxNjg5LE1UQ0lXS09WQVNZUDkyNSxNVENJV0tPVkFTWVA5MjUtOHJwemQ2bXcsMjAxNS0wMS0xOFQyMzozNDo0MS4wMDAwMDArMDAwMCwyMDE1LTAxLTE4VDIzOjM0OjUzLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wOCwyOS42LDIwMTUtMDEtMTQsb3JnYW5pYyxHZXJtYW55CjE2OTEsTVRDSVdLT1ZBU1lQOTI1LE1UQ0lXS09WQVNZUDkyNS04cnB6ZDZtdywyMDE1LTAxLTE4VDIzOjM0OjQxLjAwMDAwMCswMDAwLDIwMTUtMDEtMTlUMDA6MDM6NDcuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyLDI5LjYsMjAxNS0wMS0xNCxvcmdhbmljLEdlcm1hbnkKMTcwMCxRRFVaSklFVENBR1c2NTQsUURVWkpJRVRDQUdXNjU0LWZrNnhtOXV6LDIwMTUtMDEtMThUMjM6NDk6MDcuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOVQwMDowOTowMS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDQ4LDIxLjcsMjAxNS0wMS0wNyxmYWNlYm9vayxTd2l0emVybGFuZAoxNzA1LFdFUEtZTlJYREZVVDU3MixXRVBLWU5SWERGVVQ1NzItajNhdnVsNzUsMjAxNS0wMS0xOVQwMDozNzoyNy4wMDAwMDArMDAwMCwyMDE1LTAxLTE5VDAwOjQxOjAzLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMTIsMjkuOSwyMDE1LTAxLTEzLGNyb3NzcHJvbW8sQ2hpbmEKMTcwNixXRVBLWU5SWERGVVQ1NzIsV0VQS1lOUlhERlVUNTcyLWozYXZ1bDc1LDIwMTUtMDEtMTlUMDA6Mzc6MjcuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOVQwMDo0Mjo0NS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDEyLDI5LjksMjAxNS0wMS0xMyxjcm9zc3Byb21vLENoaW5hCjE3MDgsV0VQS1lOUlhERlVUNTcyLFdFUEtZTlJYREZVVDU3Mi1qM2F2dWw3NSwyMDE1LTAxLTE5VDAwOjM3OjI3LjAwMDAwMCswMDAwLDIwMTUtMDEtMTlUMDA6NDk6MDkuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA0OCwyOS45LDIwMTUtMDEtMTMsY3Jvc3Nwcm9tbyxDaGluYQoxNzEwLFhJQUhCTktFQ0dSTzU5OCxYSUFIQk5LRUNHUk81OTgteWlsc3hmNXAsMjAxNS0wMS0xOVQwMDo1MjozMi4wMDAwMDArMDAwMCwyMDE1LTAxLTE5VDAwOjU2OjAyLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNSwzMC40LDIwMTUtMDEtMTQsZ29vZ2xlLEVneXB0CjE3MTEsWElBSEJOS0VDR1JPNTk4LFhJQUhCTktFQ0dSTzU5OC15aWxzeGY1cCwyMDE1LTAxLTE5VDAwOjUyOjMyLjAwMDAwMCswMDAwLDIwMTUtMDEtMTlUMDE6MDI6MjAuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA0LDMwLjQsMjAxNS0wMS0xNCxnb29nbGUsRWd5cHQKMTcxMixYSUFIQk5LRUNHUk81OTgsWElBSEJOS0VDR1JPNTk4LXlpbHN4ZjVwLDIwMTUtMDEtMTlUMDA6NTI6MzIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOVQwMTowNDowOC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDE1LDMwLjQsMjAxNS0wMS0xNCxnb29nbGUsRWd5cHQKMTcxMyxYSUFIQk5LRUNHUk81OTgsWElBSEJOS0VDR1JPNTk4LXlpbHN4ZjVwLDIwMTUtMDEtMTlUMDA6NTI6MzIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOVQwMTowNTowOC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDE1LDMwLjQsMjAxNS0wMS0xNCxnb29nbGUsRWd5cHQKMTcxNixRSkdWT0JMQVRJSFc0NTcsUUpHVk9CTEFUSUhXNDU3LWNtZWxhNHo4LDIwMTUtMDEtMTlUMDE6MTE6NDEuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOVQwMToyMToxMS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDQ0LDQwLjksMjAxNS0wMS0wMixvdGhlcl9jYW1wYWlnbixTd2VkZW4KMTcxOSxHQVlJQkxVQ09FREo3MzIsR0FZSUJMVUNPRURKNzMyLTEzOHo3Z3ByLDIwMTUtMDEtMTlUMDE6Mjc6NDQuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOVQwMTozMDo1Ni4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDcsMzAuOCwyMDE1LTAxLTAzLG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwoxNzIwLEdBWUlCTFVDT0VESjczMixHQVlJQkxVQ09FREo3MzItMTM4ejdncHIsMjAxNS0wMS0xOVQwMToyNzo0NC4wMDAwMDArMDAwMCwyMDE1LTAxLTE5VDAxOjMxOjA4LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMywzMC44LDIwMTUtMDEtMDMsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjE3MjYsWElBSEJOS0VDR1JPNTk4LFhJQUhCTktFQ0dSTzU5OC0zN2Vvc3poOCwyMDE1LTAxLTE5VDAzOjE3OjAzLjAwMDAwMCswMDAwLDIwMTUtMDEtMTlUMDM6MjU6NDUuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA0NSwzOS45LDIwMTUtMDEtMTQsZ29vZ2xlLEVneXB0CjE3MjgsWElBSEJOS0VDR1JPNTk4LFhJQUhCTktFQ0dSTzU5OC0zN2Vvc3poOCwyMDE1LTAxLTE5VDAzOjE3OjAzLjAwMDAwMCswMDAwLDIwMTUtMDEtMTlUMDM6Mjk6MzMuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAzNSwzOS45LDIwMTUtMDEtMTQsZ29vZ2xlLEVneXB0CjE3MzcsTVRDSVdLT1ZBU1lQOTI1LE1UQ0lXS09WQVNZUDkyNS1lcWJjdnlndCwyMDE1LTAxLTE5VDA0OjM4OjU0LjAwMDAwMCswMDAwLDIwMTUtMDEtMTlUMDQ6Mzk6MTIuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyLDkuNCwyMDE1LTAxLTE0LG9yZ2FuaWMsR2VybWFueQoxNzQyLEZHS1hQTklSSkhDWTYyNSxGR0tYUE5JUkpIQ1k2MjUtMmQxOG80aWosMjAxNS0wMS0xOVQwNTowMDo1Ni4wMDAwMDArMDAwMCwyMDE1LTAxLTE5VDA1OjEwOjMyLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNDIsMTEuMywyMDE1LTAxLTE3LGNyb3NzcHJvbW8sSG9uZyBLb25nCg==" download="extract_0002.csv"><button style="background-color: #67C2DC; color: #FFFFFF; border: none; padding: 5px; font-weight: bold; cursor: pointer; border-radius: 4px;">CSV</button></a></td></p>
  </tr>
</tbody>
</table>
</div>
<p>In this example, we&rsquo;re using a simple function that prints a generic message whenever any threshold
is exceeded. By using the <code>Actions(default=)</code> parameter, this same function gets applied to all
threshold levels (&lsquo;warning&rsquo;, &rsquo;error&rsquo;, and &lsquo;critical&rsquo;). This saves you from having to define separate
actions for each level when you want the same behavior for all of them. The <code>highest_only=</code>
parameter (<code>True</code> by default, so not shown here) is complementary and it ensures that only the
action for the highest threshold level reached will be triggered, preventing multiple notifications
for the same validation failure.</p>
<h2 id="dynamic-messages-with-templating">Dynamic Messages with Templating
</h2>
<p>Actions don&rsquo;t have to be static messages. With Pointblank&rsquo;s templating system, you can create
context-aware notifications that include details about the specific validation failure.</p>
<p>Available placeholders include:</p>
<ul>
<li><code>{type}</code>: the validation step type (e.g., <code>&quot;col_vals_gt&quot;</code>)</li>
<li><code>{level}</code>: the threshold level (&lsquo;warning&rsquo;, &rsquo;error&rsquo;, &lsquo;critical&rsquo;)</li>
<li><code>{step}</code> or <code>{i}</code>: the step number in the validation workflow</li>
<li><code>{col}</code> or <code>{column}</code>: the column name being validated</li>
<li><code>{val}</code> or <code>{value}</code>: the comparison value used in the validation</li>
<li><code>{time}</code>: when the action was executed</li>
</ul>
<p>You can also capitalize placeholders (like <code>{LEVEL}</code>) to get uppercase text.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">action_template</span> <span class="o">=</span> <span class="s2">&#34;[</span><span class="si">{LEVEL}</span><span class="s2">] Step </span><span class="si">{step}</span><span class="s2">: Values in &#39;</span><span class="si">{column}</span><span class="s2">&#39; failed validation against </span><span class="si">{value}</span><span class="s2">.&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">validation_3</span> <span class="o">=</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">pb</span><span class="o">.</span><span class="n">Validate</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="n">data</span><span class="o">=</span><span class="n">pb</span><span class="o">.</span><span class="n">load_dataset</span><span class="p">(</span><span class="n">dataset</span><span class="o">=</span><span class="s2">&#34;small_table&#34;</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">        <span class="n">thresholds</span><span class="o">=</span><span class="n">pb</span><span class="o">.</span><span class="n">Thresholds</span><span class="p">(</span><span class="n">warning</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">error</span><span class="o">=</span><span class="mi">4</span><span class="p">,</span> <span class="n">critical</span><span class="o">=</span><span class="mi">10</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">        <span class="n">actions</span><span class="o">=</span><span class="n">pb</span><span class="o">.</span><span class="n">Actions</span><span class="p">(</span><span class="n">default</span><span class="o">=</span><span class="n">action_template</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">col_vals_lt</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="n">columns</span><span class="o">=</span><span class="s2">&#34;d&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="n">value</span><span class="o">=</span><span class="mi">3000</span>
</span></span><span class="line"><span class="cl">    <span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">interrogate</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">validation_3</span>
</span></span></code></pre></td></tr></table>
</div>
</div><pre><code>[ERROR] Step 1: Values in 'd' failed validation against 3000.
</code></pre>
<div id="pb_tbl" style="padding-left:0px;padding-right:0px;padding-top:10px;padding-bottom:10px;overflow-x:auto;overflow-y:auto;width:auto;height:auto;">
<style>
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono&display=swap');
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans&display=swap');
#pb_tbl table {
          font-family: 'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Helvetica Neue', 'Fira Sans', 'Droid Sans', Arial, sans-serif;
          -webkit-font-smoothing: antialiased;
          -moz-osx-font-smoothing: grayscale;
        }
<p>#pb_tbl thead, tbody, tfoot, tr, td, th { border-style: none; }
tr { background-color: transparent; }
#pb_tbl p { margin: 0; padding: 0; }
#pb_tbl .gt_table { display: table; border-collapse: collapse; line-height: normal; margin-left: auto; margin-right: auto; color: #333333; font-size: 90%; font-weight: normal; font-style: normal; background-color: #FFFFFF; width: auto; border-top-style: solid; border-top-width: 2px; border-top-color: #A8A8A8; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #A8A8A8; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; }
#pb_tbl .gt_caption { padding-top: 4px; padding-bottom: 4px; }
#pb_tbl .gt_title { color: #333333; font-size: 125%; font-weight: initial; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; border-bottom-color: #FFFFFF; border-bottom-width: 0; }
#pb_tbl .gt_subtitle { color: #333333; font-size: 85%; font-weight: initial; padding-top: 3px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; border-top-color: #FFFFFF; border-top-width: 0; }
#pb_tbl .gt_heading { background-color: #FFFFFF; text-align: left; border-bottom-color: #FFFFFF; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; }
#pb_tbl .gt_bottom_border { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; }
#pb_tbl .gt_col_headings { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; }
#pb_tbl .gt_col_heading { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; overflow-x: hidden; }
#pb_tbl .gt_column_spanner_outer { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; padding-top: 0; padding-bottom: 0; padding-left: 4px; padding-right: 4px; }
#pb_tbl .gt_column_spanner_outer:first-child { padding-left: 0; }
#pb_tbl .gt_column_spanner_outer:last-child { padding-right: 0; }
#pb_tbl .gt_column_spanner { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; overflow-x: hidden; display: inline-block; width: 100%; }
#pb_tbl .gt_spanner_row { border-bottom-style: hidden; }
#pb_tbl .gt_group_heading { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; text-align: left; }
#pb_tbl .gt_empty_group_heading { padding: 0.5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: middle; }
#pb_tbl .gt_from_md&gt; :first-child { margin-top: 0; }
#pb_tbl .gt_from_md&gt; :last-child { margin-bottom: 0; }
#pb_tbl .gt_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; margin: 10px; border-top-style: solid; border-top-width: 1px; border-top-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; overflow-x: hidden; }
#pb_tbl .gt_stub { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; }
#pb_tbl .gt_stub_row_group { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; vertical-align: top; }
#pb_tbl .gt_row_group_first td { border-top-width: 2px; }
#pb_tbl .gt_row_group_first th { border-top-width: 2px; }
#pb_tbl .gt_striped { color: #333333; background-color: #F4F4F4; }
#pb_tbl .gt_table_body { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; }
#pb_tbl .gt_grand_summary_row { color: #333333; background-color: #FFFFFF; text-transform: inherit; padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; }
#pb_tbl .gt_first_grand_summary_row_bottom { border-top-style: double; border-top-width: 6px; border-top-color: #D3D3D3; }
#pb_tbl .gt_last_grand_summary_row_top { border-bottom-style: double; border-bottom-width: 6px; border-bottom-color: #D3D3D3; }
#pb_tbl .gt_sourcenotes { color: #333333; background-color: #FFFFFF; border-bottom-style: none; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; }
#pb_tbl .gt_sourcenote { font-size: 90%; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; text-align: left; }
#pb_tbl .gt_left { text-align: left; }
#pb_tbl .gt_center { text-align: center; }
#pb_tbl .gt_right { text-align: right; font-variant-numeric: tabular-nums; }
#pb_tbl .gt_font_normal { font-weight: normal; }
#pb_tbl .gt_font_bold { font-weight: bold; }
#pb_tbl .gt_font_italic { font-style: italic; }
#pb_tbl .gt_super { font-size: 65%; }
#pb_tbl .gt_footnote_marks { font-size: 75%; vertical-align: 0.4em; position: initial; }
#pb_tbl .gt_asterisk { font-size: 100%; vertical-align: 0; }</p>
<p></style></p>
<table style="table-layout: fixed;; width: 0px" class="gt_table" data-quarto-disable-processing="true" data-quarto-bootstrap="false">
<colgroup>
  <col style="width:4px;"/>
  <col style="width:35px;"/>
  <col style="width:190px;"/>
  <col style="width:120px;"/>
  <col style="width:120px;"/>
  <col style="width:50px;"/>
  <col style="width:50px;"/>
  <col style="width:60px;"/>
  <col style="width:60px;"/>
  <col style="width:60px;"/>
  <col style="width:30px;"/>
  <col style="width:30px;"/>
  <col style="width:30px;"/>
  <col style="width:65px;"/>
</colgroup>
<thead>
  <tr class="gt_heading">
    <td colspan="14" class="gt_heading gt_title gt_font_normal" style="color: #444444;font-size: 28px;text-align: left;font-weight: bold; text-align: left;">Pointblank Validation</td>
  </tr>
  <tr class="gt_heading">
    <td colspan="14" class="gt_heading gt_subtitle gt_font_normal gt_bottom_border" style="text-align: left;"><div><span style='text-decoration-style: solid; text-decoration-color: #ADD8E6; text-decoration-line: underline; text-underline-position: under; color: #333333; font-variant-numeric: tabular-nums; padding-left: 4px; margin-right: 5px; padding-right: 2px;'>2026-03-13|19:09:28</span><div style="padding-top: 10px; padding-bottom: 5px;"><span style='background-color: #0075FF; color: #FFFFFF; padding: 0.5em 0.5em; position: inherit; text-transform: uppercase; margin: 5px 10px 5px 0px; border: solid 1px #0075FF; font-weight: bold; padding: 2px 10px 2px 10px; font-size: 10px;'>Polars</span><span><span style="background-color: #AAAAAA; color: white; padding: 0.5em 0.5em; position: inherit; text-transform: uppercase; margin: 5px 0px 5px 5px; border: solid 1px #AAAAAA; font-weight: bold; padding: 2px 15px 2px 15px; font-size: smaller;">WARNING</span><span style="background-color: none; color: #333333; padding: 0.5em 0.5em; position: inherit; margin: 5px 0px 5px -4px; font-weight: bold; border: solid 1px #AAAAAA; padding: 2px 15px 2px 15px; font-size: smaller; margin-right: 5px;">1</span><span style="background-color: #EBBC14; color: white; padding: 0.5em 0.5em; position: inherit; text-transform: uppercase; margin: 5px 0px 5px 1px; border: solid 1px #EBBC14; font-weight: bold; padding: 2px 15px 2px 15px; font-size: smaller;">ERROR</span><span style="background-color: none; color: #333333; padding: 0.5em 0.5em; position: inherit; margin: 5px 0px 5px -4px; font-weight: bold; border: solid 1px #EBBC14; padding: 2px 15px 2px 15px; font-size: smaller; margin-right: 5px;">4</span><span style="background-color: #FF3300; color: white; padding: 0.5em 0.5em; position: inherit; text-transform: uppercase; margin: 5px 0px 5px 1px; border: solid 1px #FF3300; font-weight: bold; padding: 2px 15px 2px 15px; font-size: smaller;">CRITICAL</span><span style="background-color: none; color: #333333; padding: 0.5em 0.5em; position: inherit; margin: 5px 0px 5px -4px; font-weight: bold; border: solid 1px #FF3300; padding: 2px 15px 2px 15px; font-size: smaller;">10</span></span></div></div></td>
  </tr>
<tr class="gt_col_headings">
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-status_color"></th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-i"></th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-type_upd">STEP</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-columns_upd">COLUMNS</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-values_upd">VALUES</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-tbl">TBL</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-eval">EVAL</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-test_units">UNITS</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-pass">PASS</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-fail">FAIL</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-w_upd">W</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-e_upd">E</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-c_upd">C</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-extract_upd">EXT</th>
</tr>
</thead>
<tbody class="gt_table_body">
  <tr>
    <td style="height: 40px; background-color: #EBBC14; color: transparent;font-size: 0px;" class="gt_row gt_left">#EBBC14</td>
    <td style="height: 40px; color: #666666;font-size: 13px;font-weight: bold;" class="gt_row gt_right">1</td>
    <td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_left">
        <div style="margin: 0; padding: 0; display: inline-block; height: 30px; vertical-align: middle; width: 16%;">
            <!--?xml version="1.0" encoding="UTF-8"?--><?xml version="1.0" encoding="UTF-8"?>
<svg width="30px" height="30px" viewBox="0 0 67 67" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="background: #FFFFFF;">
    <title>col_vals_lt</title>
    <g id="Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="col_vals_lt" transform="translate(1.500000, 1.500000)" fill-rule="nonzero">
            <path d="M55,0 C57.4852813,0 59.7352813,1.00735931 61.363961,2.63603897 C62.9926407,4.26471863 64,6.51471863 64,9 L64,9 L64,64 L9,64 C6.51471862,64 4.26471862,62.9926407 2.63603897,61.363961 C1.00735931,59.7352814 0,57.4852814 0,55 L0,55 L0,9 C0,6.51471863 1.00735931,4.26471863 2.63603897,2.63603897 C4.26471862,1.00735931 6.51471862,0 9,0 L9,0 L55,0 Z" id="rectangle" stroke="#000000" stroke-width="2" fill="#FFFFFF"></path>
            <path d="M51,10 L13,10 C11.347656,10 10,11.347656 10,13 L10,51 C10,52.652344 11.347656,54 13,54 L51,54 C52.652344,54 54,52.652344 54,51 L54,13 C54,11.347656 52.652344,10 51,10 Z M38.707031,45.292969 L37.292969,46.707031 L22.585938,32 L37.292969,17.292969 L38.707031,18.707031 L25.414063,32 L38.707031,45.292969 Z" id="less_than" fill="#000000"></path>
        </g>
    </g>
</svg>
        </div>
        <div style="font-family: 'IBM Plex Mono', monospace, courier; color: black; font-size: 11px; display: inline-block; vertical-align: middle;">
            <div>col_vals_lt()</div>
        </div>
<pre><code>    &lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;d&lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;3000&lt;/td&gt;
&lt;td style=&quot;height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;&quot; class=&quot;gt_row gt_center&quot;&gt;&lt;svg width=&quot;25px&quot; height=&quot;25px&quot; viewBox=&quot;0 0 25 25&quot; version=&quot;1.1&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot; style=&quot;vertical-align: middle;&quot;&gt;
&lt;g id=&quot;unchanged&quot; stroke=&quot;none&quot; stroke-width=&quot;1&quot; fill=&quot;none&quot; fill-rule=&quot;evenodd&quot;&gt;
    &lt;g id=&quot;unchanged&quot; transform=&quot;translate(0.500000, 0.570147)&quot;&gt;
        &lt;rect id=&quot;Rectangle&quot; x=&quot;0.125132506&quot; y=&quot;0&quot; width=&quot;23.749735&quot; height=&quot;23.7894737&quot;&gt;&lt;/rect&gt;
        &lt;path d=&quot;M5.80375046,8.18194736 C3.77191832,8.18194736 2.11875046,9.83495328 2.11875046,11.8669474 C2.11875046,13.8989414 3.77191832,15.5519474 5.80375046,15.5519474 C7.8355826,15.5519474 9.48875046,13.8989414 9.48875046,11.8669474 C9.48875046,9.83495328 7.83552863,8.18194736 5.80375046,8.18194736 Z M5.80375046,14.814915 C4.17821997,14.814915 2.85578285,13.4924778 2.85578285,11.8669474 C2.85578285,10.2414169 4.17821997,8.91897975 5.80375046,8.91897975 C7.42928095,8.91897975 8.75171807,10.2414169 8.75171807,11.8669474 C8.75171807,13.4924778 7.42928095,14.814915 5.80375046,14.814915 Z&quot; id=&quot;Shape&quot; fill=&quot;#000000&quot; fill-rule=&quot;nonzero&quot;&gt;&lt;/path&gt;
        &lt;path d=&quot;M13.9638189,8.699335 C13.9364621,8.70430925 13.9091059,8.71176968 13.8842359,8.71923074 C13.7822704,8.73663967 13.6877654,8.77643115 13.6056956,8.83860518 L10.2433156,11.3852598 C10.0766886,11.5046343 9.97720993,11.6986181 9.97720993,11.9025491 C9.97720993,12.1064807 10.0766886,12.3004639 10.2433156,12.4198383 L13.6056956,14.966493 C13.891697,15.1803725 14.2970729,15.1231721 14.5109517,14.8371707 C14.7248313,14.5511692 14.6676309,14.145794 14.3816294,13.9319145 L12.5313257,12.5392127 L21.8812495,12.5392127 L21.8812495,11.2658854 L12.5313257,11.2658854 L14.3816294,9.87318364 C14.6377872,9.71650453 14.7497006,9.40066014 14.6477351,9.11714553 C14.5482564,8.83363156 14.262255,8.65954352 13.9638189,8.699335 Z&quot; id=&quot;arrow&quot; fill=&quot;#000000&quot; transform=&quot;translate(15.929230, 11.894737) rotate(-180.000000) translate(-15.929230, -11.894737) &quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
&lt;/g&gt;
</code></pre>
<p></svg></td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color:#4CA64C;">✓</span></td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_right">13</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">9<br />0.69</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">4<br />0.31</td>
<td style="height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color: #AAAAAA;">●</span></td>
<td style="height: 40px; background-color: #FCFCFC;" class="gt_row gt_center"><span style="color: #EBBC14;">●</span></td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color: #FF3300;">○</span></td>
<td style="height: 40px;" class="gt_row gt_center"><a href="data:text/csv;base64,X3Jvd19udW1fLGRhdGVfdGltZSxkYXRlLGEsYixjLGQsZSxmCjEsMjAxNi0wMS0wNFQxMTowMDowMC4wMDAwMDAsMjAxNi0wMS0wNCwyLDEtYmNkLTM0NSwzLDM0MjMuMjksdHJ1ZSxoaWdoCjIsMjAxNi0wMS0wNFQwMDozMjowMC4wMDAwMDAsMjAxNi0wMS0wNCwzLDUtZWdoLTE2Myw4LDk5OTkuOTksdHJ1ZSxsb3cKNCwyMDE2LTAxLTA2VDE3OjIzOjAwLjAwMDAwMCwyMDE2LTAxLTA2LDIsNS1qZG8tOTAzLCwzODkyLjQsZmFsc2UsbWlkCjYsMjAxNi0wMS0xMVQwNjoxNTowMC4wMDAwMDAsMjAxNi0wMS0xMSw0LDItZGhlLTkyMyw0LDMyOTEuMDMsdHJ1ZSxtaWQK" download="extract_0001.csv"><button style="background-color: #67C2DC; color: #FFFFFF; border: none; padding: 5px; font-weight: bold; cursor: pointer; border-radius: 4px;">CSV</button></a></td></p>
  </tr>
</tbody>
</table>
</div>
<p>This templating approach is a great way to create context-aware notifications that adapt to the
specific validation failures occurring. As the example shows, when values in column <code>d</code> fail
validation against the limit of <code>3000</code>, the template automatically generates a meaningful error
message showing exactly which step, column, and threshold value was involved.</p>
<h2 id="accessing-metadata-in-custom-action-functions">Accessing Metadata in Custom Action Functions
</h2>
<p>For more sophisticated actions, you often need access to details about the validation failure. The
<code>get_action_metadata()</code> function provides this context when called inside an action function:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">send_detailed_alert</span><span class="p">():</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># Get metadata about the validation failure</span>
</span></span><span class="line"><span class="cl">    <span class="n">metadata</span> <span class="o">=</span> <span class="n">pb</span><span class="o">.</span><span class="n">get_action_metadata</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># Create a customized alert message</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;&#34;&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    VALIDATION FAILURE DETAILS
</span></span></span><span class="line"><span class="cl"><span class="s2">    -------------------------
</span></span></span><span class="line"><span class="cl"><span class="s2">    Step: </span><span class="si">{</span><span class="n">metadata</span><span class="p">[</span><span class="s1">&#39;step&#39;</span><span class="p">]</span><span class="si">}</span><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">    Column: </span><span class="si">{</span><span class="n">metadata</span><span class="p">[</span><span class="s1">&#39;column&#39;</span><span class="p">]</span><span class="si">}</span><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">    Validation type: </span><span class="si">{</span><span class="n">metadata</span><span class="p">[</span><span class="s1">&#39;type&#39;</span><span class="p">]</span><span class="si">}</span><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">    Severity: </span><span class="si">{</span><span class="n">metadata</span><span class="p">[</span><span class="s1">&#39;level&#39;</span><span class="p">]</span><span class="si">}</span><span class="s2"> (level </span><span class="si">{</span><span class="n">metadata</span><span class="p">[</span><span class="s1">&#39;level_num&#39;</span><span class="p">]</span><span class="si">}</span><span class="s2">)
</span></span></span><span class="line"><span class="cl"><span class="s2">    Time: </span><span class="si">{</span><span class="n">metadata</span><span class="p">[</span><span class="s1">&#39;time&#39;</span><span class="p">]</span><span class="si">}</span><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">    Explanation: </span><span class="si">{</span><span class="n">metadata</span><span class="p">[</span><span class="s1">&#39;failure_text&#39;</span><span class="p">]</span><span class="si">}</span><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">    &#34;&#34;&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">validation_4</span> <span class="o">=</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">pb</span><span class="o">.</span><span class="n">Validate</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="n">data</span><span class="o">=</span><span class="n">pb</span><span class="o">.</span><span class="n">load_dataset</span><span class="p">(</span><span class="n">dataset</span><span class="o">=</span><span class="s2">&#34;small_table&#34;</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">        <span class="n">thresholds</span><span class="o">=</span><span class="n">pb</span><span class="o">.</span><span class="n">Thresholds</span><span class="p">(</span><span class="n">critical</span><span class="o">=</span><span class="mi">1</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">        <span class="n">actions</span><span class="o">=</span><span class="n">pb</span><span class="o">.</span><span class="n">Actions</span><span class="p">(</span><span class="n">critical</span><span class="o">=</span><span class="n">send_detailed_alert</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">col_vals_gt</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="n">columns</span><span class="o">=</span><span class="s2">&#34;d&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="n">value</span><span class="o">=</span><span class="mi">5000</span>
</span></span><span class="line"><span class="cl">    <span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">interrogate</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">validation_4</span>
</span></span></code></pre></td></tr></table>
</div>
</div><pre><code>    VALIDATION FAILURE DETAILS
    -------------------------
    Step: 1
    Column: d
    Validation type: col_vals_gt
    Severity: critical (level 50)
    Time: 2026-03-13 19:09:29.030877+00:00

    Explanation: Exceedance of failed test units where values in `d` should have been &gt; `5000`.
</code></pre>
<div id="pb_tbl" style="padding-left:0px;padding-right:0px;padding-top:10px;padding-bottom:10px;overflow-x:auto;overflow-y:auto;width:auto;height:auto;">
<style>
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono&display=swap');
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans&display=swap');
#pb_tbl table {
          font-family: 'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Helvetica Neue', 'Fira Sans', 'Droid Sans', Arial, sans-serif;
          -webkit-font-smoothing: antialiased;
          -moz-osx-font-smoothing: grayscale;
        }
<p>#pb_tbl thead, tbody, tfoot, tr, td, th { border-style: none; }
tr { background-color: transparent; }
#pb_tbl p { margin: 0; padding: 0; }
#pb_tbl .gt_table { display: table; border-collapse: collapse; line-height: normal; margin-left: auto; margin-right: auto; color: #333333; font-size: 90%; font-weight: normal; font-style: normal; background-color: #FFFFFF; width: auto; border-top-style: solid; border-top-width: 2px; border-top-color: #A8A8A8; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #A8A8A8; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; }
#pb_tbl .gt_caption { padding-top: 4px; padding-bottom: 4px; }
#pb_tbl .gt_title { color: #333333; font-size: 125%; font-weight: initial; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; border-bottom-color: #FFFFFF; border-bottom-width: 0; }
#pb_tbl .gt_subtitle { color: #333333; font-size: 85%; font-weight: initial; padding-top: 3px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; border-top-color: #FFFFFF; border-top-width: 0; }
#pb_tbl .gt_heading { background-color: #FFFFFF; text-align: left; border-bottom-color: #FFFFFF; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; }
#pb_tbl .gt_bottom_border { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; }
#pb_tbl .gt_col_headings { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; }
#pb_tbl .gt_col_heading { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; overflow-x: hidden; }
#pb_tbl .gt_column_spanner_outer { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; padding-top: 0; padding-bottom: 0; padding-left: 4px; padding-right: 4px; }
#pb_tbl .gt_column_spanner_outer:first-child { padding-left: 0; }
#pb_tbl .gt_column_spanner_outer:last-child { padding-right: 0; }
#pb_tbl .gt_column_spanner { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; overflow-x: hidden; display: inline-block; width: 100%; }
#pb_tbl .gt_spanner_row { border-bottom-style: hidden; }
#pb_tbl .gt_group_heading { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; text-align: left; }
#pb_tbl .gt_empty_group_heading { padding: 0.5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: middle; }
#pb_tbl .gt_from_md&gt; :first-child { margin-top: 0; }
#pb_tbl .gt_from_md&gt; :last-child { margin-bottom: 0; }
#pb_tbl .gt_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; margin: 10px; border-top-style: solid; border-top-width: 1px; border-top-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; overflow-x: hidden; }
#pb_tbl .gt_stub { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; }
#pb_tbl .gt_stub_row_group { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; vertical-align: top; }
#pb_tbl .gt_row_group_first td { border-top-width: 2px; }
#pb_tbl .gt_row_group_first th { border-top-width: 2px; }
#pb_tbl .gt_striped { color: #333333; background-color: #F4F4F4; }
#pb_tbl .gt_table_body { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; }
#pb_tbl .gt_grand_summary_row { color: #333333; background-color: #FFFFFF; text-transform: inherit; padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; }
#pb_tbl .gt_first_grand_summary_row_bottom { border-top-style: double; border-top-width: 6px; border-top-color: #D3D3D3; }
#pb_tbl .gt_last_grand_summary_row_top { border-bottom-style: double; border-bottom-width: 6px; border-bottom-color: #D3D3D3; }
#pb_tbl .gt_sourcenotes { color: #333333; background-color: #FFFFFF; border-bottom-style: none; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; }
#pb_tbl .gt_sourcenote { font-size: 90%; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; text-align: left; }
#pb_tbl .gt_left { text-align: left; }
#pb_tbl .gt_center { text-align: center; }
#pb_tbl .gt_right { text-align: right; font-variant-numeric: tabular-nums; }
#pb_tbl .gt_font_normal { font-weight: normal; }
#pb_tbl .gt_font_bold { font-weight: bold; }
#pb_tbl .gt_font_italic { font-style: italic; }
#pb_tbl .gt_super { font-size: 65%; }
#pb_tbl .gt_footnote_marks { font-size: 75%; vertical-align: 0.4em; position: initial; }
#pb_tbl .gt_asterisk { font-size: 100%; vertical-align: 0; }</p>
<p></style></p>
<table style="table-layout: fixed;; width: 0px" class="gt_table" data-quarto-disable-processing="true" data-quarto-bootstrap="false">
<colgroup>
  <col style="width:4px;"/>
  <col style="width:35px;"/>
  <col style="width:190px;"/>
  <col style="width:120px;"/>
  <col style="width:120px;"/>
  <col style="width:50px;"/>
  <col style="width:50px;"/>
  <col style="width:60px;"/>
  <col style="width:60px;"/>
  <col style="width:60px;"/>
  <col style="width:30px;"/>
  <col style="width:30px;"/>
  <col style="width:30px;"/>
  <col style="width:65px;"/>
</colgroup>
<thead>
  <tr class="gt_heading">
    <td colspan="14" class="gt_heading gt_title gt_font_normal" style="color: #444444;font-size: 28px;text-align: left;font-weight: bold; text-align: left;">Pointblank Validation</td>
  </tr>
  <tr class="gt_heading">
    <td colspan="14" class="gt_heading gt_subtitle gt_font_normal gt_bottom_border" style="text-align: left;"><div><span style='text-decoration-style: solid; text-decoration-color: #ADD8E6; text-decoration-line: underline; text-underline-position: under; color: #333333; font-variant-numeric: tabular-nums; padding-left: 4px; margin-right: 5px; padding-right: 2px;'>2026-03-13|19:09:29</span><div style="padding-top: 10px; padding-bottom: 5px;"><span style='background-color: #0075FF; color: #FFFFFF; padding: 0.5em 0.5em; position: inherit; text-transform: uppercase; margin: 5px 10px 5px 0px; border: solid 1px #0075FF; font-weight: bold; padding: 2px 10px 2px 10px; font-size: 10px;'>Polars</span><span><span style="background-color: #AAAAAA; color: white; padding: 0.5em 0.5em; position: inherit; text-transform: uppercase; margin: 5px 0px 5px 5px; border: solid 1px #AAAAAA; font-weight: bold; padding: 2px 15px 2px 15px; font-size: smaller;">WARNING</span><span style="background-color: none; color: #333333; padding: 0.5em 0.5em; position: inherit; margin: 5px 0px 5px -4px; font-weight: bold; border: solid 1px #AAAAAA; padding: 2px 15px 2px 15px; font-size: smaller; margin-right: 5px;">&mdash;</span><span style="background-color: #EBBC14; color: white; padding: 0.5em 0.5em; position: inherit; text-transform: uppercase; margin: 5px 0px 5px 1px; border: solid 1px #EBBC14; font-weight: bold; padding: 2px 15px 2px 15px; font-size: smaller;">ERROR</span><span style="background-color: none; color: #333333; padding: 0.5em 0.5em; position: inherit; margin: 5px 0px 5px -4px; font-weight: bold; border: solid 1px #EBBC14; padding: 2px 15px 2px 15px; font-size: smaller; margin-right: 5px;">&mdash;</span><span style="background-color: #FF3300; color: white; padding: 0.5em 0.5em; position: inherit; text-transform: uppercase; margin: 5px 0px 5px 1px; border: solid 1px #FF3300; font-weight: bold; padding: 2px 15px 2px 15px; font-size: smaller;">CRITICAL</span><span style="background-color: none; color: #333333; padding: 0.5em 0.5em; position: inherit; margin: 5px 0px 5px -4px; font-weight: bold; border: solid 1px #FF3300; padding: 2px 15px 2px 15px; font-size: smaller;">1</span></span></div></div></td>
  </tr>
<tr class="gt_col_headings">
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-status_color"></th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-i"></th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-type_upd">STEP</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-columns_upd">COLUMNS</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-values_upd">VALUES</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-tbl">TBL</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-eval">EVAL</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-test_units">UNITS</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-pass">PASS</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-fail">FAIL</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-w_upd">W</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-e_upd">E</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-c_upd">C</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-extract_upd">EXT</th>
</tr>
</thead>
<tbody class="gt_table_body">
  <tr>
    <td style="height: 40px; background-color: #FF3300; color: transparent;font-size: 0px;" class="gt_row gt_left">#FF3300</td>
    <td style="height: 40px; color: #666666;font-size: 13px;font-weight: bold;" class="gt_row gt_right">1</td>
    <td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_left">
        <div style="margin: 0; padding: 0; display: inline-block; height: 30px; vertical-align: middle; width: 16%;">
            <!--?xml version="1.0" encoding="UTF-8"?--><?xml version="1.0" encoding="UTF-8"?>
<svg width="30px" height="30px" viewBox="0 0 67 67" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="background: #FFFFFF;">
    <title>col_vals_gt</title>
    <g id="Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="col_vals_gt" transform="translate(1.500000, 1.500000)" fill-rule="nonzero">
            <path d="M55,0 C57.4852813,0 59.7352813,1.00735931 61.363961,2.63603897 C62.9926407,4.26471863 64,6.51471863 64,9 L64,9 L64,64 L9,64 C6.51471862,64 4.26471862,62.9926407 2.63603897,61.363961 C1.00735931,59.7352814 0,57.4852814 0,55 L0,55 L0,9 C0,6.51471863 1.00735931,4.26471863 2.63603897,2.63603897 C4.26471862,1.00735931 6.51471862,0 9,0 L9,0 L55,0 Z" id="rectangle" stroke="#000000" stroke-width="2" fill="#FFFFFF"></path>
            <path d="M48.7619048,10 L15.2380953,10 C12.3466667,10 10,12.3466667 10,15.2380952 L10,48.7619048 C10,51.6533333 12.3466667,54 15.2380953,54 L48.7619048,54 C51.6533333,54 54,51.6533333 54,48.7619048 L54,15.2380952 C54,12.3466667 51.6533333,10 48.7619048,10 Z M25.2638095,44.3828571 L24.0695238,42.6647619 L39.5847619,32 L24.0695238,21.3352381 L25.2638095,19.6171429 L43.2828572,32 L25.2638095,44.3828571 Z" id="greater_than" fill="#000000"></path>
        </g>
    </g>
</svg>
        </div>
        <div style="font-family: 'IBM Plex Mono', monospace, courier; color: black; font-size: 11px; display: inline-block; vertical-align: middle;">
            <div>col_vals_gt()</div>
        </div>
<pre><code>    &lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;d&lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;5000&lt;/td&gt;
&lt;td style=&quot;height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;&quot; class=&quot;gt_row gt_center&quot;&gt;&lt;svg width=&quot;25px&quot; height=&quot;25px&quot; viewBox=&quot;0 0 25 25&quot; version=&quot;1.1&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot; style=&quot;vertical-align: middle;&quot;&gt;
&lt;g id=&quot;unchanged&quot; stroke=&quot;none&quot; stroke-width=&quot;1&quot; fill=&quot;none&quot; fill-rule=&quot;evenodd&quot;&gt;
    &lt;g id=&quot;unchanged&quot; transform=&quot;translate(0.500000, 0.570147)&quot;&gt;
        &lt;rect id=&quot;Rectangle&quot; x=&quot;0.125132506&quot; y=&quot;0&quot; width=&quot;23.749735&quot; height=&quot;23.7894737&quot;&gt;&lt;/rect&gt;
        &lt;path d=&quot;M5.80375046,8.18194736 C3.77191832,8.18194736 2.11875046,9.83495328 2.11875046,11.8669474 C2.11875046,13.8989414 3.77191832,15.5519474 5.80375046,15.5519474 C7.8355826,15.5519474 9.48875046,13.8989414 9.48875046,11.8669474 C9.48875046,9.83495328 7.83552863,8.18194736 5.80375046,8.18194736 Z M5.80375046,14.814915 C4.17821997,14.814915 2.85578285,13.4924778 2.85578285,11.8669474 C2.85578285,10.2414169 4.17821997,8.91897975 5.80375046,8.91897975 C7.42928095,8.91897975 8.75171807,10.2414169 8.75171807,11.8669474 C8.75171807,13.4924778 7.42928095,14.814915 5.80375046,14.814915 Z&quot; id=&quot;Shape&quot; fill=&quot;#000000&quot; fill-rule=&quot;nonzero&quot;&gt;&lt;/path&gt;
        &lt;path d=&quot;M13.9638189,8.699335 C13.9364621,8.70430925 13.9091059,8.71176968 13.8842359,8.71923074 C13.7822704,8.73663967 13.6877654,8.77643115 13.6056956,8.83860518 L10.2433156,11.3852598 C10.0766886,11.5046343 9.97720993,11.6986181 9.97720993,11.9025491 C9.97720993,12.1064807 10.0766886,12.3004639 10.2433156,12.4198383 L13.6056956,14.966493 C13.891697,15.1803725 14.2970729,15.1231721 14.5109517,14.8371707 C14.7248313,14.5511692 14.6676309,14.145794 14.3816294,13.9319145 L12.5313257,12.5392127 L21.8812495,12.5392127 L21.8812495,11.2658854 L12.5313257,11.2658854 L14.3816294,9.87318364 C14.6377872,9.71650453 14.7497006,9.40066014 14.6477351,9.11714553 C14.5482564,8.83363156 14.262255,8.65954352 13.9638189,8.699335 Z&quot; id=&quot;arrow&quot; fill=&quot;#000000&quot; transform=&quot;translate(15.929230, 11.894737) rotate(-180.000000) translate(-15.929230, -11.894737) &quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
&lt;/g&gt;
</code></pre>
<p></svg></td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color:#4CA64C;">✓</span></td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_right">13</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">1<br />0.08</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">12<br />0.92</td>
<td style="height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;" class="gt_row gt_center">—</td>
<td style="height: 40px; background-color: #FCFCFC;" class="gt_row gt_center">—</td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color: #FF3300;">●</span></td>
<td style="height: 40px;" class="gt_row gt_center"><a href="data:text/csv;base64,X3Jvd19udW1fLGRhdGVfdGltZSxkYXRlLGEsYixjLGQsZSxmCjEsMjAxNi0wMS0wNFQxMTowMDowMC4wMDAwMDAsMjAxNi0wMS0wNCwyLDEtYmNkLTM0NSwzLDM0MjMuMjksdHJ1ZSxoaWdoCjMsMjAxNi0wMS0wNVQxMzozMjowMC4wMDAwMDAsMjAxNi0wMS0wNSw2LDgta2RnLTkzOCwzLDIzNDMuMjMsdHJ1ZSxoaWdoCjQsMjAxNi0wMS0wNlQxNzoyMzowMC4wMDAwMDAsMjAxNi0wMS0wNiwyLDUtamRvLTkwMywsMzg5Mi40LGZhbHNlLG1pZAo1LDIwMTYtMDEtMDlUMTI6MzY6MDAuMDAwMDAwLDIwMTYtMDEtMDksOCwzLWxkbS0wMzgsNywyODMuOTQsdHJ1ZSxsb3cKNiwyMDE2LTAxLTExVDA2OjE1OjAwLjAwMDAwMCwyMDE2LTAxLTExLDQsMi1kaGUtOTIzLDQsMzI5MS4wMyx0cnVlLG1pZAo3LDIwMTYtMDEtMTVUMTg6NDY6MDAuMDAwMDAwLDIwMTYtMDEtMTUsNywxLWtudy0wOTMsMyw4NDMuMzQsdHJ1ZSxoaWdoCjgsMjAxNi0wMS0xN1QxMToyNzowMC4wMDAwMDAsMjAxNi0wMS0xNyw0LDUtYm9lLTYzOSwyLDEwMzUuNjQsZmFsc2UsbG93CjksMjAxNi0wMS0yMFQwNDozMDowMC4wMDAwMDAsMjAxNi0wMS0yMCwzLDUtYmNlLTY0Miw5LDgzNy45MyxmYWxzZSxoaWdoCjEwLDIwMTYtMDEtMjBUMDQ6MzA6MDAuMDAwMDAwLDIwMTYtMDEtMjAsMyw1LWJjZS02NDIsOSw4MzcuOTMsZmFsc2UsaGlnaAoxMSwyMDE2LTAxLTI2VDIwOjA3OjAwLjAwMDAwMCwyMDE2LTAxLTI2LDQsMi1kbXgtMDEwLDcsODMzLjk4LHRydWUsbG93CjEyLDIwMTYtMDEtMjhUMDI6NTE6MDAuMDAwMDAwLDIwMTYtMDEtMjgsMiw3LWRteC0wMTAsOCwxMDguMzQsZmFsc2UsbG93CjEzLDIwMTYtMDEtMzBUMTE6MjM6MDAuMDAwMDAwLDIwMTYtMDEtMzAsMSwzLWRrYS0zMDMsLDIyMzAuMDksdHJ1ZSxoaWdoCg==" download="extract_0001.csv"><button style="background-color: #67C2DC; color: #FFFFFF; border: none; padding: 5px; font-weight: bold; cursor: pointer; border-radius: 4px;">CSV</button></a></td></p>
  </tr>
</tbody>
</table>
</div>
<p>The metadata dictionary contains essential fields for a given validation step, including the step
number, column name, validation type, severity level, and failure explanation. This gives you
complete flexibility to create highly customized responses based on the specific nature of the
validation failure.</p>
<h2 id="final-actions-with-finalactions">Final Actions with <code>FinalActions</code>
</h2>
<p>While regular <a href="https://posit-dev.github.io/pointblank/reference/Actions.html" target="_blank" rel="noopener"><code>Actions</code></a>
 are great
for responding to individual validation steps, sometimes you need to take action based on the
overall validation results. This is where the new <code>FinalActions</code> feature from <code>v0.8.1</code> comes in.</p>
<p>Unlike regular <a href="https://posit-dev.github.io/pointblank/reference/Actions.html" target="_blank" rel="noopener"><code>Actions</code></a>
 that
trigger during validation,
<a href="https://posit-dev.github.io/pointblank/reference/FinalActions.html" target="_blank" rel="noopener"><code>FinalActions</code></a>
 execute after
all validation steps are complete.
<a href="https://posit-dev.github.io/pointblank/reference/FinalActions.html" target="_blank" rel="noopener"><code>FinalActions</code></a>
 accepts any
number of actions (strings or callables) and executes them in sequence. Each argument can be a
string message to display in the console, a callable function, or a list of strings/callables for
multiple actions to execute in sequence.</p>
<p>The real power of <a href="https://posit-dev.github.io/pointblank/reference/FinalActions.html" target="_blank" rel="noopener"><code>FinalActions</code></a>

comes from the ability to access comprehensive information about your validation results using
<a href="https://posit-dev.github.io/pointblank/reference/get_validation_summary.html" target="_blank" rel="noopener"><code>get_validation_summary()</code></a>
.
When called inside a function passed to
<a href="https://posit-dev.github.io/pointblank/reference/FinalActions.html" target="_blank" rel="noopener"><code>FinalActions</code></a>
, this function
provides a dictionary containing counts of passing/failing steps and test units, threshold levels
exceeded, and much more:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">generate_summary</span><span class="p">():</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># Access comprehensive validation results</span>
</span></span><span class="line"><span class="cl">    <span class="n">summary</span> <span class="o">=</span> <span class="n">pb</span><span class="o">.</span><span class="n">get_validation_summary</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;</span><span class="se">\n</span><span class="s2">=== VALIDATION SUMMARY ===&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;Total steps: </span><span class="si">{</span><span class="n">summary</span><span class="p">[</span><span class="s1">&#39;n_steps&#39;</span><span class="p">]</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;Passing steps: </span><span class="si">{</span><span class="n">summary</span><span class="p">[</span><span class="s1">&#39;n_passing_steps&#39;</span><span class="p">]</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;Failing steps: </span><span class="si">{</span><span class="n">summary</span><span class="p">[</span><span class="s1">&#39;n_failing_steps&#39;</span><span class="p">]</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="n">summary</span><span class="p">[</span><span class="s1">&#39;highest_severity&#39;</span><span class="p">]</span> <span class="o">==</span> <span class="s2">&#34;critical&#34;</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;</span><span class="se">\n</span><span class="s2">⚠️ CRITICAL FAILURES DETECTED - immediate action required!&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">elif</span> <span class="n">summary</span><span class="p">[</span><span class="s1">&#39;highest_severity&#39;</span><span class="p">]</span> <span class="o">==</span> <span class="s2">&#34;error&#34;</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;</span><span class="se">\n</span><span class="s2">⚠️ ERRORS DETECTED - review needed&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">elif</span> <span class="n">summary</span><span class="p">[</span><span class="s1">&#39;highest_severity&#39;</span><span class="p">]</span> <span class="o">==</span> <span class="s2">&#34;warning&#34;</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;</span><span class="se">\n</span><span class="s2">⚠️ WARNINGS DETECTED - please investigate&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">else</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;</span><span class="se">\n</span><span class="s2">✅ All validations passed!&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">validation_5</span> <span class="o">=</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">pb</span><span class="o">.</span><span class="n">Validate</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="n">data</span><span class="o">=</span><span class="n">pb</span><span class="o">.</span><span class="n">load_dataset</span><span class="p">(</span><span class="n">dataset</span><span class="o">=</span><span class="s2">&#34;small_table&#34;</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">        <span class="n">tbl_name</span><span class="o">=</span><span class="s2">&#34;small_table&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="n">thresholds</span><span class="o">=</span><span class="n">pb</span><span class="o">.</span><span class="n">Thresholds</span><span class="p">(</span><span class="n">warning</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">error</span><span class="o">=</span><span class="mi">5</span><span class="p">,</span> <span class="n">critical</span><span class="o">=</span><span class="mi">10</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">        <span class="n">final_actions</span><span class="o">=</span><span class="n">pb</span><span class="o">.</span><span class="n">FinalActions</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">            <span class="s2">&#34;Validation process complete.&#34;</span><span class="p">,</span>  <span class="c1"># A simple string message</span>
</span></span><span class="line"><span class="cl">            <span class="n">generate_summary</span>               <span class="c1"># Our function using get_validation_summary()</span>
</span></span><span class="line"><span class="cl">        <span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">col_vals_gt</span><span class="p">(</span><span class="n">columns</span><span class="o">=</span><span class="s2">&#34;a&#34;</span><span class="p">,</span> <span class="n">value</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">col_vals_lt</span><span class="p">(</span><span class="n">columns</span><span class="o">=</span><span class="s2">&#34;d&#34;</span><span class="p">,</span> <span class="n">value</span><span class="o">=</span><span class="mi">10000</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">interrogate</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">validation_5</span>
</span></span></code></pre></td></tr></table>
</div>
</div><pre><code>Validation process complete.

=== VALIDATION SUMMARY ===
Total steps: 2
Passing steps: 1
Failing steps: 1

⚠️ WARNINGS DETECTED - please investigate
</code></pre>
<div id="pb_tbl" style="padding-left:0px;padding-right:0px;padding-top:10px;padding-bottom:10px;overflow-x:auto;overflow-y:auto;width:auto;height:auto;">
<style>
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono&display=swap');
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans&display=swap');
#pb_tbl table {
          font-family: 'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Helvetica Neue', 'Fira Sans', 'Droid Sans', Arial, sans-serif;
          -webkit-font-smoothing: antialiased;
          -moz-osx-font-smoothing: grayscale;
        }
<p>#pb_tbl thead, tbody, tfoot, tr, td, th { border-style: none; }
tr { background-color: transparent; }
#pb_tbl p { margin: 0; padding: 0; }
#pb_tbl .gt_table { display: table; border-collapse: collapse; line-height: normal; margin-left: auto; margin-right: auto; color: #333333; font-size: 90%; font-weight: normal; font-style: normal; background-color: #FFFFFF; width: auto; border-top-style: solid; border-top-width: 2px; border-top-color: #A8A8A8; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #A8A8A8; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; }
#pb_tbl .gt_caption { padding-top: 4px; padding-bottom: 4px; }
#pb_tbl .gt_title { color: #333333; font-size: 125%; font-weight: initial; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; border-bottom-color: #FFFFFF; border-bottom-width: 0; }
#pb_tbl .gt_subtitle { color: #333333; font-size: 85%; font-weight: initial; padding-top: 3px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; border-top-color: #FFFFFF; border-top-width: 0; }
#pb_tbl .gt_heading { background-color: #FFFFFF; text-align: left; border-bottom-color: #FFFFFF; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; }
#pb_tbl .gt_bottom_border { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; }
#pb_tbl .gt_col_headings { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; }
#pb_tbl .gt_col_heading { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; overflow-x: hidden; }
#pb_tbl .gt_column_spanner_outer { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; padding-top: 0; padding-bottom: 0; padding-left: 4px; padding-right: 4px; }
#pb_tbl .gt_column_spanner_outer:first-child { padding-left: 0; }
#pb_tbl .gt_column_spanner_outer:last-child { padding-right: 0; }
#pb_tbl .gt_column_spanner { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; overflow-x: hidden; display: inline-block; width: 100%; }
#pb_tbl .gt_spanner_row { border-bottom-style: hidden; }
#pb_tbl .gt_group_heading { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; text-align: left; }
#pb_tbl .gt_empty_group_heading { padding: 0.5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: middle; }
#pb_tbl .gt_from_md&gt; :first-child { margin-top: 0; }
#pb_tbl .gt_from_md&gt; :last-child { margin-bottom: 0; }
#pb_tbl .gt_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; margin: 10px; border-top-style: solid; border-top-width: 1px; border-top-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; overflow-x: hidden; }
#pb_tbl .gt_stub { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; }
#pb_tbl .gt_stub_row_group { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; vertical-align: top; }
#pb_tbl .gt_row_group_first td { border-top-width: 2px; }
#pb_tbl .gt_row_group_first th { border-top-width: 2px; }
#pb_tbl .gt_striped { color: #333333; background-color: #F4F4F4; }
#pb_tbl .gt_table_body { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; }
#pb_tbl .gt_grand_summary_row { color: #333333; background-color: #FFFFFF; text-transform: inherit; padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; }
#pb_tbl .gt_first_grand_summary_row_bottom { border-top-style: double; border-top-width: 6px; border-top-color: #D3D3D3; }
#pb_tbl .gt_last_grand_summary_row_top { border-bottom-style: double; border-bottom-width: 6px; border-bottom-color: #D3D3D3; }
#pb_tbl .gt_sourcenotes { color: #333333; background-color: #FFFFFF; border-bottom-style: none; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; }
#pb_tbl .gt_sourcenote { font-size: 90%; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; text-align: left; }
#pb_tbl .gt_left { text-align: left; }
#pb_tbl .gt_center { text-align: center; }
#pb_tbl .gt_right { text-align: right; font-variant-numeric: tabular-nums; }
#pb_tbl .gt_font_normal { font-weight: normal; }
#pb_tbl .gt_font_bold { font-weight: bold; }
#pb_tbl .gt_font_italic { font-style: italic; }
#pb_tbl .gt_super { font-size: 65%; }
#pb_tbl .gt_footnote_marks { font-size: 75%; vertical-align: 0.4em; position: initial; }
#pb_tbl .gt_asterisk { font-size: 100%; vertical-align: 0; }</p>
<p></style></p>
<table style="table-layout: fixed;; width: 0px" class="gt_table" data-quarto-disable-processing="true" data-quarto-bootstrap="false">
<colgroup>
  <col style="width:4px;"/>
  <col style="width:35px;"/>
  <col style="width:190px;"/>
  <col style="width:120px;"/>
  <col style="width:120px;"/>
  <col style="width:50px;"/>
  <col style="width:50px;"/>
  <col style="width:60px;"/>
  <col style="width:60px;"/>
  <col style="width:60px;"/>
  <col style="width:30px;"/>
  <col style="width:30px;"/>
  <col style="width:30px;"/>
  <col style="width:65px;"/>
</colgroup>
<thead>
  <tr class="gt_heading">
    <td colspan="14" class="gt_heading gt_title gt_font_normal" style="color: #444444;font-size: 28px;text-align: left;font-weight: bold; text-align: left;">Pointblank Validation</td>
  </tr>
  <tr class="gt_heading">
    <td colspan="14" class="gt_heading gt_subtitle gt_font_normal gt_bottom_border" style="text-align: left;"><div><span style='text-decoration-style: solid; text-decoration-color: #ADD8E6; text-decoration-line: underline; text-underline-position: under; color: #333333; font-variant-numeric: tabular-nums; padding-left: 4px; margin-right: 5px; padding-right: 2px;'>2026-03-13|19:09:29</span><div style="padding-top: 10px; padding-bottom: 5px;"><span style='background-color: #0075FF; color: #FFFFFF; padding: 0.5em 0.5em; position: inherit; text-transform: uppercase; margin: 5px 0px 5px 0px; border: solid 1px #0075FF; font-weight: bold; padding: 2px 15px 2px 15px; font-size: 10px;'>Polars</span><span style='background-color: none; color: #222222; padding: 0.5em 0.5em; position: inherit; margin: 5px 10px 5px -4px; border: solid 1px #0075FF; font-weight: bold; padding: 2px 15px 2px 15px; font-size: 10px;'>small_table</span><span><span style="background-color: #AAAAAA; color: white; padding: 0.5em 0.5em; position: inherit; text-transform: uppercase; margin: 5px 0px 5px 5px; border: solid 1px #AAAAAA; font-weight: bold; padding: 2px 15px 2px 15px; font-size: smaller;">WARNING</span><span style="background-color: none; color: #333333; padding: 0.5em 0.5em; position: inherit; margin: 5px 0px 5px -4px; font-weight: bold; border: solid 1px #AAAAAA; padding: 2px 15px 2px 15px; font-size: smaller; margin-right: 5px;">1</span><span style="background-color: #EBBC14; color: white; padding: 0.5em 0.5em; position: inherit; text-transform: uppercase; margin: 5px 0px 5px 1px; border: solid 1px #EBBC14; font-weight: bold; padding: 2px 15px 2px 15px; font-size: smaller;">ERROR</span><span style="background-color: none; color: #333333; padding: 0.5em 0.5em; position: inherit; margin: 5px 0px 5px -4px; font-weight: bold; border: solid 1px #EBBC14; padding: 2px 15px 2px 15px; font-size: smaller; margin-right: 5px;">5</span><span style="background-color: #FF3300; color: white; padding: 0.5em 0.5em; position: inherit; text-transform: uppercase; margin: 5px 0px 5px 1px; border: solid 1px #FF3300; font-weight: bold; padding: 2px 15px 2px 15px; font-size: smaller;">CRITICAL</span><span style="background-color: none; color: #333333; padding: 0.5em 0.5em; position: inherit; margin: 5px 0px 5px -4px; font-weight: bold; border: solid 1px #FF3300; padding: 2px 15px 2px 15px; font-size: smaller;">10</span></span></div></div></td>
  </tr>
<tr class="gt_col_headings">
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-status_color"></th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-i"></th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-type_upd">STEP</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-columns_upd">COLUMNS</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-values_upd">VALUES</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-tbl">TBL</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-eval">EVAL</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-test_units">UNITS</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-pass">PASS</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-fail">FAIL</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-w_upd">W</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-e_upd">E</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-c_upd">C</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-extract_upd">EXT</th>
</tr>
</thead>
<tbody class="gt_table_body">
  <tr>
    <td style="height: 40px; background-color: #AAAAAA; color: transparent;font-size: 0px;" class="gt_row gt_left">#AAAAAA</td>
    <td style="height: 40px; color: #666666;font-size: 13px;font-weight: bold;" class="gt_row gt_right">1</td>
    <td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_left">
        <div style="margin: 0; padding: 0; display: inline-block; height: 30px; vertical-align: middle; width: 16%;">
            <!--?xml version="1.0" encoding="UTF-8"?--><?xml version="1.0" encoding="UTF-8"?>
<svg width="30px" height="30px" viewBox="0 0 67 67" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="background: #FFFFFF;">
    <title>col_vals_gt</title>
    <g id="Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="col_vals_gt" transform="translate(1.500000, 1.500000)" fill-rule="nonzero">
            <path d="M55,0 C57.4852813,0 59.7352813,1.00735931 61.363961,2.63603897 C62.9926407,4.26471863 64,6.51471863 64,9 L64,9 L64,64 L9,64 C6.51471862,64 4.26471862,62.9926407 2.63603897,61.363961 C1.00735931,59.7352814 0,57.4852814 0,55 L0,55 L0,9 C0,6.51471863 1.00735931,4.26471863 2.63603897,2.63603897 C4.26471862,1.00735931 6.51471862,0 9,0 L9,0 L55,0 Z" id="rectangle" stroke="#000000" stroke-width="2" fill="#FFFFFF"></path>
            <path d="M48.7619048,10 L15.2380953,10 C12.3466667,10 10,12.3466667 10,15.2380952 L10,48.7619048 C10,51.6533333 12.3466667,54 15.2380953,54 L48.7619048,54 C51.6533333,54 54,51.6533333 54,48.7619048 L54,15.2380952 C54,12.3466667 51.6533333,10 48.7619048,10 Z M25.2638095,44.3828571 L24.0695238,42.6647619 L39.5847619,32 L24.0695238,21.3352381 L25.2638095,19.6171429 L43.2828572,32 L25.2638095,44.3828571 Z" id="greater_than" fill="#000000"></path>
        </g>
    </g>
</svg>
        </div>
        <div style="font-family: 'IBM Plex Mono', monospace, courier; color: black; font-size: 11px; display: inline-block; vertical-align: middle;">
            <div>col_vals_gt()</div>
        </div>
<pre><code>    &lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;a&lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;1&lt;/td&gt;
&lt;td style=&quot;height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;&quot; class=&quot;gt_row gt_center&quot;&gt;&lt;svg width=&quot;25px&quot; height=&quot;25px&quot; viewBox=&quot;0 0 25 25&quot; version=&quot;1.1&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot; style=&quot;vertical-align: middle;&quot;&gt;
&lt;g id=&quot;unchanged&quot; stroke=&quot;none&quot; stroke-width=&quot;1&quot; fill=&quot;none&quot; fill-rule=&quot;evenodd&quot;&gt;
    &lt;g id=&quot;unchanged&quot; transform=&quot;translate(0.500000, 0.570147)&quot;&gt;
        &lt;rect id=&quot;Rectangle&quot; x=&quot;0.125132506&quot; y=&quot;0&quot; width=&quot;23.749735&quot; height=&quot;23.7894737&quot;&gt;&lt;/rect&gt;
        &lt;path d=&quot;M5.80375046,8.18194736 C3.77191832,8.18194736 2.11875046,9.83495328 2.11875046,11.8669474 C2.11875046,13.8989414 3.77191832,15.5519474 5.80375046,15.5519474 C7.8355826,15.5519474 9.48875046,13.8989414 9.48875046,11.8669474 C9.48875046,9.83495328 7.83552863,8.18194736 5.80375046,8.18194736 Z M5.80375046,14.814915 C4.17821997,14.814915 2.85578285,13.4924778 2.85578285,11.8669474 C2.85578285,10.2414169 4.17821997,8.91897975 5.80375046,8.91897975 C7.42928095,8.91897975 8.75171807,10.2414169 8.75171807,11.8669474 C8.75171807,13.4924778 7.42928095,14.814915 5.80375046,14.814915 Z&quot; id=&quot;Shape&quot; fill=&quot;#000000&quot; fill-rule=&quot;nonzero&quot;&gt;&lt;/path&gt;
        &lt;path d=&quot;M13.9638189,8.699335 C13.9364621,8.70430925 13.9091059,8.71176968 13.8842359,8.71923074 C13.7822704,8.73663967 13.6877654,8.77643115 13.6056956,8.83860518 L10.2433156,11.3852598 C10.0766886,11.5046343 9.97720993,11.6986181 9.97720993,11.9025491 C9.97720993,12.1064807 10.0766886,12.3004639 10.2433156,12.4198383 L13.6056956,14.966493 C13.891697,15.1803725 14.2970729,15.1231721 14.5109517,14.8371707 C14.7248313,14.5511692 14.6676309,14.145794 14.3816294,13.9319145 L12.5313257,12.5392127 L21.8812495,12.5392127 L21.8812495,11.2658854 L12.5313257,11.2658854 L14.3816294,9.87318364 C14.6377872,9.71650453 14.7497006,9.40066014 14.6477351,9.11714553 C14.5482564,8.83363156 14.262255,8.65954352 13.9638189,8.699335 Z&quot; id=&quot;arrow&quot; fill=&quot;#000000&quot; transform=&quot;translate(15.929230, 11.894737) rotate(-180.000000) translate(-15.929230, -11.894737) &quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
&lt;/g&gt;
</code></pre>
<p></svg></td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color:#4CA64C;">✓</span></td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_right">13</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">12<br />0.92</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">1<br />0.08</td>
<td style="height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color: #AAAAAA;">●</span></td>
<td style="height: 40px; background-color: #FCFCFC;" class="gt_row gt_center"><span style="color: #EBBC14;">○</span></td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color: #FF3300;">○</span></td>
<td style="height: 40px;" class="gt_row gt_center"><a href="data:text/csv;base64,X3Jvd19udW1fLGRhdGVfdGltZSxkYXRlLGEsYixjLGQsZSxmCjEzLDIwMTYtMDEtMzBUMTE6MjM6MDAuMDAwMDAwLDIwMTYtMDEtMzAsMSwzLWRrYS0zMDMsLDIyMzAuMDksdHJ1ZSxoaWdoCg==" download="extract_0001.csv"><button style="background-color: #67C2DC; color: #FFFFFF; border: none; padding: 5px; font-weight: bold; cursor: pointer; border-radius: 4px;">CSV</button></a></td></p>
  </tr>
  <tr>
    <td style="height: 40px; background-color: #4CA64C; color: transparent;font-size: 0px;" class="gt_row gt_left">#4CA64C</td>
    <td style="height: 40px; color: #666666;font-size: 13px;font-weight: bold;" class="gt_row gt_right">2</td>
    <td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_left">
        <div style="margin: 0; padding: 0; display: inline-block; height: 30px; vertical-align: middle; width: 16%;">
            <!--?xml version="1.0" encoding="UTF-8"?--><?xml version="1.0" encoding="UTF-8"?>
<svg width="30px" height="30px" viewBox="0 0 67 67" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="background: #FFFFFF;">
    <title>col_vals_lt</title>
    <g id="Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="col_vals_lt" transform="translate(1.500000, 1.500000)" fill-rule="nonzero">
            <path d="M55,0 C57.4852813,0 59.7352813,1.00735931 61.363961,2.63603897 C62.9926407,4.26471863 64,6.51471863 64,9 L64,9 L64,64 L9,64 C6.51471862,64 4.26471862,62.9926407 2.63603897,61.363961 C1.00735931,59.7352814 0,57.4852814 0,55 L0,55 L0,9 C0,6.51471863 1.00735931,4.26471863 2.63603897,2.63603897 C4.26471862,1.00735931 6.51471862,0 9,0 L9,0 L55,0 Z" id="rectangle" stroke="#000000" stroke-width="2" fill="#FFFFFF"></path>
            <path d="M51,10 L13,10 C11.347656,10 10,11.347656 10,13 L10,51 C10,52.652344 11.347656,54 13,54 L51,54 C52.652344,54 54,52.652344 54,51 L54,13 C54,11.347656 52.652344,10 51,10 Z M38.707031,45.292969 L37.292969,46.707031 L22.585938,32 L37.292969,17.292969 L38.707031,18.707031 L25.414063,32 L38.707031,45.292969 Z" id="less_than" fill="#000000"></path>
        </g>
    </g>
</svg>
        </div>
        <div style="font-family: 'IBM Plex Mono', monospace, courier; color: black; font-size: 11px; display: inline-block; vertical-align: middle;">
            <div>col_vals_lt()</div>
        </div>
<pre><code>    &lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;d&lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;10000&lt;/td&gt;
&lt;td style=&quot;height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;&quot; class=&quot;gt_row gt_center&quot;&gt;&lt;svg width=&quot;25px&quot; height=&quot;25px&quot; viewBox=&quot;0 0 25 25&quot; version=&quot;1.1&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot; style=&quot;vertical-align: middle;&quot;&gt;
&lt;g id=&quot;unchanged&quot; stroke=&quot;none&quot; stroke-width=&quot;1&quot; fill=&quot;none&quot; fill-rule=&quot;evenodd&quot;&gt;
    &lt;g id=&quot;unchanged&quot; transform=&quot;translate(0.500000, 0.570147)&quot;&gt;
        &lt;rect id=&quot;Rectangle&quot; x=&quot;0.125132506&quot; y=&quot;0&quot; width=&quot;23.749735&quot; height=&quot;23.7894737&quot;&gt;&lt;/rect&gt;
        &lt;path d=&quot;M5.80375046,8.18194736 C3.77191832,8.18194736 2.11875046,9.83495328 2.11875046,11.8669474 C2.11875046,13.8989414 3.77191832,15.5519474 5.80375046,15.5519474 C7.8355826,15.5519474 9.48875046,13.8989414 9.48875046,11.8669474 C9.48875046,9.83495328 7.83552863,8.18194736 5.80375046,8.18194736 Z M5.80375046,14.814915 C4.17821997,14.814915 2.85578285,13.4924778 2.85578285,11.8669474 C2.85578285,10.2414169 4.17821997,8.91897975 5.80375046,8.91897975 C7.42928095,8.91897975 8.75171807,10.2414169 8.75171807,11.8669474 C8.75171807,13.4924778 7.42928095,14.814915 5.80375046,14.814915 Z&quot; id=&quot;Shape&quot; fill=&quot;#000000&quot; fill-rule=&quot;nonzero&quot;&gt;&lt;/path&gt;
        &lt;path d=&quot;M13.9638189,8.699335 C13.9364621,8.70430925 13.9091059,8.71176968 13.8842359,8.71923074 C13.7822704,8.73663967 13.6877654,8.77643115 13.6056956,8.83860518 L10.2433156,11.3852598 C10.0766886,11.5046343 9.97720993,11.6986181 9.97720993,11.9025491 C9.97720993,12.1064807 10.0766886,12.3004639 10.2433156,12.4198383 L13.6056956,14.966493 C13.891697,15.1803725 14.2970729,15.1231721 14.5109517,14.8371707 C14.7248313,14.5511692 14.6676309,14.145794 14.3816294,13.9319145 L12.5313257,12.5392127 L21.8812495,12.5392127 L21.8812495,11.2658854 L12.5313257,11.2658854 L14.3816294,9.87318364 C14.6377872,9.71650453 14.7497006,9.40066014 14.6477351,9.11714553 C14.5482564,8.83363156 14.262255,8.65954352 13.9638189,8.699335 Z&quot; id=&quot;arrow&quot; fill=&quot;#000000&quot; transform=&quot;translate(15.929230, 11.894737) rotate(-180.000000) translate(-15.929230, -11.894737) &quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
&lt;/g&gt;
</code></pre>
<p></svg></td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color:#4CA64C;">✓</span></td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_right">13</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">13<br />1.00</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">0<br />0.00</td>
<td style="height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color: #AAAAAA;">○</span></td>
<td style="height: 40px; background-color: #FCFCFC;" class="gt_row gt_center"><span style="color: #EBBC14;">○</span></td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color: #FF3300;">○</span></td>
<td style="height: 40px;" class="gt_row gt_center">—</td></p>
  </tr>
</tbody>
</table>
</div>
<p>The <a href="https://posit-dev.github.io/pointblank/reference/get_validation_summary.html" target="_blank" rel="noopener"><code>get_validation_summary()</code></a>

function is only available within functions passed to
<a href="https://posit-dev.github.io/pointblank/reference/FinalActions.html" target="_blank" rel="noopener"><code>FinalActions</code></a>
. It gives you
access to these key dictionary fields:</p>
<ul>
<li><code>tbl_name</code>: name of the validated table</li>
<li><code>n_steps</code>: total number of validation steps</li>
<li><code>n_passing_steps</code>, n_failing_steps: count of passing/failing steps</li>
<li><code>n</code>, <code>n_passed</code>, <code>n_failed</code>: total test units and their pass/fail counts</li>
<li><code>highest_severity</code>: the most severe threshold level reached (&lsquo;warning&rsquo;, &rsquo;error&rsquo;, &lsquo;critical&rsquo;)</li>
<li>and many more detailed statistics</li>
</ul>
<p>This information allows you to create detailed and specific final actions that can respond
appropriately to the overall validation results.</p>
<h2 id="combining-regular-and-final-actions">Combining Regular and Final Actions
</h2>
<p>You can use both <a href="https://posit-dev.github.io/pointblank/reference/Actions.html" target="_blank" rel="noopener"><code>Actions</code></a>
 and
<a href="https://posit-dev.github.io/pointblank/reference/FinalActions.html" target="_blank" rel="noopener"><code>FinalActions</code></a>
 together for
comprehensive control over your validation workflow:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">step_alert</span><span class="p">():</span>
</span></span><span class="line"><span class="cl">    <span class="n">metadata</span> <span class="o">=</span> <span class="n">pb</span><span class="o">.</span><span class="n">get_action_metadata</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;Step </span><span class="si">{</span><span class="n">metadata</span><span class="p">[</span><span class="s1">&#39;step&#39;</span><span class="p">]</span><span class="si">}</span><span class="s2"> failed with </span><span class="si">{</span><span class="n">metadata</span><span class="p">[</span><span class="s1">&#39;level&#39;</span><span class="p">]</span><span class="si">}</span><span class="s2"> severity&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">final_summary</span><span class="p">():</span>
</span></span><span class="line"><span class="cl">    <span class="n">summary</span> <span class="o">=</span> <span class="n">pb</span><span class="o">.</span><span class="n">get_validation_summary</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># Get counts by checking each step&#39;s status in the dictionaries</span>
</span></span><span class="line"><span class="cl">    <span class="n">steps</span> <span class="o">=</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">summary</span><span class="p">[</span><span class="s1">&#39;n_steps&#39;</span><span class="p">]</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">n_critical</span> <span class="o">=</span> <span class="nb">sum</span><span class="p">(</span><span class="mi">1</span> <span class="k">for</span> <span class="n">step</span> <span class="ow">in</span> <span class="n">steps</span> <span class="k">if</span> <span class="n">summary</span><span class="p">[</span><span class="s1">&#39;dict_critical&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">step</span><span class="p">,</span> <span class="kc">False</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">    <span class="n">n_error</span> <span class="o">=</span> <span class="nb">sum</span><span class="p">(</span><span class="mi">1</span> <span class="k">for</span> <span class="n">step</span> <span class="ow">in</span> <span class="n">steps</span> <span class="k">if</span> <span class="n">summary</span><span class="p">[</span><span class="s1">&#39;dict_error&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">step</span><span class="p">,</span> <span class="kc">False</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">    <span class="n">n_warning</span> <span class="o">=</span> <span class="nb">sum</span><span class="p">(</span><span class="mi">1</span> <span class="k">for</span> <span class="n">step</span> <span class="ow">in</span> <span class="n">steps</span> <span class="k">if</span> <span class="n">summary</span><span class="p">[</span><span class="s1">&#39;dict_warning&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">step</span><span class="p">,</span> <span class="kc">False</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;</span><span class="se">\n</span><span class="s2">Validation complete with:&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;- </span><span class="si">{</span><span class="n">n_critical</span><span class="si">}</span><span class="s2"> critical issues&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;- </span><span class="si">{</span><span class="n">n_error</span><span class="si">}</span><span class="s2"> errors&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;- </span><span class="si">{</span><span class="n">n_warning</span><span class="si">}</span><span class="s2"> warnings&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">validation_6</span> <span class="o">=</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">pb</span><span class="o">.</span><span class="n">Validate</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="n">data</span><span class="o">=</span><span class="n">pb</span><span class="o">.</span><span class="n">load_dataset</span><span class="p">(</span><span class="n">dataset</span><span class="o">=</span><span class="s2">&#34;small_table&#34;</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">        <span class="n">thresholds</span><span class="o">=</span><span class="n">pb</span><span class="o">.</span><span class="n">Thresholds</span><span class="p">(</span><span class="n">warning</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">error</span><span class="o">=</span><span class="mi">5</span><span class="p">,</span> <span class="n">critical</span><span class="o">=</span><span class="mi">10</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">        <span class="n">actions</span><span class="o">=</span><span class="n">pb</span><span class="o">.</span><span class="n">Actions</span><span class="p">(</span><span class="n">default</span><span class="o">=</span><span class="n">step_alert</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">        <span class="n">final_actions</span><span class="o">=</span><span class="n">pb</span><span class="o">.</span><span class="n">FinalActions</span><span class="p">(</span><span class="n">final_summary</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">    <span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">col_vals_gt</span><span class="p">(</span><span class="n">columns</span><span class="o">=</span><span class="s2">&#34;a&#34;</span><span class="p">,</span> <span class="n">value</span><span class="o">=</span><span class="mi">5</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">col_vals_lt</span><span class="p">(</span><span class="n">columns</span><span class="o">=</span><span class="s2">&#34;d&#34;</span><span class="p">,</span> <span class="n">value</span><span class="o">=</span><span class="mi">1000</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">interrogate</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">validation_6</span>
</span></span></code></pre></td></tr></table>
</div>
</div><pre><code>Step 1 failed with critical severity
Step 2 failed with error severity

Validation complete with:
- 1 critical issues
- 2 errors
- 2 warnings
</code></pre>
<div id="pb_tbl" style="padding-left:0px;padding-right:0px;padding-top:10px;padding-bottom:10px;overflow-x:auto;overflow-y:auto;width:auto;height:auto;">
<style>
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono&display=swap');
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans&display=swap');
#pb_tbl table {
          font-family: 'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Helvetica Neue', 'Fira Sans', 'Droid Sans', Arial, sans-serif;
          -webkit-font-smoothing: antialiased;
          -moz-osx-font-smoothing: grayscale;
        }
<p>#pb_tbl thead, tbody, tfoot, tr, td, th { border-style: none; }
tr { background-color: transparent; }
#pb_tbl p { margin: 0; padding: 0; }
#pb_tbl .gt_table { display: table; border-collapse: collapse; line-height: normal; margin-left: auto; margin-right: auto; color: #333333; font-size: 90%; font-weight: normal; font-style: normal; background-color: #FFFFFF; width: auto; border-top-style: solid; border-top-width: 2px; border-top-color: #A8A8A8; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #A8A8A8; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; }
#pb_tbl .gt_caption { padding-top: 4px; padding-bottom: 4px; }
#pb_tbl .gt_title { color: #333333; font-size: 125%; font-weight: initial; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; border-bottom-color: #FFFFFF; border-bottom-width: 0; }
#pb_tbl .gt_subtitle { color: #333333; font-size: 85%; font-weight: initial; padding-top: 3px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; border-top-color: #FFFFFF; border-top-width: 0; }
#pb_tbl .gt_heading { background-color: #FFFFFF; text-align: left; border-bottom-color: #FFFFFF; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; }
#pb_tbl .gt_bottom_border { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; }
#pb_tbl .gt_col_headings { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; }
#pb_tbl .gt_col_heading { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; overflow-x: hidden; }
#pb_tbl .gt_column_spanner_outer { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; padding-top: 0; padding-bottom: 0; padding-left: 4px; padding-right: 4px; }
#pb_tbl .gt_column_spanner_outer:first-child { padding-left: 0; }
#pb_tbl .gt_column_spanner_outer:last-child { padding-right: 0; }
#pb_tbl .gt_column_spanner { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; overflow-x: hidden; display: inline-block; width: 100%; }
#pb_tbl .gt_spanner_row { border-bottom-style: hidden; }
#pb_tbl .gt_group_heading { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; text-align: left; }
#pb_tbl .gt_empty_group_heading { padding: 0.5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: middle; }
#pb_tbl .gt_from_md&gt; :first-child { margin-top: 0; }
#pb_tbl .gt_from_md&gt; :last-child { margin-bottom: 0; }
#pb_tbl .gt_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; margin: 10px; border-top-style: solid; border-top-width: 1px; border-top-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; overflow-x: hidden; }
#pb_tbl .gt_stub { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; }
#pb_tbl .gt_stub_row_group { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; vertical-align: top; }
#pb_tbl .gt_row_group_first td { border-top-width: 2px; }
#pb_tbl .gt_row_group_first th { border-top-width: 2px; }
#pb_tbl .gt_striped { color: #333333; background-color: #F4F4F4; }
#pb_tbl .gt_table_body { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; }
#pb_tbl .gt_grand_summary_row { color: #333333; background-color: #FFFFFF; text-transform: inherit; padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; }
#pb_tbl .gt_first_grand_summary_row_bottom { border-top-style: double; border-top-width: 6px; border-top-color: #D3D3D3; }
#pb_tbl .gt_last_grand_summary_row_top { border-bottom-style: double; border-bottom-width: 6px; border-bottom-color: #D3D3D3; }
#pb_tbl .gt_sourcenotes { color: #333333; background-color: #FFFFFF; border-bottom-style: none; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; }
#pb_tbl .gt_sourcenote { font-size: 90%; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; text-align: left; }
#pb_tbl .gt_left { text-align: left; }
#pb_tbl .gt_center { text-align: center; }
#pb_tbl .gt_right { text-align: right; font-variant-numeric: tabular-nums; }
#pb_tbl .gt_font_normal { font-weight: normal; }
#pb_tbl .gt_font_bold { font-weight: bold; }
#pb_tbl .gt_font_italic { font-style: italic; }
#pb_tbl .gt_super { font-size: 65%; }
#pb_tbl .gt_footnote_marks { font-size: 75%; vertical-align: 0.4em; position: initial; }
#pb_tbl .gt_asterisk { font-size: 100%; vertical-align: 0; }</p>
<p></style></p>
<table style="table-layout: fixed;; width: 0px" class="gt_table" data-quarto-disable-processing="true" data-quarto-bootstrap="false">
<colgroup>
  <col style="width:4px;"/>
  <col style="width:35px;"/>
  <col style="width:190px;"/>
  <col style="width:120px;"/>
  <col style="width:120px;"/>
  <col style="width:50px;"/>
  <col style="width:50px;"/>
  <col style="width:60px;"/>
  <col style="width:60px;"/>
  <col style="width:60px;"/>
  <col style="width:30px;"/>
  <col style="width:30px;"/>
  <col style="width:30px;"/>
  <col style="width:65px;"/>
</colgroup>
<thead>
  <tr class="gt_heading">
    <td colspan="14" class="gt_heading gt_title gt_font_normal" style="color: #444444;font-size: 28px;text-align: left;font-weight: bold; text-align: left;">Pointblank Validation</td>
  </tr>
  <tr class="gt_heading">
    <td colspan="14" class="gt_heading gt_subtitle gt_font_normal gt_bottom_border" style="text-align: left;"><div><span style='text-decoration-style: solid; text-decoration-color: #ADD8E6; text-decoration-line: underline; text-underline-position: under; color: #333333; font-variant-numeric: tabular-nums; padding-left: 4px; margin-right: 5px; padding-right: 2px;'>2026-03-13|19:09:29</span><div style="padding-top: 10px; padding-bottom: 5px;"><span style='background-color: #0075FF; color: #FFFFFF; padding: 0.5em 0.5em; position: inherit; text-transform: uppercase; margin: 5px 10px 5px 0px; border: solid 1px #0075FF; font-weight: bold; padding: 2px 10px 2px 10px; font-size: 10px;'>Polars</span><span><span style="background-color: #AAAAAA; color: white; padding: 0.5em 0.5em; position: inherit; text-transform: uppercase; margin: 5px 0px 5px 5px; border: solid 1px #AAAAAA; font-weight: bold; padding: 2px 15px 2px 15px; font-size: smaller;">WARNING</span><span style="background-color: none; color: #333333; padding: 0.5em 0.5em; position: inherit; margin: 5px 0px 5px -4px; font-weight: bold; border: solid 1px #AAAAAA; padding: 2px 15px 2px 15px; font-size: smaller; margin-right: 5px;">1</span><span style="background-color: #EBBC14; color: white; padding: 0.5em 0.5em; position: inherit; text-transform: uppercase; margin: 5px 0px 5px 1px; border: solid 1px #EBBC14; font-weight: bold; padding: 2px 15px 2px 15px; font-size: smaller;">ERROR</span><span style="background-color: none; color: #333333; padding: 0.5em 0.5em; position: inherit; margin: 5px 0px 5px -4px; font-weight: bold; border: solid 1px #EBBC14; padding: 2px 15px 2px 15px; font-size: smaller; margin-right: 5px;">5</span><span style="background-color: #FF3300; color: white; padding: 0.5em 0.5em; position: inherit; text-transform: uppercase; margin: 5px 0px 5px 1px; border: solid 1px #FF3300; font-weight: bold; padding: 2px 15px 2px 15px; font-size: smaller;">CRITICAL</span><span style="background-color: none; color: #333333; padding: 0.5em 0.5em; position: inherit; margin: 5px 0px 5px -4px; font-weight: bold; border: solid 1px #FF3300; padding: 2px 15px 2px 15px; font-size: smaller;">10</span></span></div></div></td>
  </tr>
<tr class="gt_col_headings">
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-status_color"></th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-i"></th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-type_upd">STEP</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-columns_upd">COLUMNS</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-values_upd">VALUES</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-tbl">TBL</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-eval">EVAL</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-test_units">UNITS</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-pass">PASS</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-fail">FAIL</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-w_upd">W</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-e_upd">E</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-c_upd">C</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-extract_upd">EXT</th>
</tr>
</thead>
<tbody class="gt_table_body">
  <tr>
    <td style="height: 40px; background-color: #FF3300; color: transparent;font-size: 0px;" class="gt_row gt_left">#FF3300</td>
    <td style="height: 40px; color: #666666;font-size: 13px;font-weight: bold;" class="gt_row gt_right">1</td>
    <td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_left">
        <div style="margin: 0; padding: 0; display: inline-block; height: 30px; vertical-align: middle; width: 16%;">
            <!--?xml version="1.0" encoding="UTF-8"?--><?xml version="1.0" encoding="UTF-8"?>
<svg width="30px" height="30px" viewBox="0 0 67 67" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="background: #FFFFFF;">
    <title>col_vals_gt</title>
    <g id="Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="col_vals_gt" transform="translate(1.500000, 1.500000)" fill-rule="nonzero">
            <path d="M55,0 C57.4852813,0 59.7352813,1.00735931 61.363961,2.63603897 C62.9926407,4.26471863 64,6.51471863 64,9 L64,9 L64,64 L9,64 C6.51471862,64 4.26471862,62.9926407 2.63603897,61.363961 C1.00735931,59.7352814 0,57.4852814 0,55 L0,55 L0,9 C0,6.51471863 1.00735931,4.26471863 2.63603897,2.63603897 C4.26471862,1.00735931 6.51471862,0 9,0 L9,0 L55,0 Z" id="rectangle" stroke="#000000" stroke-width="2" fill="#FFFFFF"></path>
            <path d="M48.7619048,10 L15.2380953,10 C12.3466667,10 10,12.3466667 10,15.2380952 L10,48.7619048 C10,51.6533333 12.3466667,54 15.2380953,54 L48.7619048,54 C51.6533333,54 54,51.6533333 54,48.7619048 L54,15.2380952 C54,12.3466667 51.6533333,10 48.7619048,10 Z M25.2638095,44.3828571 L24.0695238,42.6647619 L39.5847619,32 L24.0695238,21.3352381 L25.2638095,19.6171429 L43.2828572,32 L25.2638095,44.3828571 Z" id="greater_than" fill="#000000"></path>
        </g>
    </g>
</svg>
        </div>
        <div style="font-family: 'IBM Plex Mono', monospace, courier; color: black; font-size: 11px; display: inline-block; vertical-align: middle;">
            <div>col_vals_gt()</div>
        </div>
<pre><code>    &lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;a&lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;5&lt;/td&gt;
&lt;td style=&quot;height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;&quot; class=&quot;gt_row gt_center&quot;&gt;&lt;svg width=&quot;25px&quot; height=&quot;25px&quot; viewBox=&quot;0 0 25 25&quot; version=&quot;1.1&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot; style=&quot;vertical-align: middle;&quot;&gt;
&lt;g id=&quot;unchanged&quot; stroke=&quot;none&quot; stroke-width=&quot;1&quot; fill=&quot;none&quot; fill-rule=&quot;evenodd&quot;&gt;
    &lt;g id=&quot;unchanged&quot; transform=&quot;translate(0.500000, 0.570147)&quot;&gt;
        &lt;rect id=&quot;Rectangle&quot; x=&quot;0.125132506&quot; y=&quot;0&quot; width=&quot;23.749735&quot; height=&quot;23.7894737&quot;&gt;&lt;/rect&gt;
        &lt;path d=&quot;M5.80375046,8.18194736 C3.77191832,8.18194736 2.11875046,9.83495328 2.11875046,11.8669474 C2.11875046,13.8989414 3.77191832,15.5519474 5.80375046,15.5519474 C7.8355826,15.5519474 9.48875046,13.8989414 9.48875046,11.8669474 C9.48875046,9.83495328 7.83552863,8.18194736 5.80375046,8.18194736 Z M5.80375046,14.814915 C4.17821997,14.814915 2.85578285,13.4924778 2.85578285,11.8669474 C2.85578285,10.2414169 4.17821997,8.91897975 5.80375046,8.91897975 C7.42928095,8.91897975 8.75171807,10.2414169 8.75171807,11.8669474 C8.75171807,13.4924778 7.42928095,14.814915 5.80375046,14.814915 Z&quot; id=&quot;Shape&quot; fill=&quot;#000000&quot; fill-rule=&quot;nonzero&quot;&gt;&lt;/path&gt;
        &lt;path d=&quot;M13.9638189,8.699335 C13.9364621,8.70430925 13.9091059,8.71176968 13.8842359,8.71923074 C13.7822704,8.73663967 13.6877654,8.77643115 13.6056956,8.83860518 L10.2433156,11.3852598 C10.0766886,11.5046343 9.97720993,11.6986181 9.97720993,11.9025491 C9.97720993,12.1064807 10.0766886,12.3004639 10.2433156,12.4198383 L13.6056956,14.966493 C13.891697,15.1803725 14.2970729,15.1231721 14.5109517,14.8371707 C14.7248313,14.5511692 14.6676309,14.145794 14.3816294,13.9319145 L12.5313257,12.5392127 L21.8812495,12.5392127 L21.8812495,11.2658854 L12.5313257,11.2658854 L14.3816294,9.87318364 C14.6377872,9.71650453 14.7497006,9.40066014 14.6477351,9.11714553 C14.5482564,8.83363156 14.262255,8.65954352 13.9638189,8.699335 Z&quot; id=&quot;arrow&quot; fill=&quot;#000000&quot; transform=&quot;translate(15.929230, 11.894737) rotate(-180.000000) translate(-15.929230, -11.894737) &quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
&lt;/g&gt;
</code></pre>
<p></svg></td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color:#4CA64C;">✓</span></td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_right">13</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">3<br />0.23</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">10<br />0.77</td>
<td style="height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color: #AAAAAA;">●</span></td>
<td style="height: 40px; background-color: #FCFCFC;" class="gt_row gt_center"><span style="color: #EBBC14;">●</span></td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color: #FF3300;">●</span></td>
<td style="height: 40px;" class="gt_row gt_center"><a href="data:text/csv;base64,X3Jvd19udW1fLGRhdGVfdGltZSxkYXRlLGEsYixjLGQsZSxmCjEsMjAxNi0wMS0wNFQxMTowMDowMC4wMDAwMDAsMjAxNi0wMS0wNCwyLDEtYmNkLTM0NSwzLDM0MjMuMjksdHJ1ZSxoaWdoCjIsMjAxNi0wMS0wNFQwMDozMjowMC4wMDAwMDAsMjAxNi0wMS0wNCwzLDUtZWdoLTE2Myw4LDk5OTkuOTksdHJ1ZSxsb3cKNCwyMDE2LTAxLTA2VDE3OjIzOjAwLjAwMDAwMCwyMDE2LTAxLTA2LDIsNS1qZG8tOTAzLCwzODkyLjQsZmFsc2UsbWlkCjYsMjAxNi0wMS0xMVQwNjoxNTowMC4wMDAwMDAsMjAxNi0wMS0xMSw0LDItZGhlLTkyMyw0LDMyOTEuMDMsdHJ1ZSxtaWQKOCwyMDE2LTAxLTE3VDExOjI3OjAwLjAwMDAwMCwyMDE2LTAxLTE3LDQsNS1ib2UtNjM5LDIsMTAzNS42NCxmYWxzZSxsb3cKOSwyMDE2LTAxLTIwVDA0OjMwOjAwLjAwMDAwMCwyMDE2LTAxLTIwLDMsNS1iY2UtNjQyLDksODM3LjkzLGZhbHNlLGhpZ2gKMTAsMjAxNi0wMS0yMFQwNDozMDowMC4wMDAwMDAsMjAxNi0wMS0yMCwzLDUtYmNlLTY0Miw5LDgzNy45MyxmYWxzZSxoaWdoCjExLDIwMTYtMDEtMjZUMjA6MDc6MDAuMDAwMDAwLDIwMTYtMDEtMjYsNCwyLWRteC0wMTAsNyw4MzMuOTgsdHJ1ZSxsb3cKMTIsMjAxNi0wMS0yOFQwMjo1MTowMC4wMDAwMDAsMjAxNi0wMS0yOCwyLDctZG14LTAxMCw4LDEwOC4zNCxmYWxzZSxsb3cKMTMsMjAxNi0wMS0zMFQxMToyMzowMC4wMDAwMDAsMjAxNi0wMS0zMCwxLDMtZGthLTMwMywsMjIzMC4wOSx0cnVlLGhpZ2gK" download="extract_0001.csv"><button style="background-color: #67C2DC; color: #FFFFFF; border: none; padding: 5px; font-weight: bold; cursor: pointer; border-radius: 4px;">CSV</button></a></td></p>
  </tr>
  <tr>
    <td style="height: 40px; background-color: #EBBC14; color: transparent;font-size: 0px;" class="gt_row gt_left">#EBBC14</td>
    <td style="height: 40px; color: #666666;font-size: 13px;font-weight: bold;" class="gt_row gt_right">2</td>
    <td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_left">
        <div style="margin: 0; padding: 0; display: inline-block; height: 30px; vertical-align: middle; width: 16%;">
            <!--?xml version="1.0" encoding="UTF-8"?--><?xml version="1.0" encoding="UTF-8"?>
<svg width="30px" height="30px" viewBox="0 0 67 67" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="background: #FFFFFF;">
    <title>col_vals_lt</title>
    <g id="Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="col_vals_lt" transform="translate(1.500000, 1.500000)" fill-rule="nonzero">
            <path d="M55,0 C57.4852813,0 59.7352813,1.00735931 61.363961,2.63603897 C62.9926407,4.26471863 64,6.51471863 64,9 L64,9 L64,64 L9,64 C6.51471862,64 4.26471862,62.9926407 2.63603897,61.363961 C1.00735931,59.7352814 0,57.4852814 0,55 L0,55 L0,9 C0,6.51471863 1.00735931,4.26471863 2.63603897,2.63603897 C4.26471862,1.00735931 6.51471862,0 9,0 L9,0 L55,0 Z" id="rectangle" stroke="#000000" stroke-width="2" fill="#FFFFFF"></path>
            <path d="M51,10 L13,10 C11.347656,10 10,11.347656 10,13 L10,51 C10,52.652344 11.347656,54 13,54 L51,54 C52.652344,54 54,52.652344 54,51 L54,13 C54,11.347656 52.652344,10 51,10 Z M38.707031,45.292969 L37.292969,46.707031 L22.585938,32 L37.292969,17.292969 L38.707031,18.707031 L25.414063,32 L38.707031,45.292969 Z" id="less_than" fill="#000000"></path>
        </g>
    </g>
</svg>
        </div>
        <div style="font-family: 'IBM Plex Mono', monospace, courier; color: black; font-size: 11px; display: inline-block; vertical-align: middle;">
            <div>col_vals_lt()</div>
        </div>
<pre><code>    &lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;d&lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;1000&lt;/td&gt;
&lt;td style=&quot;height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;&quot; class=&quot;gt_row gt_center&quot;&gt;&lt;svg width=&quot;25px&quot; height=&quot;25px&quot; viewBox=&quot;0 0 25 25&quot; version=&quot;1.1&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot; style=&quot;vertical-align: middle;&quot;&gt;
&lt;g id=&quot;unchanged&quot; stroke=&quot;none&quot; stroke-width=&quot;1&quot; fill=&quot;none&quot; fill-rule=&quot;evenodd&quot;&gt;
    &lt;g id=&quot;unchanged&quot; transform=&quot;translate(0.500000, 0.570147)&quot;&gt;
        &lt;rect id=&quot;Rectangle&quot; x=&quot;0.125132506&quot; y=&quot;0&quot; width=&quot;23.749735&quot; height=&quot;23.7894737&quot;&gt;&lt;/rect&gt;
        &lt;path d=&quot;M5.80375046,8.18194736 C3.77191832,8.18194736 2.11875046,9.83495328 2.11875046,11.8669474 C2.11875046,13.8989414 3.77191832,15.5519474 5.80375046,15.5519474 C7.8355826,15.5519474 9.48875046,13.8989414 9.48875046,11.8669474 C9.48875046,9.83495328 7.83552863,8.18194736 5.80375046,8.18194736 Z M5.80375046,14.814915 C4.17821997,14.814915 2.85578285,13.4924778 2.85578285,11.8669474 C2.85578285,10.2414169 4.17821997,8.91897975 5.80375046,8.91897975 C7.42928095,8.91897975 8.75171807,10.2414169 8.75171807,11.8669474 C8.75171807,13.4924778 7.42928095,14.814915 5.80375046,14.814915 Z&quot; id=&quot;Shape&quot; fill=&quot;#000000&quot; fill-rule=&quot;nonzero&quot;&gt;&lt;/path&gt;
        &lt;path d=&quot;M13.9638189,8.699335 C13.9364621,8.70430925 13.9091059,8.71176968 13.8842359,8.71923074 C13.7822704,8.73663967 13.6877654,8.77643115 13.6056956,8.83860518 L10.2433156,11.3852598 C10.0766886,11.5046343 9.97720993,11.6986181 9.97720993,11.9025491 C9.97720993,12.1064807 10.0766886,12.3004639 10.2433156,12.4198383 L13.6056956,14.966493 C13.891697,15.1803725 14.2970729,15.1231721 14.5109517,14.8371707 C14.7248313,14.5511692 14.6676309,14.145794 14.3816294,13.9319145 L12.5313257,12.5392127 L21.8812495,12.5392127 L21.8812495,11.2658854 L12.5313257,11.2658854 L14.3816294,9.87318364 C14.6377872,9.71650453 14.7497006,9.40066014 14.6477351,9.11714553 C14.5482564,8.83363156 14.262255,8.65954352 13.9638189,8.699335 Z&quot; id=&quot;arrow&quot; fill=&quot;#000000&quot; transform=&quot;translate(15.929230, 11.894737) rotate(-180.000000) translate(-15.929230, -11.894737) &quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
&lt;/g&gt;
</code></pre>
<p></svg></td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color:#4CA64C;">✓</span></td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_right">13</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">6<br />0.46</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">7<br />0.54</td>
<td style="height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color: #AAAAAA;">●</span></td>
<td style="height: 40px; background-color: #FCFCFC;" class="gt_row gt_center"><span style="color: #EBBC14;">●</span></td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color: #FF3300;">○</span></td>
<td style="height: 40px;" class="gt_row gt_center"><a href="data:text/csv;base64,X3Jvd19udW1fLGRhdGVfdGltZSxkYXRlLGEsYixjLGQsZSxmCjEsMjAxNi0wMS0wNFQxMTowMDowMC4wMDAwMDAsMjAxNi0wMS0wNCwyLDEtYmNkLTM0NSwzLDM0MjMuMjksdHJ1ZSxoaWdoCjIsMjAxNi0wMS0wNFQwMDozMjowMC4wMDAwMDAsMjAxNi0wMS0wNCwzLDUtZWdoLTE2Myw4LDk5OTkuOTksdHJ1ZSxsb3cKMywyMDE2LTAxLTA1VDEzOjMyOjAwLjAwMDAwMCwyMDE2LTAxLTA1LDYsOC1rZGctOTM4LDMsMjM0My4yMyx0cnVlLGhpZ2gKNCwyMDE2LTAxLTA2VDE3OjIzOjAwLjAwMDAwMCwyMDE2LTAxLTA2LDIsNS1qZG8tOTAzLCwzODkyLjQsZmFsc2UsbWlkCjYsMjAxNi0wMS0xMVQwNjoxNTowMC4wMDAwMDAsMjAxNi0wMS0xMSw0LDItZGhlLTkyMyw0LDMyOTEuMDMsdHJ1ZSxtaWQKOCwyMDE2LTAxLTE3VDExOjI3OjAwLjAwMDAwMCwyMDE2LTAxLTE3LDQsNS1ib2UtNjM5LDIsMTAzNS42NCxmYWxzZSxsb3cKMTMsMjAxNi0wMS0zMFQxMToyMzowMC4wMDAwMDAsMjAxNi0wMS0zMCwxLDMtZGthLTMwMywsMjIzMC4wOSx0cnVlLGhpZ2gK" download="extract_0002.csv"><button style="background-color: #67C2DC; color: #FFFFFF; border: none; padding: 5px; font-weight: bold; cursor: pointer; border-radius: 4px;">CSV</button></a></td></p>
  </tr>
</tbody>
</table>
</div>
<p>This approach allows you to log individual step failures during the validation process using
<a href="https://posit-dev.github.io/pointblank/reference/Actions.html" target="_blank" rel="noopener"><code>Actions</code></a>
 and generate a
comprehensive report after all validation steps are complete using
<a href="https://posit-dev.github.io/pointblank/reference/FinalActions.html" target="_blank" rel="noopener"><code>FinalActions</code></a>
. Using both
action types gives you fine-grained control over when and how notifications and other actions are
triggered in your validation workflow.</p>
<h2 id="real-world-example-building-an-automated-validation-pipeline">Real-World Example: Building an Automated Validation Pipeline
</h2>
<p>Let&rsquo;s put everything together in a more realistic example. Imagine you&rsquo;re validating a gaming
revenue dataset and want to:</p>
<ol>
<li>log detailed information about each failure</li>
<li>send a Slack notification if critical failures occur</li>
<li>generate a comprehensive report after validation completes</li>
</ol>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span><span class="lnt">49
</span><span class="lnt">50
</span><span class="lnt">51
</span><span class="lnt">52
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">log_step_failure</span><span class="p">():</span>
</span></span><span class="line"><span class="cl">    <span class="n">metadata</span> <span class="o">=</span> <span class="n">pb</span><span class="o">.</span><span class="n">get_action_metadata</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;[</span><span class="si">{</span><span class="n">metadata</span><span class="p">[</span><span class="s1">&#39;level&#39;</span><span class="p">]</span><span class="o">.</span><span class="n">upper</span><span class="p">()</span><span class="si">}</span><span class="s2">] Step </span><span class="si">{</span><span class="n">metadata</span><span class="p">[</span><span class="s1">&#39;step&#39;</span><span class="p">]</span><span class="si">}</span><span class="s2">: </span><span class="si">{</span><span class="n">metadata</span><span class="p">[</span><span class="s1">&#39;failure_text&#39;</span><span class="p">]</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">analyze_results</span><span class="p">():</span>
</span></span><span class="line"><span class="cl">    <span class="n">summary</span> <span class="o">=</span> <span class="n">pb</span><span class="o">.</span><span class="n">get_validation_summary</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># Calculate overall pass rate</span>
</span></span><span class="line"><span class="cl">    <span class="n">pass_rate</span> <span class="o">=</span> <span class="p">(</span><span class="n">summary</span><span class="p">[</span><span class="s1">&#39;n_passing_steps&#39;</span><span class="p">]</span> <span class="o">/</span> <span class="n">summary</span><span class="p">[</span><span class="s1">&#39;n_steps&#39;</span><span class="p">])</span> <span class="o">*</span> <span class="mi">100</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;</span><span class="se">\n</span><span class="s2">==== VALIDATION RESULTS ====&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;Table: </span><span class="si">{</span><span class="n">summary</span><span class="p">[</span><span class="s1">&#39;tbl_name&#39;</span><span class="p">]</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;Pass rate: </span><span class="si">{</span><span class="n">pass_rate</span><span class="si">:</span><span class="s2">.2f</span><span class="si">}</span><span class="s2">%&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;Failing steps: </span><span class="si">{</span><span class="n">summary</span><span class="p">[</span><span class="s1">&#39;n_failing_steps&#39;</span><span class="p">]</span><span class="si">}</span><span class="s2"> of </span><span class="si">{</span><span class="n">summary</span><span class="p">[</span><span class="s1">&#39;n_steps&#39;</span><span class="p">]</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># In a real scenario, here you might:</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># 1. Save results to a database</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># 2. Generate and email an HTML report</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># 3. Trigger data cleansing workflows</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># Simulate a Slack notification</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="n">summary</span><span class="p">[</span><span class="s1">&#39;highest_severity&#39;</span><span class="p">]</span> <span class="o">==</span> <span class="s2">&#34;critical&#34;</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;</span><span class="se">\n</span><span class="s2">🚨 [SLACK NOTIFICATION] Critical data quality issues detected!&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;@data-team Please investigate immediately.&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Create our validation workflow with actions</span>
</span></span><span class="line"><span class="cl"><span class="n">validation_7</span> <span class="o">=</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">pb</span><span class="o">.</span><span class="n">Validate</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="n">data</span><span class="o">=</span><span class="n">pb</span><span class="o">.</span><span class="n">load_dataset</span><span class="p">(</span><span class="n">dataset</span><span class="o">=</span><span class="s2">&#34;game_revenue&#34;</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">        <span class="n">tbl_name</span><span class="o">=</span><span class="s2">&#34;game_revenue&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="n">thresholds</span><span class="o">=</span><span class="n">pb</span><span class="o">.</span><span class="n">Thresholds</span><span class="p">(</span><span class="n">warning</span><span class="o">=</span><span class="mf">0.05</span><span class="p">,</span> <span class="n">error</span><span class="o">=</span><span class="mf">0.10</span><span class="p">,</span> <span class="n">critical</span><span class="o">=</span><span class="mf">0.15</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">        <span class="n">actions</span><span class="o">=</span><span class="n">pb</span><span class="o">.</span><span class="n">Actions</span><span class="p">(</span><span class="n">default</span><span class="o">=</span><span class="n">log_step_failure</span><span class="p">,</span> <span class="n">highest_only</span><span class="o">=</span><span class="kc">True</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">        <span class="n">final_actions</span><span class="o">=</span><span class="n">pb</span><span class="o">.</span><span class="n">FinalActions</span><span class="p">(</span><span class="n">analyze_results</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">        <span class="n">brief</span><span class="o">=</span><span class="kc">True</span>  <span class="c1"># Add automatically-generated briefs</span>
</span></span><span class="line"><span class="cl">    <span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">col_vals_regex</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="n">columns</span><span class="o">=</span><span class="s2">&#34;player_id&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="n">pattern</span><span class="o">=</span><span class="sa">r</span><span class="s2">&#34;[A-Z]</span><span class="si">{12}</span><span class="s2">\d</span><span class="si">{3}</span><span class="s2">&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="n">brief</span><span class="o">=</span><span class="s2">&#34;Player IDs must follow standard format&#34;</span>  <span class="c1"># Custom brief text</span>
</span></span><span class="line"><span class="cl">    <span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">col_vals_gt</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="n">columns</span><span class="o">=</span><span class="s2">&#34;item_revenue&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="n">value</span><span class="o">=</span><span class="mf">0.10</span>
</span></span><span class="line"><span class="cl">    <span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">col_vals_gt</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="n">columns</span><span class="o">=</span><span class="s2">&#34;session_duration&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="n">value</span><span class="o">=</span><span class="mi">15</span>
</span></span><span class="line"><span class="cl">    <span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">interrogate</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">validation_7</span>
</span></span></code></pre></td></tr></table>
</div>
</div><pre><code>[CRITICAL] Step 2: Exceedance of failed test units where values in `item_revenue` should have been &gt; `0.1`.
[CRITICAL] Step 3: Exceedance of failed test units where values in `session_duration` should have been &gt; `15`.

==== VALIDATION RESULTS ====
Table: game_revenue
Pass rate: 33.33%
Failing steps: 2 of 3

🚨 [SLACK NOTIFICATION] Critical data quality issues detected!
@data-team Please investigate immediately.
</code></pre>
<div id="pb_tbl" style="padding-left:0px;padding-right:0px;padding-top:10px;padding-bottom:10px;overflow-x:auto;overflow-y:auto;width:auto;height:auto;">
<style>
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono&display=swap');
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans&display=swap');
#pb_tbl table {
          font-family: 'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Helvetica Neue', 'Fira Sans', 'Droid Sans', Arial, sans-serif;
          -webkit-font-smoothing: antialiased;
          -moz-osx-font-smoothing: grayscale;
        }
<p>#pb_tbl thead, tbody, tfoot, tr, td, th { border-style: none; }
tr { background-color: transparent; }
#pb_tbl p { margin: 0; padding: 0; }
#pb_tbl .gt_table { display: table; border-collapse: collapse; line-height: normal; margin-left: auto; margin-right: auto; color: #333333; font-size: 90%; font-weight: normal; font-style: normal; background-color: #FFFFFF; width: auto; border-top-style: solid; border-top-width: 2px; border-top-color: #A8A8A8; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #A8A8A8; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; }
#pb_tbl .gt_caption { padding-top: 4px; padding-bottom: 4px; }
#pb_tbl .gt_title { color: #333333; font-size: 125%; font-weight: initial; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; border-bottom-color: #FFFFFF; border-bottom-width: 0; }
#pb_tbl .gt_subtitle { color: #333333; font-size: 85%; font-weight: initial; padding-top: 3px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; border-top-color: #FFFFFF; border-top-width: 0; }
#pb_tbl .gt_heading { background-color: #FFFFFF; text-align: left; border-bottom-color: #FFFFFF; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; }
#pb_tbl .gt_bottom_border { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; }
#pb_tbl .gt_col_headings { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; }
#pb_tbl .gt_col_heading { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; overflow-x: hidden; }
#pb_tbl .gt_column_spanner_outer { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; padding-top: 0; padding-bottom: 0; padding-left: 4px; padding-right: 4px; }
#pb_tbl .gt_column_spanner_outer:first-child { padding-left: 0; }
#pb_tbl .gt_column_spanner_outer:last-child { padding-right: 0; }
#pb_tbl .gt_column_spanner { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; overflow-x: hidden; display: inline-block; width: 100%; }
#pb_tbl .gt_spanner_row { border-bottom-style: hidden; }
#pb_tbl .gt_group_heading { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; text-align: left; }
#pb_tbl .gt_empty_group_heading { padding: 0.5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: middle; }
#pb_tbl .gt_from_md&gt; :first-child { margin-top: 0; }
#pb_tbl .gt_from_md&gt; :last-child { margin-bottom: 0; }
#pb_tbl .gt_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; margin: 10px; border-top-style: solid; border-top-width: 1px; border-top-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; overflow-x: hidden; }
#pb_tbl .gt_stub { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; }
#pb_tbl .gt_stub_row_group { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; vertical-align: top; }
#pb_tbl .gt_row_group_first td { border-top-width: 2px; }
#pb_tbl .gt_row_group_first th { border-top-width: 2px; }
#pb_tbl .gt_striped { color: #333333; background-color: #F4F4F4; }
#pb_tbl .gt_table_body { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; }
#pb_tbl .gt_grand_summary_row { color: #333333; background-color: #FFFFFF; text-transform: inherit; padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; }
#pb_tbl .gt_first_grand_summary_row_bottom { border-top-style: double; border-top-width: 6px; border-top-color: #D3D3D3; }
#pb_tbl .gt_last_grand_summary_row_top { border-bottom-style: double; border-bottom-width: 6px; border-bottom-color: #D3D3D3; }
#pb_tbl .gt_sourcenotes { color: #333333; background-color: #FFFFFF; border-bottom-style: none; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; }
#pb_tbl .gt_sourcenote { font-size: 90%; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; text-align: left; }
#pb_tbl .gt_left { text-align: left; }
#pb_tbl .gt_center { text-align: center; }
#pb_tbl .gt_right { text-align: right; font-variant-numeric: tabular-nums; }
#pb_tbl .gt_font_normal { font-weight: normal; }
#pb_tbl .gt_font_bold { font-weight: bold; }
#pb_tbl .gt_font_italic { font-style: italic; }
#pb_tbl .gt_super { font-size: 65%; }
#pb_tbl .gt_footnote_marks { font-size: 75%; vertical-align: 0.4em; position: initial; }
#pb_tbl .gt_asterisk { font-size: 100%; vertical-align: 0; }</p>
<p></style></p>
<table style="table-layout: fixed;; width: 0px" class="gt_table" data-quarto-disable-processing="true" data-quarto-bootstrap="false">
<colgroup>
  <col style="width:4px;"/>
  <col style="width:35px;"/>
  <col style="width:190px;"/>
  <col style="width:120px;"/>
  <col style="width:120px;"/>
  <col style="width:50px;"/>
  <col style="width:50px;"/>
  <col style="width:60px;"/>
  <col style="width:60px;"/>
  <col style="width:60px;"/>
  <col style="width:30px;"/>
  <col style="width:30px;"/>
  <col style="width:30px;"/>
  <col style="width:65px;"/>
</colgroup>
<thead>
  <tr class="gt_heading">
    <td colspan="14" class="gt_heading gt_title gt_font_normal" style="color: #444444;font-size: 28px;text-align: left;font-weight: bold; text-align: left;">Pointblank Validation</td>
  </tr>
  <tr class="gt_heading">
    <td colspan="14" class="gt_heading gt_subtitle gt_font_normal gt_bottom_border" style="text-align: left;"><div><span style='text-decoration-style: solid; text-decoration-color: #ADD8E6; text-decoration-line: underline; text-underline-position: under; color: #333333; font-variant-numeric: tabular-nums; padding-left: 4px; margin-right: 5px; padding-right: 2px;'>2026-03-13|19:09:29</span><div style="padding-top: 10px; padding-bottom: 5px;"><span style='background-color: #0075FF; color: #FFFFFF; padding: 0.5em 0.5em; position: inherit; text-transform: uppercase; margin: 5px 0px 5px 0px; border: solid 1px #0075FF; font-weight: bold; padding: 2px 15px 2px 15px; font-size: 10px;'>Polars</span><span style='background-color: none; color: #222222; padding: 0.5em 0.5em; position: inherit; margin: 5px 10px 5px -4px; border: solid 1px #0075FF; font-weight: bold; padding: 2px 15px 2px 15px; font-size: 10px;'>game_revenue</span><span><span style="background-color: #AAAAAA; color: white; padding: 0.5em 0.5em; position: inherit; text-transform: uppercase; margin: 5px 0px 5px 5px; border: solid 1px #AAAAAA; font-weight: bold; padding: 2px 15px 2px 15px; font-size: smaller;">WARNING</span><span style="background-color: none; color: #333333; padding: 0.5em 0.5em; position: inherit; margin: 5px 0px 5px -4px; font-weight: bold; border: solid 1px #AAAAAA; padding: 2px 15px 2px 15px; font-size: smaller; margin-right: 5px;">0.05</span><span style="background-color: #EBBC14; color: white; padding: 0.5em 0.5em; position: inherit; text-transform: uppercase; margin: 5px 0px 5px 1px; border: solid 1px #EBBC14; font-weight: bold; padding: 2px 15px 2px 15px; font-size: smaller;">ERROR</span><span style="background-color: none; color: #333333; padding: 0.5em 0.5em; position: inherit; margin: 5px 0px 5px -4px; font-weight: bold; border: solid 1px #EBBC14; padding: 2px 15px 2px 15px; font-size: smaller; margin-right: 5px;">0.1</span><span style="background-color: #FF3300; color: white; padding: 0.5em 0.5em; position: inherit; text-transform: uppercase; margin: 5px 0px 5px 1px; border: solid 1px #FF3300; font-weight: bold; padding: 2px 15px 2px 15px; font-size: smaller;">CRITICAL</span><span style="background-color: none; color: #333333; padding: 0.5em 0.5em; position: inherit; margin: 5px 0px 5px -4px; font-weight: bold; border: solid 1px #FF3300; padding: 2px 15px 2px 15px; font-size: smaller;">0.15</span></span></div></div></td>
  </tr>
<tr class="gt_col_headings">
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-status_color"></th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-i"></th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-type_upd">STEP</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-columns_upd">COLUMNS</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-values_upd">VALUES</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-tbl">TBL</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-eval">EVAL</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-test_units">UNITS</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-pass">PASS</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-fail">FAIL</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-w_upd">W</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-e_upd">E</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-c_upd">C</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-extract_upd">EXT</th>
</tr>
</thead>
<tbody class="gt_table_body">
  <tr>
    <td style="height: 40px; background-color: #4CA64C; color: transparent;font-size: 0px;" class="gt_row gt_left">#4CA64C</td>
    <td style="height: 40px; color: #666666;font-size: 13px;font-weight: bold;" class="gt_row gt_right">1</td>
    <td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_left">
        <div style="margin: 0; padding: 0; display: inline-block; height: 30px; vertical-align: middle; width: 16%;">
            <!--?xml version="1.0" encoding="UTF-8"?--><?xml version="1.0" encoding="UTF-8"?>
<svg width="30px" height="30px" viewBox="0 0 67 67" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <title>col_vals_regex</title>
    <g id="Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="col_vals_regex" transform="translate(0.000000, 0.034483)">
            <path d="M56.712234,1 C59.1975153,1 61.4475153,2.00735931 63.076195,3.63603897 C64.7048747,5.26471863 65.712234,7.51471863 65.712234,10 L65.712234,10 L65.712234,65 L10.712234,65 C8.22695259,65 5.97695259,63.9926407 4.34827294,62.363961 C2.71959328,60.7352814 1.71223397,58.4852814 1.71223397,56 L1.71223397,56 L1.71223397,10 C1.71223397,7.51471863 2.71959328,5.26471863 4.34827294,3.63603897 C5.97695259,2.00735931 8.22695259,1 10.712234,1 L10.712234,1 Z" id="rectangle" stroke="#000000" stroke-width="2" fill="#FFFFFF"></path>
            <g id="regex_symbols" transform="translate(18.000000, 12.000000)" fill="#000000" fill-rule="nonzero">
                <path d="M4.17434508,33.013582 C1.94895328,33.013582 0.138006923,34.8245284 0.138006923,37.0499202 C0.138006923,39.275312 1.94895328,41.0862583 4.17434508,41.0862583 C6.39973688,41.0862583 8.21068324,39.275312 8.21068324,37.0499202 C8.21068324,34.8245284 6.39973688,33.013582 4.17434508,33.013582 Z" id="full_stop"></path>
                <path d="M23.9479718,23.3175402 L21.5628264,23.3175402 C21.2344032,23.3175402 20.9665401,23.0520067 20.9665401,22.7212538 L20.9665401,15.1022979 L14.3445004,18.8873192 C14.0626621,19.050366 13.7016292,18.952538 13.5362533,18.6706991 L12.3436806,16.6442575 C12.262157,16.506832 12.2388642,16.3437852 12.2807909,16.1900549 C12.3203879,16.0363251 12.4205455,15.9058874 12.557971,15.8266929 L19.1800101,11.9880994 L12.557971,8.15183511 C12.4205455,8.07264112 12.3203879,7.93987439 12.2807909,7.78614401 C12.2388642,7.63241423 12.262157,7.46936689 12.3413509,7.33194137 L13.5339237,5.30549975 C13.6993001,5.02366143 14.0626621,4.92816199 14.3445004,5.09120934 L20.9665401,8.87390091 L20.9665401,1.25494501 C20.9665401,0.926521818 21.2344032,0.658658658 21.5628264,0.658658658 L23.9479718,0.658658658 C24.2787247,0.658658658 24.5442582,0.926521818 24.5442582,1.25494501 L24.5442582,8.87390091 L31.1662979,5.09120934 C31.4481362,4.92816199 31.8091691,5.02366143 31.9745455,5.30549975 L33.1671182,7.33194137 C33.2486413,7.46936689 33.2719341,7.63241423 33.2300074,7.78614401 C33.1904104,7.93987439 33.0902528,8.07264112 32.9528278,8.15183511 L26.3307882,11.9880994 L32.9528278,15.8243638 C33.0879237,15.9058874 33.1880813,16.0363251 33.2300074,16.1900549 C33.269605,16.3437852 33.2486413,16.506832 33.1671182,16.6442575 L31.9745455,18.6706991 C31.8091691,18.952538 31.4481362,19.050366 31.1662979,18.8849895 L24.5442582,15.1022979 L24.5442582,22.7212538 C24.5442582,23.0520067 24.2787247,23.3175402 23.9479718,23.3175402 Z" id="asterisk"></path>
            </g>
        </g>
    </g>
</svg>
        </div>
        <div style="font-family: 'IBM Plex Mono', monospace, courier; color: black; font-size: 11px; display: inline-block; vertical-align: middle;">
            <div>col_vals_regex()</div>
        </div>
        <div style="font-size: 9px; font-family: 'IBM Plex Sans'; text-wrap: balance; margin-top: 3px;"><p style="font-size: inherit; margin: 0;">Player IDs must follow standard format</p>
</div>
        </td>
    <td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">player_id</td>
    <td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">[A-Z]{12}\d{3}</td>
    <td style="height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;" class="gt_row gt_center"><svg width="25px" height="25px" viewBox="0 0 25 25" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="vertical-align: middle;">
    <g id="unchanged" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="unchanged" transform="translate(0.500000, 0.570147)">
            <rect id="Rectangle" x="0.125132506" y="0" width="23.749735" height="23.7894737"></rect>
            <path d="M5.80375046,8.18194736 C3.77191832,8.18194736 2.11875046,9.83495328 2.11875046,11.8669474 C2.11875046,13.8989414 3.77191832,15.5519474 5.80375046,15.5519474 C7.8355826,15.5519474 9.48875046,13.8989414 9.48875046,11.8669474 C9.48875046,9.83495328 7.83552863,8.18194736 5.80375046,8.18194736 Z M5.80375046,14.814915 C4.17821997,14.814915 2.85578285,13.4924778 2.85578285,11.8669474 C2.85578285,10.2414169 4.17821997,8.91897975 5.80375046,8.91897975 C7.42928095,8.91897975 8.75171807,10.2414169 8.75171807,11.8669474 C8.75171807,13.4924778 7.42928095,14.814915 5.80375046,14.814915 Z" id="Shape" fill="#000000" fill-rule="nonzero"></path>
            <path d="M13.9638189,8.699335 C13.9364621,8.70430925 13.9091059,8.71176968 13.8842359,8.71923074 C13.7822704,8.73663967 13.6877654,8.77643115 13.6056956,8.83860518 L10.2433156,11.3852598 C10.0766886,11.5046343 9.97720993,11.6986181 9.97720993,11.9025491 C9.97720993,12.1064807 10.0766886,12.3004639 10.2433156,12.4198383 L13.6056956,14.966493 C13.891697,15.1803725 14.2970729,15.1231721 14.5109517,14.8371707 C14.7248313,14.5511692 14.6676309,14.145794 14.3816294,13.9319145 L12.5313257,12.5392127 L21.8812495,12.5392127 L21.8812495,11.2658854 L12.5313257,11.2658854 L14.3816294,9.87318364 C14.6377872,9.71650453 14.7497006,9.40066014 14.6477351,9.11714553 C14.5482564,8.83363156 14.262255,8.65954352 13.9638189,8.699335 Z" id="arrow" fill="#000000" transform="translate(15.929230, 11.894737) rotate(-180.000000) translate(-15.929230, -11.894737) "></path>
        </g>
    </g>
</svg></td>
    <td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color:#4CA64C;">&check;</span></td>
    <td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_right">2000</td>
    <td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">2000<br />1.00</td>
    <td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">0<br />0.00</td>
    <td style="height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color: #AAAAAA;">&cir;</span></td>
    <td style="height: 40px; background-color: #FCFCFC;" class="gt_row gt_center"><span style="color: #EBBC14;">&cir;</span></td>
    <td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color: #FF3300;">&cir;</span></td>
    <td style="height: 40px;" class="gt_row gt_center">—</td>
  </tr>
  <tr>
    <td style="height: 40px; background-color: #FF3300; color: transparent;font-size: 0px;" class="gt_row gt_left">#FF3300</td>
    <td style="height: 40px; color: #666666;font-size: 13px;font-weight: bold;" class="gt_row gt_right">2</td>
    <td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_left">
        <div style="margin: 0; padding: 0; display: inline-block; height: 30px; vertical-align: middle; width: 16%;">
            <!--?xml version="1.0" encoding="UTF-8"?--><?xml version="1.0" encoding="UTF-8"?>
<svg width="30px" height="30px" viewBox="0 0 67 67" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="background: #FFFFFF;">
    <title>col_vals_gt</title>
    <g id="Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="col_vals_gt" transform="translate(1.500000, 1.500000)" fill-rule="nonzero">
            <path d="M55,0 C57.4852813,0 59.7352813,1.00735931 61.363961,2.63603897 C62.9926407,4.26471863 64,6.51471863 64,9 L64,9 L64,64 L9,64 C6.51471862,64 4.26471862,62.9926407 2.63603897,61.363961 C1.00735931,59.7352814 0,57.4852814 0,55 L0,55 L0,9 C0,6.51471863 1.00735931,4.26471863 2.63603897,2.63603897 C4.26471862,1.00735931 6.51471862,0 9,0 L9,0 L55,0 Z" id="rectangle" stroke="#000000" stroke-width="2" fill="#FFFFFF"></path>
            <path d="M48.7619048,10 L15.2380953,10 C12.3466667,10 10,12.3466667 10,15.2380952 L10,48.7619048 C10,51.6533333 12.3466667,54 15.2380953,54 L48.7619048,54 C51.6533333,54 54,51.6533333 54,48.7619048 L54,15.2380952 C54,12.3466667 51.6533333,10 48.7619048,10 Z M25.2638095,44.3828571 L24.0695238,42.6647619 L39.5847619,32 L24.0695238,21.3352381 L25.2638095,19.6171429 L43.2828572,32 L25.2638095,44.3828571 Z" id="greater_than" fill="#000000"></path>
        </g>
    </g>
</svg>
        </div>
        <div style="font-family: 'IBM Plex Mono', monospace, courier; color: black; font-size: 11px; display: inline-block; vertical-align: middle;">
            <div>col_vals_gt()</div>
        </div>
        <div style="font-size: 9px; font-family: 'IBM Plex Sans'; text-wrap: balance; margin-top: 3px;"><p style="font-size: inherit; margin: 0;">Expect that values in <code>item_revenue</code> should be &gt; <code>0.1</code>.</p>
</div>
        </td>
    <td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">item_revenue</td>
    <td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">0.1</td>
    <td style="height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;" class="gt_row gt_center"><svg width="25px" height="25px" viewBox="0 0 25 25" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="vertical-align: middle;">
    <g id="unchanged" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="unchanged" transform="translate(0.500000, 0.570147)">
            <rect id="Rectangle" x="0.125132506" y="0" width="23.749735" height="23.7894737"></rect>
            <path d="M5.80375046,8.18194736 C3.77191832,8.18194736 2.11875046,9.83495328 2.11875046,11.8669474 C2.11875046,13.8989414 3.77191832,15.5519474 5.80375046,15.5519474 C7.8355826,15.5519474 9.48875046,13.8989414 9.48875046,11.8669474 C9.48875046,9.83495328 7.83552863,8.18194736 5.80375046,8.18194736 Z M5.80375046,14.814915 C4.17821997,14.814915 2.85578285,13.4924778 2.85578285,11.8669474 C2.85578285,10.2414169 4.17821997,8.91897975 5.80375046,8.91897975 C7.42928095,8.91897975 8.75171807,10.2414169 8.75171807,11.8669474 C8.75171807,13.4924778 7.42928095,14.814915 5.80375046,14.814915 Z" id="Shape" fill="#000000" fill-rule="nonzero"></path>
            <path d="M13.9638189,8.699335 C13.9364621,8.70430925 13.9091059,8.71176968 13.8842359,8.71923074 C13.7822704,8.73663967 13.6877654,8.77643115 13.6056956,8.83860518 L10.2433156,11.3852598 C10.0766886,11.5046343 9.97720993,11.6986181 9.97720993,11.9025491 C9.97720993,12.1064807 10.0766886,12.3004639 10.2433156,12.4198383 L13.6056956,14.966493 C13.891697,15.1803725 14.2970729,15.1231721 14.5109517,14.8371707 C14.7248313,14.5511692 14.6676309,14.145794 14.3816294,13.9319145 L12.5313257,12.5392127 L21.8812495,12.5392127 L21.8812495,11.2658854 L12.5313257,11.2658854 L14.3816294,9.87318364 C14.6377872,9.71650453 14.7497006,9.40066014 14.6477351,9.11714553 C14.5482564,8.83363156 14.262255,8.65954352 13.9638189,8.699335 Z" id="arrow" fill="#000000" transform="translate(15.929230, 11.894737) rotate(-180.000000) translate(-15.929230, -11.894737) "></path>
        </g>
    </g>
</svg></td>
    <td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color:#4CA64C;">&check;</span></td>
    <td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_right">2000</td>
    <td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">1440<br />0.72</td>
    <td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">560<br />0.28</td>
    <td style="height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color: #AAAAAA;">&#9679;</span></td>
    <td style="height: 40px; background-color: #FCFCFC;" class="gt_row gt_center"><span style="color: #EBBC14;">&#9679;</span></td>
    <td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color: #FF3300;">&#9679;</span></td>
    <td style="height: 40px;" class="gt_row gt_center"><a href="data:text/csv;base64,X3Jvd19udW1fLHBsYXllcl9pZCxzZXNzaW9uX2lkLHNlc3Npb25fc3RhcnQsdGltZSxpdGVtX3R5cGUsaXRlbV9uYW1lLGl0ZW1fcmV2ZW51ZSxzZXNzaW9uX2R1cmF0aW9uLHN0YXJ0X2RheSxhY3F1aXNpdGlvbixjb3VudHJ5CjUsRUNQQU5PSVhMWkhGODk2LEVDUEFOT0lYTFpIRjg5Ni1oZHU5amtscywyMDE1LTAxLTAxVDExOjUwOjAyLjAwMDAwMCswMDAwLDIwMTUtMDEtMDFUMTE6NTU6MjAuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAzLDM1LjIsMjAxNS0wMS0wMSxnb29nbGUsR2VybWFueQo2LEVDUEFOT0lYTFpIRjg5NixFQ1BBTk9JWExaSEY4OTYtaGR1OWprbHMsMjAxNS0wMS0wMVQxMTo1MDowMi4wMDAwMDArMDAwMCwyMDE1LTAxLTAxVDEyOjA4OjU2LjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDcsMzUuMiwyMDE1LTAxLTAxLGdvb2dsZSxHZXJtYW55CjcsRUNQQU5PSVhMWkhGODk2LEVDUEFOT0lYTFpIRjg5Ni1oZHU5amtscywyMDE1LTAxLTAxVDExOjUwOjAyLjAwMDAwMCswMDAwLDIwMTUtMDEtMDFUMTI6MTQ6MDguMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4wOCwzNS4yLDIwMTUtMDEtMDEsZ29vZ2xlLEdlcm1hbnkKMTAsRlhXVU9SR1lOSkFFMjcxLEZYV1VPUkdZTkpBRTI3MS1ldDdiczYzOSwyMDE1LTAxLTAxVDE1OjE3OjE4LjAwMDAwMCswMDAwLDIwMTUtMDEtMDFUMTU6MTk6MzYuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA4LDMwLjcsMjAxNS0wMS0wMSxvcmdhbmljLENhbmFkYQoxMyxGWFdVT1JHWU5KQUUyNzEsRlhXVU9SR1lOSkFFMjcxLWV0N2JzNjM5LDIwMTUtMDEtMDFUMTU6MTc6MTguMDAwMDAwKzAwMDAsMjAxNS0wMS0wMVQxNTo0Mzo0Mi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDQsMzAuNywyMDE1LTAxLTAxLG9yZ2FuaWMsQ2FuYWRhCjE2LENQWlZNR1dRU0lPSDEzMixDUFpWTUdXUVNJT0gxMzItZnlzOXg2MnYsMjAxNS0wMS0wMVQxNTo1MjoyNC4wMDAwMDArMDAwMCwyMDE1LTAxLTAxVDE2OjA2OjEyLjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDc3LDEzLjgsMjAxNS0wMS0wMSxjcm9zc3Byb21vLFNvdXRoIEtvcmVhCjE4LEZYV1VPUkdZTkpBRTI3MSxGWFdVT1JHWU5KQUUyNzEtN3djZGVhaXAsMjAxNS0wMS0wMVQyMjoxNzoyNy4wMDAwMDArMDAwMCwyMDE1LTAxLTAxVDIyOjIyOjU3LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wOCwxMy4xLDIwMTUtMDEtMDEsb3JnYW5pYyxDYW5hZGEKMjEsQ1BaVk1HV1FTSU9IMTMyLENQWlZNR1dRU0lPSDEzMi05M2pxbm01ZCwyMDE1LTAxLTAxVDIyOjQyOjMzLjAwMDAwMCswMDAwLDIwMTUtMDEtMDFUMjI6NDQ6MTUuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyOCwyMC43LDIwMTUtMDEtMDEsY3Jvc3Nwcm9tbyxTb3V0aCBLb3JlYQoyNyxRSkdWT0JMQVRJSFc0NTcsUUpHVk9CTEFUSUhXNDU3LThheGg1MWJ2LDIwMTUtMDEtMDJUMDE6MDI6MDYuMDAwMDAwKzAwMDAsMjAxNS0wMS0wMlQwMToyNjowNi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDg4LDMwLjUsMjAxNS0wMS0wMixvdGhlcl9jYW1wYWlnbixTd2VkZW4KMjksRUNQQU5PSVhMWkhGODk2LEVDUEFOT0lYTFpIRjg5Ni14ZWIxbWk0ciwyMDE1LTAxLTAyVDAyOjQxOjU3LjAwMDAwMCswMDAwLDIwMTUtMDEtMDJUMDI6NTA6MjcuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyLDI4LjMsMjAxNS0wMS0wMSxnb29nbGUsR2VybWFueQozMyxFQ1BBTk9JWExaSEY4OTYsRUNQQU5PSVhMWkhGODk2LXhlYjFtaTRyLDIwMTUtMDEtMDJUMDI6NDE6NTcuMDAwMDAwKzAwMDAsMjAxNS0wMS0wMlQwMzowNDoxNS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDMsMjguMywyMDE1LTAxLTAxLGdvb2dsZSxHZXJtYW55CjM5LEZYV1VPUkdZTkpBRTI3MSxGWFdVT1JHWU5KQUUyNzEtOGszamJzeG8sMjAxNS0wMS0wMlQwMzo1MDoyNy4wMDAwMDArMDAwMCwyMDE1LTAxLTAyVDA0OjA0OjIxLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNSwxNS41LDIwMTUtMDEtMDEsb3JnYW5pYyxDYW5hZGEKNDAsRlhXVU9SR1lOSkFFMjcxLEZYV1VPUkdZTkpBRTI3MS16ODM0a3RmcCwyMDE1LTAxLTAyVDA4OjQyOjQwLjAwMDAwMCswMDAwLDIwMTUtMDEtMDJUMDg6NDU6NTIuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAzLDM3LjAsMjAxNS0wMS0wMSxvcmdhbmljLENhbmFkYQo0MSxGWFdVT1JHWU5KQUUyNzEsRlhXVU9SR1lOSkFFMjcxLXo4MzRrdGZwLDIwMTUtMDEtMDJUMDg6NDI6NDAuMDAwMDAwKzAwMDAsMjAxNS0wMS0wMlQwOTowMDoxNi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDcsMzcuMCwyMDE1LTAxLTAxLG9yZ2FuaWMsQ2FuYWRhCjQzLEZYV1VPUkdZTkpBRTI3MSxGWFdVT1JHWU5KQUUyNzEtejgzNGt0ZnAsMjAxNS0wMS0wMlQwODo0Mjo0MC4wMDAwMDArMDAwMCwyMDE1LTAxLTAyVDA5OjA5OjI4LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wOCwzNy4wLDIwMTUtMDEtMDEsb3JnYW5pYyxDYW5hZGEKNDUsRlhXVU9SR1lOSkFFMjcxLEZYV1VPUkdZTkpBRTI3MS16ODM0a3RmcCwyMDE1LTAxLTAyVDA4OjQyOjQwLjAwMDAwMCswMDAwLDIwMTUtMDEtMDJUMDk6MTU6NDAuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjEsMzcuMCwyMDE1LTAxLTAxLG9yZ2FuaWMsQ2FuYWRhCjQ5LEZYV1VPUkdZTkpBRTI3MSxGWFdVT1JHWU5KQUUyNzEtM2w5Y3Y4YnMsMjAxNS0wMS0wMlQxMjoyOTo0MC4wMDAwMDArMDAwMCwyMDE1LTAxLTAyVDEyOjM1OjA0LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMywzMy4yLDIwMTUtMDEtMDEsb3JnYW5pYyxDYW5hZGEKNTAsRlhXVU9SR1lOSkFFMjcxLEZYV1VPUkdZTkpBRTI3MS0zbDljdjhicywyMDE1LTAxLTAyVDEyOjI5OjQwLjAwMDAwMCswMDAwLDIwMTUtMDEtMDJUMTI6Mzk6MzQuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyLDMzLjIsMjAxNS0wMS0wMSxvcmdhbmljLENhbmFkYQo1MixGWFdVT1JHWU5KQUUyNzEsRlhXVU9SR1lOSkFFMjcxLTNsOWN2OGJzLDIwMTUtMDEtMDJUMTI6Mjk6NDAuMDAwMDAwKzAwMDAsMjAxNS0wMS0wMlQxMjo1OTowNC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDgsMzMuMiwyMDE1LTAxLTAxLG9yZ2FuaWMsQ2FuYWRhCjU0LENQWlZNR1dRU0lPSDEzMixDUFpWTUdXUVNJT0gxMzItNTlmNmtvaXEsMjAxNS0wMS0wMlQxNTozNzowOC4wMDAwMDArMDAwMCwyMDE1LTAxLTAyVDE1OjUwOjA4LjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDk4LDE1LjUsMjAxNS0wMS0wMSxjcm9zc3Byb21vLFNvdXRoIEtvcmVhCjY3LEZYV1VPUkdZTkpBRTI3MSxGWFdVT1JHWU5KQUUyNzEtNXNtMTJyNHYsMjAxNS0wMS0wM1QwNTo1ODoyOS4wMDAwMDArMDAwMCwyMDE1LTAxLTAzVDA2OjE5OjQ3LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNCwzMC42LDIwMTUtMDEtMDEsb3JnYW5pYyxDYW5hZGEKNjksRlhXVU9SR1lOSkFFMjcxLEZYV1VPUkdZTkpBRTI3MS01c20xMnI0diwyMDE1LTAxLTAzVDA1OjU4OjI5LjAwMDAwMCswMDAwLDIwMTUtMDEtMDNUMDY6MjU6NTkuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA5LDMwLjYsMjAxNS0wMS0wMSxvcmdhbmljLENhbmFkYQo3MCxFQ1BBTk9JWExaSEY4OTYsRUNQQU5PSVhMWkhGODk2LWVvYndnbDRuLDIwMTUtMDEtMDNUMDY6MTE6MTAuMDAwMDAwKzAwMDAsMjAxNS0wMS0wM1QwNjoxNjoyOC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDcsMTAuNiwyMDE1LTAxLTAxLGdvb2dsZSxHZXJtYW55CjczLFFKR1ZPQkxBVElIVzQ1NyxRSkdWT0JMQVRJSFc0NTcteXp2NHBkYXcsMjAxNS0wMS0wM1QxNDozMDoxNy4wMDAwMDArMDAwMCwyMDE1LTAxLTAzVDE0OjM1OjU5LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMzMsMTIuMCwyMDE1LTAxLTAyLG90aGVyX2NhbXBhaWduLFN3ZWRlbgo3NixGS1JDSEVMWVRQQlE2MzEsRktSQ0hFTFlUUEJRNjMxLWc1amt3YXVyLDIwMTUtMDEtMDNUMjE6MzQ6NTEuMDAwMDAwKzAwMDAsMjAxNS0wMS0wM1QyMTozODozOS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDMsMTMuOSwyMDE1LTAxLTAzLG9yZ2FuaWMsTWV4aWNvCjg1LEVRVUROR1pJQ01BSzQ4MixFUVVETkdaSUNNQUs0ODItOHVheTl3NzUsMjAxNS0wMS0wNFQwMToyMTowMy4wMDAwMDArMDAwMCwyMDE1LTAxLTA0VDAxOjQwOjM5LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wOCwyNi44LDIwMTUtMDEtMDQsZ29vZ2xlLEdlcm1hbnkKOTEsRUNQQU5PSVhMWkhGODk2LEVDUEFOT0lYTFpIRjg5Ni03ejloc2FncSwyMDE1LTAxLTA0VDAzOjE1OjM0LjAwMDAwMCswMDAwLDIwMTUtMDEtMDRUMDM6MzI6NTguMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAzLDM1LjEsMjAxNS0wMS0wMSxnb29nbGUsR2VybWFueQo5MyxFQ1BBTk9JWExaSEY4OTYsRUNQQU5PSVhMWkhGODk2LTd6OWhzYWdxLDIwMTUtMDEtMDRUMDM6MTU6MzQuMDAwMDAwKzAwMDAsMjAxNS0wMS0wNFQwMzo0MzoyOC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDIsMzUuMSwyMDE1LTAxLTAxLGdvb2dsZSxHZXJtYW55Cjk4LFBNRkhWTkNVRVlMVDkxMyxQTUZIVk5DVUVZTFQ5MTMtbzhnd3hjMWQsMjAxNS0wMS0wNFQwNToxNDozOC4wMDAwMDArMDAwMCwyMDE1LTAxLTA0VDA1OjIwOjU2LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNywxNS4zLDIwMTUtMDEtMDQsb3JnYW5pYyxBdXN0cmlhCjk5LFBNRkhWTkNVRVlMVDkxMyxQTUZIVk5DVUVZTFQ5MTMtbzhnd3hjMWQsMjAxNS0wMS0wNFQwNToxNDozOC4wMDAwMDArMDAwMCwyMDE1LTAxLTA0VDA1OjIyOjM4LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNCwxNS4zLDIwMTUtMDEtMDQsb3JnYW5pYyxBdXN0cmlhCjEwMCxQTUZIVk5DVUVZTFQ5MTMsUE1GSFZOQ1VFWUxUOTEzLW84Z3d4YzFkLDIwMTUtMDEtMDRUMDU6MTQ6MzguMDAwMDAwKzAwMDAsMjAxNS0wMS0wNFQwNToyNToyNi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDMsMTUuMywyMDE1LTAxLTA0LG9yZ2FuaWMsQXVzdHJpYQoxMDIsSllFQkNMTlVaVFhRNDU3LEpZRUJDTE5VWlRYUTQ1Ny01cnZubzFoNywyMDE1LTAxLTA0VDA5OjE1OjAwLjAwMDAwMCswMDAwLDIwMTUtMDEtMDRUMDk6MzA6MzYuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4wNDUsMzAuMiwyMDE1LTAxLTA0LG90aGVyX2NhbXBhaWduLEVneXB0CjEwMyxKWUVCQ0xOVVpUWFE0NTcsSllFQkNMTlVaVFhRNDU3LTVydm5vMWg3LDIwMTUtMDEtMDRUMDk6MTU6MDAuMDAwMDAwKzAwMDAsMjAxNS0wMS0wNFQwOTo0NDoxOC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDUsMzAuMiwyMDE1LTAxLTA0LG90aGVyX2NhbXBhaWduLEVneXB0CjEwOCxRSkdWT0JMQVRJSFc0NTcsUUpHVk9CTEFUSUhXNDU3LW45dzFrNDI3LDIwMTUtMDEtMDRUMTY6NDE6MjMuMDAwMDAwKzAwMDAsMjAxNS0wMS0wNFQxNjo0Njo1OS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDc3LDM3LjEsMjAxNS0wMS0wMixvdGhlcl9jYW1wYWlnbixTd2VkZW4KMTIwLFpQVElITlNWRllBUTE0NixaUFRJSE5TVkZZQVExNDYtemZramhxM2ksMjAxNS0wMS0wNVQwMTo1Mzo0MC4wMDAwMDArMDAwMCwyMDE1LTAxLTA1VDAyOjAxOjUyLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNDIsMjAuMCwyMDE1LTAxLTA0LGZhY2Vib29rLE1leGljbwoxMjEsWlBUSUhOU1ZGWUFRMTQ2LFpQVElITlNWRllBUTE0Ni16ZmtqaHEzaSwyMDE1LTAxLTA1VDAxOjUzOjQwLjAwMDAwMCswMDAwLDIwMTUtMDEtMDVUMDI6MDU6MDQuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA0MiwyMC4wLDIwMTUtMDEtMDQsZmFjZWJvb2ssTWV4aWNvCjEyMixFUVVETkdaSUNNQUs0ODIsRVFVRE5HWklDTUFLNDgyLTRrdjU4OWVtLDIwMTUtMDEtMDVUMDI6MjA6MTYuMDAwMDAwKzAwMDAsMjAxNS0wMS0wNVQwMjoyMzozNC4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjA3LDI5LjgsMjAxNS0wMS0wNCxnb29nbGUsR2VybWFueQoxMjUsRVFVRE5HWklDTUFLNDgyLEVRVUROR1pJQ01BSzQ4Mi00a3Y1ODllbSwyMDE1LTAxLTA1VDAyOjIwOjE2LjAwMDAwMCswMDAwLDIwMTUtMDEtMDVUMDI6NDA6MzQuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA1LDI5LjgsMjAxNS0wMS0wNCxnb29nbGUsR2VybWFueQoxMzEsRktSQ0hFTFlUUEJRNjMxLEZLUkNIRUxZVFBCUTYzMS1qN284MWQyeCwyMDE1LTAxLTA1VDA4OjUzOjQ4LjAwMDAwMCswMDAwLDIwMTUtMDEtMDVUMDk6MjE6NDguMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4wOTYsMjkuNywyMDE1LTAxLTAzLG9yZ2FuaWMsTWV4aWNvCjEzNixFQ1BBTk9JWExaSEY4OTYsRUNQQU5PSVhMWkhGODk2LXpqN3B4bmN0LDIwMTUtMDEtMDVUMDk6MTM6MDMuMDAwMDAwKzAwMDAsMjAxNS0wMS0wNVQwOTozMjo0NS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMSwyOC4xLDIwMTUtMDEtMDEsZ29vZ2xlLEdlcm1hbnkKMTM4LFpMUVhPQkFUVlBVTjM0NixaTFFYT0JBVFZQVU4zNDYtcDM5bmVzNXEsMjAxNS0wMS0wNVQxMDo1OToxMi4wMDAwMDArMDAwMCwyMDE1LTAxLTA1VDExOjExOjAwLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMzYsMTguOCwyMDE1LTAxLTA1LG9yZ2FuaWMsTm9yd2F5CjE0MCxaTFFYT0JBVFZQVU4zNDYsWkxRWE9CQVRWUFVOMzQ2LWE4eDRqNXFsLDIwMTUtMDEtMDVUMTI6MDg6MTkuMDAwMDAwKzAwMDAsMjAxNS0wMS0wNVQxMjoxMDo0OS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDI3LDE3LjcsMjAxNS0wMS0wNSxvcmdhbmljLE5vcndheQoxNDgsWlBUSUhOU1ZGWUFRMTQ2LFpQVElITlNWRllBUTE0Ni1wNTh5ZW51MywyMDE1LTAxLTA1VDIyOjQyOjQ3LjAwMDAwMCswMDAwLDIwMTUtMDEtMDVUMjM6MDg6MTcuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyNCwzMy4yLDIwMTUtMDEtMDQsZmFjZWJvb2ssTWV4aWNvCjE1MSxHQVlJQkxVQ09FREo3MzIsR0FZSUJMVUNPRURKNzMyLWlrenF5YnUyLDIwMTUtMDEtMDZUMDE6MTE6MDkuMDAwMDAwKzAwMDAsMjAxNS0wMS0wNlQwMTozODo1MS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDUsMzIuNSwyMDE1LTAxLTAzLG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwoxNTMsVlBESktTWlJZUVhFMTIzLFZQREpLU1pSWVFYRTEyMy1wZWt4OGZ6MSwyMDE1LTAxLTA2VDAzOjUwOjMwLjAwMDAwMCswMDAwLDIwMTUtMDEtMDZUMDQ6MDA6MDYuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAzLDM0LjUsMjAxNS0wMS0wNixnb29nbGUsQXVzdHJhbGlhCjE1NixJQ0JBVVpLR1NRUEYxNDUsSUNCQVVaS0dTUVBGMTQ1LXh1ejduNXlwLDIwMTUtMDEtMDZUMDY6MTg6NDguMDAwMDAwKzAwMDAsMjAxNS0wMS0wNlQwNjoyNToyNC4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjA4LDIzLjMsMjAxNS0wMS0wNixnb29nbGUsU291dGggQWZyaWNhCjE2MSxES09BWEVMU0ZQV0M3MjMsREtPQVhFTFNGUFdDNzIzLTI0OW1yemV2LDIwMTUtMDEtMDZUMDk6MjQ6MzUuMDAwMDAwKzAwMDAsMjAxNS0wMS0wNlQwOTozMjoyMy4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDY2LDM0LjYsMjAxNS0wMS0wNSxmYWNlYm9vayxKYXBhbgoxNjUsSllFQkNMTlVaVFhRNDU3LEpZRUJDTE5VWlRYUTQ1Ny0yNzRjejh3cSwyMDE1LTAxLTA2VDA5OjM2OjIzLjAwMDAwMCswMDAwLDIwMTUtMDEtMDZUMTA6MDM6NDcuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4wOTUsMzMuNCwyMDE1LTAxLTA0LG90aGVyX2NhbXBhaWduLEVneXB0CjE3MCxJQ0JBVVpLR1NRUEYxNDUsSUNCQVVaS0dTUVBGMTQ1LWtiaHl2NHByLDIwMTUtMDEtMDZUMTU6MDI6MzkuMDAwMDAwKzAwMDAsMjAxNS0wMS0wNlQxNToxNDowMy4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjA4NCwyMy4zLDIwMTUtMDEtMDYsZ29vZ2xlLFNvdXRoIEFmcmljYQoxODksUE1GSFZOQ1VFWUxUOTEzLFBNRkhWTkNVRVlMVDkxMy1ycHduYXV2MSwyMDE1LTAxLTA2VDIzOjAxOjU4LjAwMDAwMCswMDAwLDIwMTUtMDEtMDZUMjM6MDI6MDQuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA4LDE3LjYsMjAxNS0wMS0wNCxvcmdhbmljLEF1c3RyaWEKMTk3LEVRVUROR1pJQ01BSzQ4MixFUVVETkdaSUNNQUs0ODIta3h2Y21xZnIsMjAxNS0wMS0wNlQyMzozMDozMC4wMDAwMDArMDAwMCwyMDE1LTAxLTA2VDIzOjQ1OjU0LjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMSwxNy40LDIwMTUtMDEtMDQsZ29vZ2xlLEdlcm1hbnkKMjAwLFpQVElITlNWRllBUTE0NixaUFRJSE5TVkZZQVExNDYtc2MzbWJ1MmUsMjAxNS0wMS0wNlQyMzo0NDo1MS4wMDAwMDArMDAwMCwyMDE1LTAxLTA2VDIzOjQ4OjMzLjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDcyLDI3LjMsMjAxNS0wMS0wNCxmYWNlYm9vayxNZXhpY28KMjAzLFpQVElITlNWRllBUTE0NixaUFRJSE5TVkZZQVExNDYtc2MzbWJ1MmUsMjAxNS0wMS0wNlQyMzo0NDo1MS4wMDAwMDArMDAwMCwyMDE1LTAxLTA3VDAwOjA5OjI3LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNiwyNy4zLDIwMTUtMDEtMDQsZmFjZWJvb2ssTWV4aWNvCjIxMixWUERKS1NaUllRWEUxMjMsVlBESktTWlJZUVhFMTIzLWQ0eWdjenI5LDIwMTUtMDEtMDdUMDE6MTc6MjkuMDAwMDAwKzAwMDAsMjAxNS0wMS0wN1QwMToyMzoyOS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDIsMzUuMiwyMDE1LTAxLTA2LGdvb2dsZSxBdXN0cmFsaWEKMjE1LEhLSlBPTVFXTFZESTY3NCxIS0pQT01RV0xWREk2NzQta2hiaWYzeGUsMjAxNS0wMS0wN1QwMzo0ODozOC4wMDAwMDArMDAwMCwyMDE1LTAxLTA3VDAzOjUwOjAyLjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDksMzUuMiwyMDE1LTAxLTA2LG90aGVyX2NhbXBhaWduLFNwYWluCjIxNyxIS0pQT01RV0xWREk2NzQsSEtKUE9NUVdMVkRJNjc0LWtoYmlmM3hlLDIwMTUtMDEtMDdUMDM6NDg6MzguMDAwMDAwKzAwMDAsMjAxNS0wMS0wN1QwMzo1Mzo1Ni4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjA5LDM1LjIsMjAxNS0wMS0wNixvdGhlcl9jYW1wYWlnbixTcGFpbgoyMTksR1NRSlhJT0tZTUVBNzEyLEdTUUpYSU9LWU1FQTcxMi00NXpldWxwZCwyMDE1LTAxLTA3VDA0OjQ2OjEyLjAwMDAwMCswMDAwLDIwMTUtMDEtMDdUMDQ6NTA6MzYuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAzLDM1LjIsMjAxNS0wMS0wNyxnb29nbGUsR2VybWFueQoyMjUsUUpHVk9CTEFUSUhXNDU3LFFKR1ZPQkxBVElIVzQ1Ny1jMzE3YWx3aiwyMDE1LTAxLTA3VDA1OjUzOjM2LjAwMDAwMCswMDAwLDIwMTUtMDEtMDdUMDU6NTg6NDIuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA3NywxNC4yLDIwMTUtMDEtMDIsb3RoZXJfY2FtcGFpZ24sU3dlZGVuCjIzMCxKWUVCQ0xOVVpUWFE0NTcsSllFQkNMTlVaVFhRNDU3LTl0cWlsc3c4LDIwMTUtMDEtMDdUMDc6MTU6NTMuMDAwMDAwKzAwMDAsMjAxNS0wMS0wN1QwNzozMTo0MS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDMsMzcuMywyMDE1LTAxLTA0LG90aGVyX2NhbXBhaWduLEVneXB0CjIzMixKWUVCQ0xOVVpUWFE0NTcsSllFQkNMTlVaVFhRNDU3LTl0cWlsc3c4LDIwMTUtMDEtMDdUMDc6MTU6NTMuMDAwMDAwKzAwMDAsMjAxNS0wMS0wN1QwNzo0Njo1OS4wMDAwMDArMDAwMCxhZCxhZF8xNXNlYywwLjA4LDM3LjMsMjAxNS0wMS0wNCxvdGhlcl9jYW1wYWlnbixFZ3lwdAoyMzMsSllFQkNMTlVaVFhRNDU3LEpZRUJDTE5VWlRYUTQ1Ny03b3o2NXdmYiwyMDE1LTAxLTA3VDA4OjI0OjAxLjAwMDAwMCswMDAwLDIwMTUtMDEtMDdUMDg6MzQ6MDEuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyLDIxLjAsMjAxNS0wMS0wNCxvdGhlcl9jYW1wYWlnbixFZ3lwdAoyMzUsSllFQkNMTlVaVFhRNDU3LEpZRUJDTE5VWlRYUTQ1Ny03b3o2NXdmYiwyMDE1LTAxLTA3VDA4OjI0OjAxLjAwMDAwMCswMDAwLDIwMTUtMDEtMDdUMDg6MzQ6MzEuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4wNSwyMS4wLDIwMTUtMDEtMDQsb3RoZXJfY2FtcGFpZ24sRWd5cHQKMjM2LEpZRUJDTE5VWlRYUTQ1NyxKWUVCQ0xOVVpUWFE0NTctN296NjV3ZmIsMjAxNS0wMS0wN1QwODoyNDowMS4wMDAwMDArMDAwMCwyMDE1LTAxLTA3VDA4OjM0OjQzLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMzUsMjEuMCwyMDE1LTAxLTA0LG90aGVyX2NhbXBhaWduLEVneXB0CjIzOCxRSkdWT0JMQVRJSFc0NTcsUUpHVk9CTEFUSUhXNDU3LW9qd21zcTgzLDIwMTUtMDEtMDdUMDg6Mjk6NDUuMDAwMDAwKzAwMDAsMjAxNS0wMS0wN1QwODozNjoyMS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDk5LDE3LjcsMjAxNS0wMS0wMixvdGhlcl9jYW1wYWlnbixTd2VkZW4KMjM5LFFKR1ZPQkxBVElIVzQ1NyxRSkdWT0JMQVRJSFc0NTctb2p3bXNxODMsMjAxNS0wMS0wN1QwODoyOTo0NS4wMDAwMDArMDAwMCwyMDE1LTAxLTA3VDA4OjQyOjU3LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wOTksMTcuNywyMDE1LTAxLTAyLG90aGVyX2NhbXBhaWduLFN3ZWRlbgoyNDYsTERTVUhDUkFZS01PMTc5LExEU1VIQ1JBWUtNTzE3OS00aWh0b3F5dSwyMDE1LTAxLTA3VDEyOjE4OjMwLjAwMDAwMCswMDAwLDIwMTUtMDEtMDdUMTI6MzQ6MDAuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA1NCwyNi4yLDIwMTUtMDEtMDcsb3RoZXJfY2FtcGFpZ24sUG9ydHVnYWwKMjUwLEtCRVFaR0ZTUlBISjQ3OSxLQkVRWkdGU1JQSEo0NzktNzY1amZ1bWssMjAxNS0wMS0wN1QxMjo0NToxMC4wMDAwMDArMDAwMCwyMDE1LTAxLTA3VDEyOjU0OjEwLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMjEsMjIuMSwyMDE1LTAxLTA3LG9yZ2FuaWMsUnVzc2lhCjI1MixLQkVRWkdGU1JQSEo0NzksS0JFUVpHRlNSUEhKNDc5LTc2NWpmdW1rLDIwMTUtMDEtMDdUMTI6NDU6MTAuMDAwMDAwKzAwMDAsMjAxNS0wMS0wN1QxMjo1NjoyMi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDMsMjIuMSwyMDE1LTAxLTA3LG9yZ2FuaWMsUnVzc2lhCjI1MyxLSUxXWllIUlNKRUczMTYsS0lMV1pZSFJTSkVHMzE2LW90OWJ2bGFkLDIwMTUtMDEtMDdUMTM6NDg6MzQuMDAwMDAwKzAwMDAsMjAxNS0wMS0wN1QxNDowNTo1Mi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDg4LDMwLjgsMjAxNS0wMS0wNCxvcmdhbmljLERlbm1hcmsKMjU0LFBaQk5SS1NNVUxIWDIxMyxQWkJOUktTTVVMSFgyMTMta29zdjhobGUsMjAxNS0wMS0wN1QxMzo0OToxOS4wMDAwMDArMDAwMCwyMDE1LTAxLTA3VDE0OjA0OjAxLjAwMDAwMCswMDAwLGFkLGFkXzE1c2VjLDAuMDU2LDIyLjIsMjAxNS0wMS0wNyxvcmdhbmljLEluZGlhCjI1NSxQWkJOUktTTVVMSFgyMTMsUFpCTlJLU01VTEhYMjEzLWtvc3Y4aGxlLDIwMTUtMDEtMDdUMTM6NDk6MTkuMDAwMDAwKzAwMDAsMjAxNS0wMS0wN1QxNDowNTozMS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDA0LDIyLjIsMjAxNS0wMS0wNyxvcmdhbmljLEluZGlhCjI2MixPTUNWVUFJS1NEVFI2NTEsT01DVlVBSUtTRFRSNjUxLWJkbTNvODI2LDIwMTUtMDEtMDdUMTM6NTM6NDYuMDAwMDAwKzAwMDAsMjAxNS0wMS0wN1QxNDoxNTo1Mi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDMsMzUuNiwyMDE1LTAxLTA3LG90aGVyX2NhbXBhaWduLFVuaXRlZCBTdGF0ZXMKMjgwLFZQREpLU1pSWVFYRTEyMyxWUERKS1NaUllRWEUxMjMtYWwzOG1pcmUsMjAxNS0wMS0wN1QxNzoyMDowNy4wMDAwMDArMDAwMCwyMDE1LTAxLTA3VDE3OjI0OjA3LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNiwzMC4zLDIwMTUtMDEtMDYsZ29vZ2xlLEF1c3RyYWxpYQoyODQsVlBESktTWlJZUVhFMTIzLFZQREpLU1pSWVFYRTEyMy1hbDM4bWlyZSwyMDE1LTAxLTA3VDE3OjIwOjA3LjAwMDAwMCswMDAwLDIwMTUtMDEtMDdUMTc6MzQ6MTkuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA1LDMwLjMsMjAxNS0wMS0wNixnb29nbGUsQXVzdHJhbGlhCjI4NSxWUERKS1NaUllRWEUxMjMsVlBESktTWlJZUVhFMTIzLWFsMzhtaXJlLDIwMTUtMDEtMDdUMTc6MjA6MDcuMDAwMDAwKzAwMDAsMjAxNS0wMS0wN1QxNzo0ODowNy4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDgsMzAuMywyMDE1LTAxLTA2LGdvb2dsZSxBdXN0cmFsaWEKMjg3LFBaQk5SS1NNVUxIWDIxMyxQWkJOUktTTVVMSFgyMTMtanhud2FoNHYsMjAxNS0wMS0wN1QxNzo1NToyMi4wMDAwMDArMDAwMCwyMDE1LTAxLTA3VDE3OjU4OjQ2LjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDMsMzAuOSwyMDE1LTAxLTA3LG9yZ2FuaWMsSW5kaWEKMjg4LFBaQk5SS1NNVUxIWDIxMyxQWkJOUktTTVVMSFgyMTMtanhud2FoNHYsMjAxNS0wMS0wN1QxNzo1NToyMi4wMDAwMDArMDAwMCwyMDE1LTAxLTA3VDE4OjEyOjA0LjAwMDAwMCswMDAwLGFkLGFkXzE1c2VjLDAuMDQsMzAuOSwyMDE1LTAxLTA3LG9yZ2FuaWMsSW5kaWEKMjg5LFBaQk5SS1NNVUxIWDIxMyxQWkJOUktTTVVMSFgyMTMtanhud2FoNHYsMjAxNS0wMS0wN1QxNzo1NToyMi4wMDAwMDArMDAwMCwyMDE1LTAxLTA3VDE4OjIyOjI4LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMiwzMC45LDIwMTUtMDEtMDcsb3JnYW5pYyxJbmRpYQoyOTEsUFpCTlJLU01VTEhYMjEzLFBaQk5SS1NNVUxIWDIxMy1qeG53YWg0diwyMDE1LTAxLTA3VDE3OjU1OjIyLjAwMDAwMCswMDAwLDIwMTUtMDEtMDdUMTg6MjQ6MjguMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAxNCwzMC45LDIwMTUtMDEtMDcsb3JnYW5pYyxJbmRpYQoyOTQsU0ZKQ1pPVEtHQUlENjQ1LFNGSkNaT1RLR0FJRDY0NS1pYmRtd3Y5NywyMDE1LTAxLTA3VDE4OjI3OjQ2LjAwMDAwMCswMDAwLDIwMTUtMDEtMDdUMTg6Mzc6NTguMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4wNywzMC4wLDIwMTUtMDEtMDYsZ29vZ2xlLEZyYW5jZQozMDAsSUNCQVVaS0dTUVBGMTQ1LElDQkFVWktHU1FQRjE0NS1wYTRkbXFpMywyMDE1LTAxLTA3VDIwOjI2OjQxLjAwMDAwMCswMDAwLDIwMTUtMDEtMDdUMjA6MzI6MDUuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4wNTYsMTkuOSwyMDE1LTAxLTA2LGdvb2dsZSxTb3V0aCBBZnJpY2EKMzAxLElDQkFVWktHU1FQRjE0NSxJQ0JBVVpLR1NRUEYxNDUtcGE0ZG1xaTMsMjAxNS0wMS0wN1QyMDoyNjo0MS4wMDAwMDArMDAwMCwyMDE1LTAxLTA3VDIwOjQxOjM1LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMjIsMTkuOSwyMDE1LTAxLTA2LGdvb2dsZSxTb3V0aCBBZnJpY2EKMzAyLFpQVElITlNWRllBUTE0NixaUFRJSE5TVkZZQVExNDYteHQzNzZlZmQsMjAxNS0wMS0wN1QyMDo1Mzo0Mi4wMDAwMDArMDAwMCwyMDE1LTAxLTA3VDIxOjAwOjM2LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNTQsMzEuMywyMDE1LTAxLTA0LGZhY2Vib29rLE1leGljbwozMDYsS0JFUVpHRlNSUEhKNDc5LEtCRVFaR0ZTUlBISjQ3OS02eHp5bmp2ZCwyMDE1LTAxLTA3VDIyOjM3OjM3LjAwMDAwMCswMDAwLDIwMTUtMDEtMDdUMjI6NDM6NTUuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyNywyNy40LDIwMTUtMDEtMDcsb3JnYW5pYyxSdXNzaWEKMzA4LEtCRVFaR0ZTUlBISjQ3OSxLQkVRWkdGU1JQSEo0NzktNnh6eW5qdmQsMjAxNS0wMS0wN1QyMjozNzozNy4wMDAwMDArMDAwMCwyMDE1LTAxLTA3VDIyOjU4OjEzLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMDksMjcuNCwyMDE1LTAxLTA3LG9yZ2FuaWMsUnVzc2lhCjMxMyxHQVlJQkxVQ09FREo3MzIsR0FZSUJMVUNPRURKNzMyLTlpZmd0dmFyLDIwMTUtMDEtMDdUMjI6NTY6MzkuMDAwMDAwKzAwMDAsMjAxNS0wMS0wN1QyMzoyMjo1MS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDQsMzQuNSwyMDE1LTAxLTAzLG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwozMTcsSlZCWkNQS1hIRk1VNDkxLEpWQlpDUEtYSEZNVTQ5MS1ib3dnZjd0biwyMDE1LTAxLTA3VDIzOjIyOjI4LjAwMDAwMCswMDAwLDIwMTUtMDEtMDdUMjM6Mjc6NDAuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA5LDIxLjEsMjAxNS0wMS0wNyxvcmdhbmljLFVuaXRlZCBTdGF0ZXMKMzE4LEpWQlpDUEtYSEZNVTQ5MSxKVkJaQ1BLWEhGTVU0OTEtYm93Z2Y3dG4sMjAxNS0wMS0wN1QyMzoyMjoyOC4wMDAwMDArMDAwMCwyMDE1LTAxLTA3VDIzOjI4OjA0LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNywyMS4xLDIwMTUtMDEtMDcsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjMyMSxKVkJaQ1BLWEhGTVU0OTEsSlZCWkNQS1hIRk1VNDkxLWJvd2dmN3RuLDIwMTUtMDEtMDdUMjM6MjI6MjguMDAwMDAwKzAwMDAsMjAxNS0wMS0wN1QyMzozNzoyMi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDMsMjEuMSwyMDE1LTAxLTA3LG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwozMjIsUFpCTlJLU01VTEhYMjEzLFBaQk5SS1NNVUxIWDIxMy1zaXh1OG82aiwyMDE1LTAxLTA4VDAwOjM2OjEzLjAwMDAwMCswMDAwLDIwMTUtMDEtMDhUMDA6Mzk6MDcuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyLDEyLjAsMjAxNS0wMS0wNyxvcmdhbmljLEluZGlhCjMyMyxQWkJOUktTTVVMSFgyMTMsUFpCTlJLU01VTEhYMjEzLXNpeHU4bzZqLDIwMTUtMDEtMDhUMDA6MzY6MTMuMDAwMDAwKzAwMDAsMjAxNS0wMS0wOFQwMDozOToyNS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDIyLDEyLjAsMjAxNS0wMS0wNyxvcmdhbmljLEluZGlhCjMyOSxFUVVETkdaSUNNQUs0ODIsRVFVRE5HWklDTUFLNDgyLXkzZG96d3ZzLDIwMTUtMDEtMDhUMDI6Mjg6MzguMDAwMDAwKzAwMDAsMjAxNS0wMS0wOFQwMjo0NDo1Ni4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjA5LDI5LjMsMjAxNS0wMS0wNCxnb29nbGUsR2VybWFueQozMzEsRVFVRE5HWklDTUFLNDgyLEVRVUROR1pJQ01BSzQ4Mi15M2Rvend2cywyMDE1LTAxLTA4VDAyOjI4OjM4LjAwMDAwMCswMDAwLDIwMTUtMDEtMDhUMDI6NTU6MzguMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA2LDI5LjMsMjAxNS0wMS0wNCxnb29nbGUsR2VybWFueQozMzgsUE1GSFZOQ1VFWUxUOTEzLFBNRkhWTkNVRVlMVDkxMy16eGV5cGFzbSwyMDE1LTAxLTA4VDA1OjA5OjA0LjAwMDAwMCswMDAwLDIwMTUtMDEtMDhUMDU6MTY6NDAuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4wNyw5LjgsMjAxNS0wMS0wNCxvcmdhbmljLEF1c3RyaWEKMzM5LFZQREpLU1pSWVFYRTEyMyxWUERKS1NaUllRWEUxMjMtNTMyeGJ1dnksMjAxNS0wMS0wOFQwNTowOTo0MS4wMDAwMDArMDAwMCwyMDE1LTAxLTA4VDA1OjEzOjU5LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNiwxNy44LDIwMTUtMDEtMDYsZ29vZ2xlLEF1c3RyYWxpYQozNDgsSUNCQVVaS0dTUVBGMTQ1LElDQkFVWktHU1FQRjE0NS1mbGFveWRqNSwyMDE1LTAxLTA4VDEyOjQ4OjEzLjAwMDAwMCswMDAwLDIwMTUtMDEtMDhUMTM6MDg6MjUuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAxNDk5LDI3LjksMjAxNS0wMS0wNixnb29nbGUsU291dGggQWZyaWNhCjM1MCxQWkJOUktTTVVMSFgyMTMsUFpCTlJLU01VTEhYMjEzLW0ybjZ0azFpLDIwMTUtMDEtMDhUMTQ6MTA6MTguMDAwMDAwKzAwMDAsMjAxNS0wMS0wOFQxNDoxNjozMC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDEsMzQuMiwyMDE1LTAxLTA3LG9yZ2FuaWMsSW5kaWEKMzUzLFBaQk5SS1NNVUxIWDIxMyxQWkJOUktTTVVMSFgyMTMtbTJuNnRrMWksMjAxNS0wMS0wOFQxNDoxMDoxOC4wMDAwMDArMDAwMCwyMDE1LTAxLTA4VDE0OjM4OjA2LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMDYsMzQuMiwyMDE1LTAxLTA3LG9yZ2FuaWMsSW5kaWEKMzU0LFBaQk5SS1NNVUxIWDIxMyxQWkJOUktTTVVMSFgyMTMtbTJuNnRrMWksMjAxNS0wMS0wOFQxNDoxMDoxOC4wMDAwMDArMDAwMCwyMDE1LTAxLTA4VDE0OjM4OjA2LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMjQsMzQuMiwyMDE1LTAxLTA3LG9yZ2FuaWMsSW5kaWEKMzYxLEtCRVFaR0ZTUlBISjQ3OSxLQkVRWkdGU1JQSEo0NzktbTVpcHF3MmIsMjAxNS0wMS0wOFQxNTowNzo0NS4wMDAwMDArMDAwMCwyMDE1LTAxLTA4VDE1OjE1OjQ1LjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDMsOS4yLDIwMTUtMDEtMDcsb3JnYW5pYyxSdXNzaWEKMzYyLEtCRVFaR0ZTUlBISjQ3OSxLQkVRWkdGU1JQSEo0NzktZjJlNXJkYWIsMjAxNS0wMS0wOFQxNjoxMTowOC4wMDAwMDArMDAwMCwyMDE1LTAxLTA4VDE2OjE1OjIwLjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDU0LDMzLjEsMjAxNS0wMS0wNyxvcmdhbmljLFJ1c3NpYQozNjUsS0JFUVpHRlNSUEhKNDc5LEtCRVFaR0ZTUlBISjQ3OS1mMmU1cmRhYiwyMDE1LTAxLTA4VDE2OjExOjA4LjAwMDAwMCswMDAwLDIwMTUtMDEtMDhUMTY6MzU6MDIuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAxOCwzMy4xLDIwMTUtMDEtMDcsb3JnYW5pYyxSdXNzaWEKMzY5LFZQREpLU1pSWVFYRTEyMyxWUERKS1NaUllRWEUxMjMtOW5hZzRocGksMjAxNS0wMS0wOFQxODowNDo1Ni4wMDAwMDArMDAwMCwyMDE1LTAxLTA4VDE4OjE0OjQ0LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNCwzNy45LDIwMTUtMDEtMDYsZ29vZ2xlLEF1c3RyYWxpYQozNzEsVlBESktTWlJZUVhFMTIzLFZQREpLU1pSWVFYRTEyMy05bmFnNGhwaSwyMDE1LTAxLTA4VDE4OjA0OjU2LjAwMDAwMCswMDAwLDIwMTUtMDEtMDhUMTg6MjM6NTAuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA1LDM3LjksMjAxNS0wMS0wNixnb29nbGUsQXVzdHJhbGlhCjM3NyxHU1FKWElPS1lNRUE3MTIsR1NRSlhJT0tZTUVBNzEyLTVtNHZzOWtjLDIwMTUtMDEtMDhUMjA6MDg6NTIuMDAwMDAwKzAwMDAsMjAxNS0wMS0wOFQyMDoxMToyOC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDIsMzEuNiwyMDE1LTAxLTA3LGdvb2dsZSxHZXJtYW55CjM5NCxPTUNWVUFJS1NEVFI2NTEsT01DVlVBSUtTRFRSNjUxLTE0YWV1aWRrLDIwMTUtMDEtMDlUMDE6MTg6NDMuMDAwMDAwKzAwMDAsMjAxNS0wMS0wOVQwMTo0MDowMS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDQsMjQuNiwyMDE1LTAxLTA3LG90aGVyX2NhbXBhaWduLFVuaXRlZCBTdGF0ZXMKMzk1LEdTUUpYSU9LWU1FQTcxMixHU1FKWElPS1lNRUE3MTIteXVnZjZhZGgsMjAxNS0wMS0wOVQwMTo1ODo1Mi4wMDAwMDArMDAwMCwyMDE1LTAxLTA5VDAyOjExOjUyLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNywyNy43LDIwMTUtMDEtMDcsZ29vZ2xlLEdlcm1hbnkKNDAxLFFEVVpKSUVUQ0FHVzY1NCxRRFVaSklFVENBR1c2NTQtZ21pNmJvZjEsMjAxNS0wMS0wOVQwMzowNDowNS4wMDAwMDArMDAwMCwyMDE1LTAxLTA5VDAzOjEwOjA1LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNiwxMS4zLDIwMTUtMDEtMDcsZmFjZWJvb2ssU3dpdHplcmxhbmQKNDAzLEtCRVFaR0ZTUlBISjQ3OSxLQkVRWkdGU1JQSEo0NzktN3BhZWtvYzIsMjAxNS0wMS0wOVQwMzowNDo0MS4wMDAwMDArMDAwMCwyMDE1LTAxLTA5VDAzOjE3OjU5LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMywxOC41LDIwMTUtMDEtMDcsb3JnYW5pYyxSdXNzaWEKNDA2LFpQVElITlNWRllBUTE0NixaUFRJSE5TVkZZQVExNDYtNW80N2QyaWwsMjAxNS0wMS0wOVQwNToxMDozMS4wMDAwMDArMDAwMCwyMDE1LTAxLTA5VDA1OjI0OjQ5LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMjQsMzguNywyMDE1LTAxLTA0LGZhY2Vib29rLE1leGljbwo0MTEsUU5MVlJERU9YRllKODkyLFFOTFZSREVPWEZZSjg5Mi1zZjd3ZWh6OSwyMDE1LTAxLTA5VDA3OjI3OjE0LjAwMDAwMCswMDAwLDIwMTUtMDEtMDlUMDc6Mjk6MzIuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAzLDguMSwyMDE1LTAxLTA5LGNyb3NzcHJvbW8sQXVzdHJhbGlhCjQxMixTRkpDWk9US0dBSUQ2NDUsU0ZKQ1pPVEtHQUlENjQ1LWtsNnMyOXV3LDIwMTUtMDEtMDlUMDg6MTg6MTQuMDAwMDAwKzAwMDAsMjAxNS0wMS0wOVQwODoyNzo0NC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDQsMjkuOCwyMDE1LTAxLTA2LGdvb2dsZSxGcmFuY2UKNDE3LEVRVUROR1pJQ01BSzQ4MixFUVVETkdaSUNNQUs0ODItdXB2M2Q4NWgsMjAxNS0wMS0wOVQwODoyMjowMC4wMDAwMDArMDAwMCwyMDE1LTAxLTA5VDA4OjI2OjU0LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMiwzOC45LDIwMTUtMDEtMDQsZ29vZ2xlLEdlcm1hbnkKNDI2LFFOTFZSREVPWEZZSjg5MixRTkxWUkRFT1hGWUo4OTItY3Z3dGpmbzIsMjAxNS0wMS0wOVQxMzo1NDoyOS4wMDAwMDArMDAwMCwyMDE1LTAxLTA5VDEzOjU2OjU5LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMywyOC41LDIwMTUtMDEtMDksY3Jvc3Nwcm9tbyxBdXN0cmFsaWEKNDI4LFFOTFZSREVPWEZZSjg5MixRTkxWUkRFT1hGWUo4OTItY3Z3dGpmbzIsMjAxNS0wMS0wOVQxMzo1NDoyOS4wMDAwMDArMDAwMCwyMDE1LTAxLTA5VDE0OjIxOjI5LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNiwyOC41LDIwMTUtMDEtMDksY3Jvc3Nwcm9tbyxBdXN0cmFsaWEKNDM0LEdGTFlKSEFQTVpXRDYzMSxHRkxZSkhBUE1aV0Q2MzEtd2R6Mzd2Y3QsMjAxNS0wMS0wOVQxNTo1MDoxOC4wMDAwMDArMDAwMCwyMDE1LTAxLTA5VDE1OjUwOjQyLjAwMDAwMCswMDAwLGFkLGFkXzE1c2VjLDAuMDYyLDMwLjksMjAxNS0wMS0wOSxvcmdhbmljLEluZGlhCjQzNSxHRkxZSkhBUE1aV0Q2MzEsR0ZMWUpIQVBNWldENjMxLXdkejM3dmN0LDIwMTUtMDEtMDlUMTU6NTA6MTguMDAwMDAwKzAwMDAsMjAxNS0wMS0wOVQxNTo1MzowNi4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjAyNCwzMC45LDIwMTUtMDEtMDksb3JnYW5pYyxJbmRpYQo0MzYsR0ZMWUpIQVBNWldENjMxLEdGTFlKSEFQTVpXRDYzMS13ZHozN3ZjdCwyMDE1LTAxLTA5VDE1OjUwOjE4LjAwMDAwMCswMDAwLDIwMTUtMDEtMDlUMTU6NTg6MTIuMDAwMDAwKzAwMDAsYWQsYWRfMTVzZWMsMC4wNTQsMzAuOSwyMDE1LTAxLTA5LG9yZ2FuaWMsSW5kaWEKNDM3LEdGTFlKSEFQTVpXRDYzMSxHRkxZSkhBUE1aV0Q2MzEtd2R6Mzd2Y3QsMjAxNS0wMS0wOVQxNTo1MDoxOC4wMDAwMDArMDAwMCwyMDE1LTAxLTA5VDE2OjEyOjA2LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMTQsMzAuOSwyMDE1LTAxLTA5LG9yZ2FuaWMsSW5kaWEKNDM4LEdGTFlKSEFQTVpXRDYzMSxHRkxZSkhBUE1aV0Q2MzEtd2R6Mzd2Y3QsMjAxNS0wMS0wOVQxNTo1MDoxOC4wMDAwMDArMDAwMCwyMDE1LTAxLTA5VDE2OjE3OjM2LjAwMDAwMCswMDAwLGFkLGFkXzE1c2VjLDAuMDUsMzAuOSwyMDE1LTAxLTA5LG9yZ2FuaWMsSW5kaWEKNDQxLE5NUlVXSEFZSlBCUTgyNCxOTVJVV0hBWUpQQlE4MjQtdm9mM2c5eXQsMjAxNS0wMS0wOVQxODoyNzowMS4wMDAwMDArMDAwMCwyMDE1LTAxLTA5VDE4OjQwOjQ5LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNDksMzguMSwyMDE1LTAxLTA4LG9yZ2FuaWMsSG9uZyBLb25nCjQ0NCxaUFRJSE5TVkZZQVExNDYsWlBUSUhOU1ZGWUFRMTQ2LTcydWNzdmtvLDIwMTUtMDEtMDlUMTg6NTI6MTEuMDAwMDAwKzAwMDAsMjAxNS0wMS0wOVQxODo1MjoyOS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDM2LDM2LjgsMjAxNS0wMS0wNCxmYWNlYm9vayxNZXhpY28KNDQ3LFpQVElITlNWRllBUTE0NixaUFRJSE5TVkZZQVExNDYtNzJ1Y3N2a28sMjAxNS0wMS0wOVQxODo1MjoxMS4wMDAwMDArMDAwMCwyMDE1LTAxLTA5VDE5OjIxOjM1LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMzYsMzYuOCwyMDE1LTAxLTA0LGZhY2Vib29rLE1leGljbwo0NDksTERTVUhDUkFZS01PMTc5LExEU1VIQ1JBWUtNTzE3OS1uNWJmZ2p1OCwyMDE1LTAxLTA5VDIwOjIxOjM0LjAwMDAwMCswMDAwLDIwMTUtMDEtMDlUMjA6MjM6MTYuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA1NCwzNS4zLDIwMTUtMDEtMDcsb3RoZXJfY2FtcGFpZ24sUG9ydHVnYWwKNDUwLExEU1VIQ1JBWUtNTzE3OSxMRFNVSENSQVlLTU8xNzktbjViZmdqdTgsMjAxNS0wMS0wOVQyMDoyMTozNC4wMDAwMDArMDAwMCwyMDE1LTAxLTA5VDIwOjM1OjQwLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNzIsMzUuMywyMDE1LTAxLTA3LG90aGVyX2NhbXBhaWduLFBvcnR1Z2FsCjQ2MixMRFNVSENSQVlLTU8xNzksTERTVUhDUkFZS01PMTc5LTR4a282OWVpLDIwMTUtMDEtMDlUMjM6NTQ6MTcuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMFQwMDowMjoyMy4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDE4LDIwLjMsMjAxNS0wMS0wNyxvdGhlcl9jYW1wYWlnbixQb3J0dWdhbAo0NjUsTERTVUhDUkFZS01PMTc5LExEU1VIQ1JBWUtNTzE3OS00eGtvNjllaSwyMDE1LTAxLTA5VDIzOjU0OjE3LjAwMDAwMCswMDAwLDIwMTUtMDEtMTBUMDA6MTE6NDEuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA3MiwyMC4zLDIwMTUtMDEtMDcsb3RoZXJfY2FtcGFpZ24sUG9ydHVnYWwKNDY2LFFKR1ZPQkxBVElIVzQ1NyxRSkdWT0JMQVRJSFc0NTctN29obGcyNmksMjAxNS0wMS0xMFQwMDo0OTozMS4wMDAwMDArMDAwMCwyMDE1LTAxLTEwVDAwOjUwOjEzLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wODgsMTkuNSwyMDE1LTAxLTAyLG90aGVyX2NhbXBhaWduLFN3ZWRlbgo0NjgsUUpHVk9CTEFUSUhXNDU3LFFKR1ZPQkxBVElIVzQ1Ny03b2hsZzI2aSwyMDE1LTAxLTEwVDAwOjQ5OjMxLjAwMDAwMCswMDAwLDIwMTUtMDEtMTBUMDE6MDg6NTUuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA4OCwxOS41LDIwMTUtMDEtMDIsb3RoZXJfY2FtcGFpZ24sU3dlZGVuCjQ2OSxHU1FKWElPS1lNRUE3MTIsR1NRSlhJT0tZTUVBNzEyLTN4cTd3ZzFsLDIwMTUtMDEtMTBUMDA6NTc6MzEuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMFQwMDo1OTowNy4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjA4LDM5LjgsMjAxNS0wMS0wNyxnb29nbGUsR2VybWFueQo0NzEsR1NRSlhJT0tZTUVBNzEyLEdTUUpYSU9LWU1FQTcxMi0zeHE3d2cxbCwyMDE1LTAxLTEwVDAwOjU3OjMxLjAwMDAwMCswMDAwLDIwMTUtMDEtMTBUMDE6Mjg6MzcuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4wOCwzOS44LDIwMTUtMDEtMDcsZ29vZ2xlLEdlcm1hbnkKNDcyLFJNT1NXSEpHRUxDSTY3NSxSTU9TV0hKR0VMQ0k2NzUtejl5bnVzcHIsMjAxNS0wMS0xMFQwNDowOTo1MC4wMDAwMDArMDAwMCwyMDE1LTAxLTEwVDA0OjE4OjU2LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNSwyNy4yLDIwMTUtMDEtMTAsb3RoZXJfY2FtcGFpZ24sRnJhbmNlCjQ3NCxSTU9TV0hKR0VMQ0k2NzUsUk1PU1dISkdFTENJNjc1LXo5eW51c3ByLDIwMTUtMDEtMTBUMDQ6MDk6NTAuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMFQwNDoyODozOC4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjEsMjcuMiwyMDE1LTAxLTEwLG90aGVyX2NhbXBhaWduLEZyYW5jZQo0NzUsUk1PU1dISkdFTENJNjc1LFJNT1NXSEpHRUxDSTY3NS16OXludXNwciwyMDE1LTAxLTEwVDA0OjA5OjUwLjAwMDAwMCswMDAwLDIwMTUtMDEtMTBUMDQ6Mjk6NTYuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjEsMjcuMiwyMDE1LTAxLTEwLG90aGVyX2NhbXBhaWduLEZyYW5jZQo0ODIsVVpRRkhEQkVNWVBWNTk0LFVaUUZIREJFTVlQVjU5NC1ha2NwenR1bywyMDE1LTAxLTEwVDA1OjQ4OjQ2LjAwMDAwMCswMDAwLDIwMTUtMDEtMTBUMDU6NDg6NTguMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA3Miw4LjEsMjAxNS0wMS0xMCxnb29nbGUsU3dpdHplcmxhbmQKNDgzLEdBWUlCTFVDT0VESjczMixHQVlJQkxVQ09FREo3MzItOHVuYzE3MmwsMjAxNS0wMS0xMFQwNjoyMTozNS4wMDAwMDArMDAwMCwyMDE1LTAxLTEwVDA2OjM3OjU5LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMywzNC44LDIwMTUtMDEtMDMsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjQ5MyxMRFNVSENSQVlLTU8xNzksTERTVUhDUkFZS01PMTc5LW1hdzdxZXIxLDIwMTUtMDEtMTBUMDc6MzU6NTcuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMFQwNzo1MTozOS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDcyLDI2LjQsMjAxNS0wMS0wNyxvdGhlcl9jYW1wYWlnbixQb3J0dWdhbAo0OTYsTERTVUhDUkFZS01PMTc5LExEU1VIQ1JBWUtNTzE3OS1tYXc3cWVyMSwyMDE1LTAxLTEwVDA3OjM1OjU3LjAwMDAwMCswMDAwLDIwMTUtMDEtMTBUMDc6NTU6MzMuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA1NCwyNi40LDIwMTUtMDEtMDcsb3RoZXJfY2FtcGFpZ24sUG9ydHVnYWwKNTAzLE1YQ09WRVlJQUtGSDU5NCxNWENPVkVZSUFLRkg1OTQtdGRrZXVnMmIsMjAxNS0wMS0xMFQwOToyODoyNi4wMDAwMDArMDAwMCwyMDE1LTAxLTEwVDA5OjU4OjUwLjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDg0LDMyLjEsMjAxNS0wMS0xMCxvcmdhbmljLENoaW5hCjUwNSxWTFFIWUpDS0JPSU43MjksVkxRSFlKQ0tCT0lONzI5LTkxdDVka2ZtLDIwMTUtMDEtMTBUMDk6NTM6MDIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMFQwOTo1NjoyNi4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjA4NCwyMy4yLDIwMTUtMDEtMTAsb3JnYW5pYyxKYXBhbgo1MDgsS0JFUVpHRlNSUEhKNDc5LEtCRVFaR0ZTUlBISjQ3OS0xMmdvM3R6NywyMDE1LTAxLTEwVDEwOjMwOjA0LjAwMDAwMCswMDAwLDIwMTUtMDEtMTBUMTA6NDQ6NTIuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAzLDM3LjgsMjAxNS0wMS0wNyxvcmdhbmljLFJ1c3NpYQo1MTYsR0ZMWUpIQVBNWldENjMxLEdGTFlKSEFQTVpXRDYzMS12cHdmajNjYSwyMDE1LTAxLTEwVDEyOjM0OjQ1LjAwMDAwMCswMDAwLDIwMTUtMDEtMTBUMTI6NDg6MzkuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4wMjYsMjEuNCwyMDE1LTAxLTA5LG9yZ2FuaWMsSW5kaWEKNTE3LEdGTFlKSEFQTVpXRDYzMSxHRkxZSkhBUE1aV0Q2MzEtdnB3ZmozY2EsMjAxNS0wMS0xMFQxMjozNDo0NS4wMDAwMDArMDAwMCwyMDE1LTAxLTEwVDEyOjQ5OjUxLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMDQsMjEuNCwyMDE1LTAxLTA5LG9yZ2FuaWMsSW5kaWEKNTE4LEdGTFlKSEFQTVpXRDYzMSxHRkxZSkhBUE1aV0Q2MzEtdnB3ZmozY2EsMjAxNS0wMS0xMFQxMjozNDo0NS4wMDAwMDArMDAwMCwyMDE1LTAxLTEwVDEyOjU1OjUxLjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDE2LDIxLjQsMjAxNS0wMS0wOSxvcmdhbmljLEluZGlhCjUxOSxQWkJOUktTTVVMSFgyMTMsUFpCTlJLU01VTEhYMjEzLXZ0bHkzNWZjLDIwMTUtMDEtMTBUMTQ6MDY6MzYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMFQxNDowOToxOC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDA2LDI2LjMsMjAxNS0wMS0wNyxvcmdhbmljLEluZGlhCjUyMCxQWkJOUktTTVVMSFgyMTMsUFpCTlJLU01VTEhYMjEzLXZ0bHkzNWZjLDIwMTUtMDEtMTBUMTQ6MDY6MzYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMFQxNDoxNDoxOC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDE2LDI2LjMsMjAxNS0wMS0wNyxvcmdhbmljLEluZGlhCjUyMyxQWkJOUktTTVVMSFgyMTMsUFpCTlJLU01VTEhYMjEzLXZ0bHkzNWZjLDIwMTUtMDEtMTBUMTQ6MDY6MzYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMFQxNDoyNTowMC4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjA0NCwyNi4zLDIwMTUtMDEtMDcsb3JnYW5pYyxJbmRpYQo1MjQsUFpCTlJLU01VTEhYMjEzLFBaQk5SS1NNVUxIWDIxMy12dGx5MzVmYywyMDE1LTAxLTEwVDE0OjA2OjM2LjAwMDAwMCswMDAwLDIwMTUtMDEtMTBUMTQ6MzE6NTQuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAwNiwyNi4zLDIwMTUtMDEtMDcsb3JnYW5pYyxJbmRpYQo1MjYsRVFVRE5HWklDTUFLNDgyLEVRVUROR1pJQ01BSzQ4Mi1pNWtyZzluZiwyMDE1LTAxLTEwVDE0OjEyOjA5LjAwMDAwMCswMDAwLDIwMTUtMDEtMTBUMTQ6MjA6MDkuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAzLDEwLjYsMjAxNS0wMS0wNCxnb29nbGUsR2VybWFueQo1MjcsSllFQkNMTlVaVFhRNDU3LEpZRUJDTE5VWlRYUTQ1Ny1mZ3Btcnd4biwyMDE1LTAxLTEwVDE1OjA1OjIwLjAwMDAwMCswMDAwLDIwMTUtMDEtMTBUMTU6MTI6MzIuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyLDI1LjMsMjAxNS0wMS0wNCxvdGhlcl9jYW1wYWlnbixFZ3lwdAo1MjgsSllFQkNMTlVaVFhRNDU3LEpZRUJDTE5VWlRYUTQ1Ny1mZ3Btcnd4biwyMDE1LTAxLTEwVDE1OjA1OjIwLjAwMDAwMCswMDAwLDIwMTUtMDEtMTBUMTU6MjE6NDQuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAzNSwyNS4zLDIwMTUtMDEtMDQsb3RoZXJfY2FtcGFpZ24sRWd5cHQKNTI5LEpZRUJDTE5VWlRYUTQ1NyxKWUVCQ0xOVVpUWFE0NTctZmdwbXJ3eG4sMjAxNS0wMS0xMFQxNTowNToyMC4wMDAwMDArMDAwMCwyMDE1LTAxLTEwVDE1OjI0OjIwLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMiwyNS4zLDIwMTUtMDEtMDQsb3RoZXJfY2FtcGFpZ24sRWd5cHQKNTM1LE9NQ1ZVQUlLU0RUUjY1MSxPTUNWVUFJS1NEVFI2NTEtYzlubTJidGwsMjAxNS0wMS0xMFQxNToyOTowMi4wMDAwMDArMDAwMCwyMDE1LTAxLTEwVDE1OjU4OjIwLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4xLDM0LjEsMjAxNS0wMS0wNyxvdGhlcl9jYW1wYWlnbixVbml0ZWQgU3RhdGVzCjUzNixPTUNWVUFJS1NEVFI2NTEsT01DVlVBSUtTRFRSNjUxLWM5bm0yYnRsLDIwMTUtMDEtMTBUMTU6Mjk6MDIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMFQxNjowMjoyNi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDQsMzQuMSwyMDE1LTAxLTA3LG90aGVyX2NhbXBhaWduLFVuaXRlZCBTdGF0ZXMKNTQyLFFKR1ZPQkxBVElIVzQ1NyxRSkdWT0JMQVRJSFc0NTctbjN4bGFic3osMjAxNS0wMS0xMFQxNTo0OTo1NC4wMDAwMDArMDAwMCwyMDE1LTAxLTEwVDE1OjU1OjM2LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wOTksMjQuOSwyMDE1LTAxLTAyLG90aGVyX2NhbXBhaWduLFN3ZWRlbgo1NDMsUUpHVk9CTEFUSUhXNDU3LFFKR1ZPQkxBVElIVzQ1Ny1uM3hsYWJzeiwyMDE1LTAxLTEwVDE1OjQ5OjU0LjAwMDAwMCswMDAwLDIwMTUtMDEtMTBUMTY6MDU6MjQuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA0NCwyNC45LDIwMTUtMDEtMDIsb3RoZXJfY2FtcGFpZ24sU3dlZGVuCjU0NCxRSkdWT0JMQVRJSFc0NTcsUUpHVk9CTEFUSUhXNDU3LW4zeGxhYnN6LDIwMTUtMDEtMTBUMTU6NDk6NTQuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMFQxNjowOTo0OC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDMzLDI0LjksMjAxNS0wMS0wMixvdGhlcl9jYW1wYWlnbixTd2VkZW4KNTQ1LFFKR1ZPQkxBVElIVzQ1NyxRSkdWT0JMQVRJSFc0NTctbjN4bGFic3osMjAxNS0wMS0xMFQxNTo0OTo1NC4wMDAwMDArMDAwMCwyMDE1LTAxLTEwVDE2OjEzOjEyLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNDQsMjQuOSwyMDE1LTAxLTAyLG90aGVyX2NhbXBhaWduLFN3ZWRlbgo1NDgsWlBUSUhOU1ZGWUFRMTQ2LFpQVElITlNWRllBUTE0Ni1vNDg1enJlYSwyMDE1LTAxLTEwVDE2OjA4OjM0LjAwMDAwMCswMDAwLDIwMTUtMDEtMTBUMTY6MTk6NDYuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA1NCwxNy41LDIwMTUtMDEtMDQsZmFjZWJvb2ssTWV4aWNvCjU1NCxKVkJaQ1BLWEhGTVU0OTEsSlZCWkNQS1hIRk1VNDkxLW45d3MydGwxLDIwMTUtMDEtMTBUMTg6NDg6MDYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMFQxOTowNToxOC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDUsMzQuMSwyMDE1LTAxLTA3LG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwo1NTUsSUNCQVVaS0dTUVBGMTQ1LElDQkFVWktHU1FQRjE0NS1lZ3h0aThkcCwyMDE1LTAxLTEwVDE4OjQ5OjM3LjAwMDAwMCswMDAwLDIwMTUtMDEtMTBUMTg6NTM6NTUuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA0OSwzNy4wLDIwMTUtMDEtMDYsZ29vZ2xlLFNvdXRoIEFmcmljYQo1NTYsSUNCQVVaS0dTUVBGMTQ1LElDQkFVWktHU1FQRjE0NS1lZ3h0aThkcCwyMDE1LTAxLTEwVDE4OjQ5OjM3LjAwMDAwMCswMDAwLDIwMTUtMDEtMTBUMTk6MTI6NTUuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA4NDksMzcuMCwyMDE1LTAxLTA2LGdvb2dsZSxTb3V0aCBBZnJpY2EKNTU4LElDQkFVWktHU1FQRjE0NSxJQ0JBVVpLR1NRUEYxNDUtZWd4dGk4ZHAsMjAxNS0wMS0xMFQxODo0OTozNy4wMDAwMDArMDAwMCwyMDE1LTAxLTEwVDE5OjIwOjI1LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNzksMzcuMCwyMDE1LTAxLTA2LGdvb2dsZSxTb3V0aCBBZnJpY2EKNTYwLFFOTFZSREVPWEZZSjg5MixRTkxWUkRFT1hGWUo4OTItNnVjN3RoMjUsMjAxNS0wMS0xMFQxOTo0MjoyOC4wMDAwMDArMDAwMCwyMDE1LTAxLTEwVDE5OjU1OjI4LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMiwyNS4xLDIwMTUtMDEtMDksY3Jvc3Nwcm9tbyxBdXN0cmFsaWEKNTY0LFFOTFZSREVPWEZZSjg5MixRTkxWUkRFT1hGWUo4OTItNnVjN3RoMjUsMjAxNS0wMS0xMFQxOTo0MjoyOC4wMDAwMDArMDAwMCwyMDE1LTAxLTEwVDIwOjA0OjU4LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wOSwyNS4xLDIwMTUtMDEtMDksY3Jvc3Nwcm9tbyxBdXN0cmFsaWEKNTY1LFBaQk5SS1NNVUxIWDIxMyxQWkJOUktTTVVMSFgyMTMteTcyMWZ1dGEsMjAxNS0wMS0xMFQxOTo1NDoxMS4wMDAwMDArMDAwMCwyMDE1LTAxLTEwVDIwOjEyOjI5LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMDQsMzkuOCwyMDE1LTAxLTA3LG9yZ2FuaWMsSW5kaWEKNTY2LFBaQk5SS1NNVUxIWDIxMyxQWkJOUktTTVVMSFgyMTMteTcyMWZ1dGEsMjAxNS0wMS0xMFQxOTo1NDoxMS4wMDAwMDArMDAwMCwyMDE1LTAxLTEwVDIwOjI3OjI5LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMiwzOS44LDIwMTUtMDEtMDcsb3JnYW5pYyxJbmRpYQo1NzEsQkZOTFVSSVNKWFRINjQ3LEJGTkxVUklTSlhUSDY0Ny0zYmNtdGVwZywyMDE1LTAxLTEwVDIxOjAwOjMxLjAwMDAwMCswMDAwLDIwMTUtMDEtMTBUMjE6MTE6MDcuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyLDM0LjAsMjAxNS0wMS0xMCxvcmdhbmljLEluZGlhCjU3MixCRk5MVVJJU0pYVEg2NDcsQkZOTFVSSVNKWFRINjQ3LTNiY210ZXBnLDIwMTUtMDEtMTBUMjE6MDA6MzEuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMFQyMToxNjo0My4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDA0LDM0LjAsMjAxNS0wMS0xMCxvcmdhbmljLEluZGlhCjU3MyxCRk5MVVJJU0pYVEg2NDcsQkZOTFVSSVNKWFRINjQ3LTNiY210ZXBnLDIwMTUtMDEtMTBUMjE6MDA6MzEuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMFQyMToxODo0My4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDA0LDM0LjAsMjAxNS0wMS0xMCxvcmdhbmljLEluZGlhCjU3NCxCRk5MVVJJU0pYVEg2NDcsQkZOTFVSSVNKWFRINjQ3LTNiY210ZXBnLDIwMTUtMDEtMTBUMjE6MDA6MzEuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMFQyMToyMTo0OS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDE0LDM0LjAsMjAxNS0wMS0xMCxvcmdhbmljLEluZGlhCjU4MCxSTU9TV0hKR0VMQ0k2NzUsUk1PU1dISkdFTENJNjc1LWQ3c2JndTlhLDIwMTUtMDEtMTBUMjM6MjQ6MjAuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMFQyMzozODowMi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDIsMjQuMCwyMDE1LTAxLTEwLG90aGVyX2NhbXBhaWduLEZyYW5jZQo1ODIsTkFPSlJETUNTRUJJMjgxLE5BT0pSRE1DU0VCSTI4MS1kemU3a3NwdSwyMDE1LTAxLTExVDAwOjI0OjM1LjAwMDAwMCswMDAwLDIwMTUtMDEtMTFUMDA6MzA6MjkuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA4MSwzMC45LDIwMTUtMDEtMTEsb3JnYW5pYyxOb3J3YXkKNTg0LE5BT0pSRE1DU0VCSTI4MSxOQU9KUkRNQ1NFQkkyODEtZHplN2tzcHUsMjAxNS0wMS0xMVQwMDoyNDozNS4wMDAwMDArMDAwMCwyMDE1LTAxLTExVDAwOjQ2OjU5LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNDUsMzAuOSwyMDE1LTAxLTExLG9yZ2FuaWMsTm9yd2F5CjU5NSxHU1FKWElPS1lNRUE3MTIsR1NRSlhJT0tZTUVBNzEyLWk1N3Y0ZmJ4LDIwMTUtMDEtMTFUMDM6MDg6NDYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMVQwMzoxNzoyMi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDgsMTAuOCwyMDE1LTAxLTA3LGdvb2dsZSxHZXJtYW55CjYwMSxHU1FKWElPS1lNRUE3MTIsR1NRSlhJT0tZTUVBNzEyLWx5a2FzeG83LDIwMTUtMDEtMTFUMDU6MTY6NDYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMVQwNToxNzozNC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDUsMjAuMSwyMDE1LTAxLTA3LGdvb2dsZSxHZXJtYW55CjYwNyxDSEtVUkFCVEZaREUzNzIsQ0hLVVJBQlRGWkRFMzcyLXo5eWJoam9xLDIwMTUtMDEtMTFUMDU6NDc6NDMuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMVQwNjowNTo0OS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDg4LDI1LjAsMjAxNS0wMS0xMSxvcmdhbmljLERlbm1hcmsKNjA4LENIS1VSQUJURlpERTM3MixDSEtVUkFCVEZaREUzNzItejl5Ymhqb3EsMjAxNS0wMS0xMVQwNTo0Nzo0My4wMDAwMDArMDAwMCwyMDE1LTAxLTExVDA2OjA4OjMxLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wODgsMjUuMCwyMDE1LTAxLTExLG9yZ2FuaWMsRGVubWFyawo2MTEsUk1PU1dISkdFTENJNjc1LFJNT1NXSEpHRUxDSTY3NS04dWx3ZGt2dCwyMDE1LTAxLTExVDA2OjE1OjM2LjAwMDAwMCswMDAwLDIwMTUtMDEtMTFUMDY6MTU6NTQuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyLDkuNCwyMDE1LTAxLTEwLG90aGVyX2NhbXBhaWduLEZyYW5jZQo2MTcsSUNCQVVaS0dTUVBGMTQ1LElDQkFVWktHU1FQRjE0NS1iaDFhbmx5NSwyMDE1LTAxLTExVDA2OjQ1OjI0LjAwMDAwMCswMDAwLDIwMTUtMDEtMTFUMDc6MDU6MjQuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA0MSwyOS4zLDIwMTUtMDEtMDYsZ29vZ2xlLFNvdXRoIEFmcmljYQo2MTgsSlZCWkNQS1hIRk1VNDkxLEpWQlpDUEtYSEZNVTQ5MS0xdGFlZzZpeSwyMDE1LTAxLTExVDA3OjA5OjM0LjAwMDAwMCswMDAwLDIwMTUtMDEtMTFUMDc6MTQ6MjIuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyLDcuOSwyMDE1LTAxLTA3LG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwo2MjMsS0daQ09KSFBGVFFWNzUzLEtHWkNPSkhQRlRRVjc1My1mZTRiZDN4bSwyMDE1LTAxLTExVDA3OjQ0OjI3LjAwMDAwMCswMDAwLDIwMTUtMDEtMTFUMDc6NDU6MjcuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjEsMjIuNiwyMDE1LTAxLTExLG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwo2MjUsT01DVlVBSUtTRFRSNjUxLE9NQ1ZVQUlLU0RUUjY1MS15eDVqbzR2NywyMDE1LTAxLTExVDA5OjA0OjUyLjAwMDAwMCswMDAwLDIwMTUtMDEtMTFUMDk6MDc6NDAuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA2LDM4LjUsMjAxNS0wMS0wNyxvdGhlcl9jYW1wYWlnbixVbml0ZWQgU3RhdGVzCjYyOSxPTUNWVUFJS1NEVFI2NTEsT01DVlVBSUtTRFRSNjUxLXl4NWpvNHY3LDIwMTUtMDEtMTFUMDk6MDQ6NTIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMVQwOTozMjo0Ni4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDksMzguNSwyMDE1LTAxLTA3LG90aGVyX2NhbXBhaWduLFVuaXRlZCBTdGF0ZXMKNjM0LEFVV0ZEUlpNWFZKSDkyOCxBVVdGRFJaTVhWSkg5MjgtNG42Z3h2ZW8sMjAxNS0wMS0xMVQxMDoxNzoyMi4wMDAwMDArMDAwMCwyMDE1LTAxLTExVDEwOjE4OjU4LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMiwxMy42LDIwMTUtMDEtMTEsZ29vZ2xlLEluZGlhCjYzNixRTkxWUkRFT1hGWUo4OTIsUU5MVlJERU9YRllKODkyLTQ1Y3Z0YXgzLDIwMTUtMDEtMTFUMTA6NTI6MDYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMVQxMDo1OTo1NC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMSwyMS4yLDIwMTUtMDEtMDksY3Jvc3Nwcm9tbyxBdXN0cmFsaWEKNjM4LFFOTFZSREVPWEZZSjg5MixRTkxWUkRFT1hGWUo4OTItNDVjdnRheDMsMjAxNS0wMS0xMVQxMDo1MjowNi4wMDAwMDArMDAwMCwyMDE1LTAxLTExVDExOjA5OjQyLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNywyMS4yLDIwMTUtMDEtMDksY3Jvc3Nwcm9tbyxBdXN0cmFsaWEKNjM5LEJGTkxVUklTSlhUSDY0NyxCRk5MVVJJU0pYVEg2NDctZnVjcTFlbTgsMjAxNS0wMS0xMVQxMTowMjowOS4wMDAwMDArMDAwMCwyMDE1LTAxLTExVDExOjE0OjM5LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMiw0MC43LDIwMTUtMDEtMTAsb3JnYW5pYyxJbmRpYQo2NDAsQkZOTFVSSVNKWFRINjQ3LEJGTkxVUklTSlhUSDY0Ny1mdWNxMWVtOCwyMDE1LTAxLTExVDExOjAyOjA5LjAwMDAwMCswMDAwLDIwMTUtMDEtMTFUMTE6MTg6MDkuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4wNDYsNDAuNywyMDE1LTAxLTEwLG9yZ2FuaWMsSW5kaWEKNjQyLEJGTkxVUklTSlhUSDY0NyxCRk5MVVJJU0pYVEg2NDctZnVjcTFlbTgsMjAxNS0wMS0xMVQxMTowMjowOS4wMDAwMDArMDAwMCwyMDE1LTAxLTExVDExOjM0OjUxLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMDgsNDAuNywyMDE1LTAxLTEwLG9yZ2FuaWMsSW5kaWEKNjQzLFFOTFZSREVPWEZZSjg5MixRTkxWUkRFT1hGWUo4OTItaTJrZ3hqNW0sMjAxNS0wMS0xMVQxMjoxMzo0My4wMDAwMDArMDAwMCwyMDE1LTAxLTExVDEyOjI3OjEzLjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDgsMzguOCwyMDE1LTAxLTA5LGNyb3NzcHJvbW8sQXVzdHJhbGlhCjY0NixNWENPVkVZSUFLRkg1OTQsTVhDT1ZFWUlBS0ZINTk0LW16ODV2bmM2LDIwMTUtMDEtMTFUMTQ6MTA6NDMuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMVQxNDoxNTo0My4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDU0LDI2LjgsMjAxNS0wMS0xMCxvcmdhbmljLENoaW5hCjY0OCxNWENPVkVZSUFLRkg1OTQsTVhDT1ZFWUlBS0ZINTk0LW16ODV2bmM2LDIwMTUtMDEtMTFUMTQ6MTA6NDMuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMVQxNDozMjozMS4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjA2LDI2LjgsMjAxNS0wMS0xMCxvcmdhbmljLENoaW5hCjY1NCxRSkdWT0JMQVRJSFc0NTcsUUpHVk9CTEFUSUhXNDU3LTUzbGtmYTZ2LDIwMTUtMDEtMTFUMTQ6MzU6MjIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMVQxNDozNzoxMC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDMzLDIxLjksMjAxNS0wMS0wMixvdGhlcl9jYW1wYWlnbixTd2VkZW4KNjc1LEdGTFlKSEFQTVpXRDYzMSxHRkxZSkhBUE1aV0Q2MzEta3E3dGptb2UsMjAxNS0wMS0xMVQxODoyMzoyMi4wMDAwMDArMDAwMCwyMDE1LTAxLTExVDE4OjI2OjQ2LjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDI2LDEyLjIsMjAxNS0wMS0wOSxvcmdhbmljLEluZGlhCjY3NyxJQ0JBVVpLR1NRUEYxNDUsSUNCQVVaS0dTUVBGMTQ1LXp1bzJqOTU0LDIwMTUtMDEtMTFUMTk6MDQ6MzYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMVQxOToxMjoyNC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDQ5LDguMSwyMDE1LTAxLTA2LGdvb2dsZSxTb3V0aCBBZnJpY2EKNjgwLEZYV0ROS0lVTUpZUjQ3MSxGWFdETktJVU1KWVI0NzEtZXBtY3hoMzUsMjAxNS0wMS0xMVQyMDowMzoyNS4wMDAwMDArMDAwMCwyMDE1LTAxLTExVDIwOjA3OjAxLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wOSwxOS40LDIwMTUtMDEtMTAsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjY4NixSTU9TV0hKR0VMQ0k2NzUsUk1PU1dISkdFTENJNjc1LXVxZzRvN2V2LDIwMTUtMDEtMTFUMjE6Mzc6MjcuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMVQyMTozOToyMS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDksOC4yLDIwMTUtMDEtMTAsb3RoZXJfY2FtcGFpZ24sRnJhbmNlCjY4OSxQWkJOUktTTVVMSFgyMTMsUFpCTlJLU01VTEhYMjEzLW44ZWw2cHV3LDIwMTUtMDEtMTFUMjI6MDg6MjQuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMVQyMjoyNDozMC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDA0LDI4LjYsMjAxNS0wMS0wNyxvcmdhbmljLEluZGlhCjY5MCxQWkJOUktTTVVMSFgyMTMsUFpCTlJLU01VTEhYMjEzLW44ZWw2cHV3LDIwMTUtMDEtMTFUMjI6MDg6MjQuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMVQyMjoyODowMC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDE2LDI4LjYsMjAxNS0wMS0wNyxvcmdhbmljLEluZGlhCjY5MSxQWkJOUktTTVVMSFgyMTMsUFpCTlJLU01VTEhYMjEzLW44ZWw2cHV3LDIwMTUtMDEtMTFUMjI6MDg6MjQuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMVQyMjozMjo1NC4wMDAwMDArMDAwMCxhZCxhZF8xNXNlYywwLjA0NiwyOC42LDIwMTUtMDEtMDcsb3JnYW5pYyxJbmRpYQo2OTIsUFpCTlJLU01VTEhYMjEzLFBaQk5SS1NNVUxIWDIxMy1uOGVsNnB1dywyMDE1LTAxLTExVDIyOjA4OjI0LjAwMDAwMCswMDAwLDIwMTUtMDEtMTFUMjI6MzU6NTQuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyNCwyOC42LDIwMTUtMDEtMDcsb3JnYW5pYyxJbmRpYQo2OTQsS0lMV1pZSFJTSkVHMzE2LEtJTFdaWUhSU0pFRzMxNi1oOXQ3ZjV2MiwyMDE1LTAxLTExVDIyOjIwOjQ2LjAwMDAwMCswMDAwLDIwMTUtMDEtMTFUMjI6MzQ6NDAuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA5OSwyOS4yLDIwMTUtMDEtMDQsb3JnYW5pYyxEZW5tYXJrCjY5NyxFUVVETkdaSUNNQUs0ODIsRVFVRE5HWklDTUFLNDgyLWh4ajF3NjRiLDIwMTUtMDEtMTFUMjI6NTg6MTcuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMVQyMzoxMjoyMy4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjA3LDE5LjQsMjAxNS0wMS0wNCxnb29nbGUsR2VybWFueQo2OTgsR0ZMWUpIQVBNWldENjMxLEdGTFlKSEFQTVpXRDYzMS1wZDZqczE1bSwyMDE1LTAxLTExVDIzOjI4OjA5LjAwMDAwMCswMDAwLDIwMTUtMDEtMTFUMjM6MzE6NTEuMDAwMDAwKzAwMDAsYWQsYWRfMTVzZWMsMC4wNDIsOS4wLDIwMTUtMDEtMDksb3JnYW5pYyxJbmRpYQo3MDEsR1NRSlhJT0tZTUVBNzEyLEdTUUpYSU9LWU1FQTcxMi0ycXhudHN3YywyMDE1LTAxLTEyVDAwOjI1OjEzLjAwMDAwMCswMDAwLDIwMTUtMDEtMTJUMDA6NDY6NTUuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA1LDMzLjMsMjAxNS0wMS0wNyxnb29nbGUsR2VybWFueQo3MDksSlZCWkNQS1hIRk1VNDkxLEpWQlpDUEtYSEZNVTQ5MS10ZnI5bTJsdiwyMDE1LTAxLTEyVDAzOjI5OjMxLjAwMDAwMCswMDAwLDIwMTUtMDEtMTJUMDM6Mzk6MDcuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA0LDI0LjQsMjAxNS0wMS0wNyxvcmdhbmljLFVuaXRlZCBTdGF0ZXMKNzEwLEpWQlpDUEtYSEZNVTQ5MSxKVkJaQ1BLWEhGTVU0OTEtdGZyOW0ybHYsMjAxNS0wMS0xMlQwMzoyOTozMS4wMDAwMDArMDAwMCwyMDE1LTAxLTEyVDAzOjQxOjA3LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNSwyNC40LDIwMTUtMDEtMDcsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjcxMSxBVVdGRFJaTVhWSkg5MjgsQVVXRkRSWk1YVkpIOTI4LW14cmI4bGQzLDIwMTUtMDEtMTJUMDQ6MzA6MTIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMlQwNDozMTo0OC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDEyLDE5LjQsMjAxNS0wMS0xMSxnb29nbGUsSW5kaWEKNzEzLEFVV0ZEUlpNWFZKSDkyOCxBVVdGRFJaTVhWSkg5MjgtbXhyYjhsZDMsMjAxNS0wMS0xMlQwNDozMDoxMi4wMDAwMDArMDAwMCwyMDE1LTAxLTEyVDA0OjQ0OjAwLjAwMDAwMCswMDAwLGFkLGFkXzE1c2VjLDAuMDY0LDE5LjQsMjAxNS0wMS0xMSxnb29nbGUsSW5kaWEKNzE2LElDQkFVWktHU1FQRjE0NSxJQ0JBVVpLR1NRUEYxNDUtOHlzZ2p2bTYsMjAxNS0wMS0xMlQwNToyMDowMS4wMDAwMDArMDAwMCwyMDE1LTAxLTEyVDA1OjMzOjU1LjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDgsMTcuNCwyMDE1LTAxLTA2LGdvb2dsZSxTb3V0aCBBZnJpY2EKNzE5LE1YQ09WRVlJQUtGSDU5NCxNWENPVkVZSUFLRkg1OTQtb25jbDN1cDEsMjAxNS0wMS0xMlQwNTo0MjozNy4wMDAwMDArMDAwMCwyMDE1LTAxLTEyVDA1OjQyOjQzLjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDksMjMuNSwyMDE1LTAxLTEwLG9yZ2FuaWMsQ2hpbmEKNzI1LE9NQ1ZVQUlLU0RUUjY1MSxPTUNWVUFJS1NEVFI2NTEtcnR1MXdwbWUsMjAxNS0wMS0xMlQwNjowMzo0Mi4wMDAwMDArMDAwMCwyMDE1LTAxLTEyVDA2OjMwOjAwLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNywyOS41LDIwMTUtMDEtMDcsb3RoZXJfY2FtcGFpZ24sVW5pdGVkIFN0YXRlcwo3MjcsSUNCQVVaS0dTUVBGMTQ1LElDQkFVWktHU1FQRjE0NS1rdnVoM2N6cywyMDE1LTAxLTEyVDA4OjA0OjM2LjAwMDAwMCswMDAwLDIwMTUtMDEtMTJUMDg6MTI6MTguMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA4NDksMTMuOSwyMDE1LTAxLTA2LGdvb2dsZSxTb3V0aCBBZnJpY2EKNzI5LE1YQ09WRVlJQUtGSDU5NCxNWENPVkVZSUFLRkg1OTQtcHphNmllY24sMjAxNS0wMS0xMlQwODoxNjowMi4wMDAwMDArMDAwMCwyMDE1LTAxLTEyVDA4OjE2OjA4LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMzYsMzYuNiwyMDE1LTAxLTEwLG9yZ2FuaWMsQ2hpbmEKNzMwLE1YQ09WRVlJQUtGSDU5NCxNWENPVkVZSUFLRkg1OTQtcHphNmllY24sMjAxNS0wMS0xMlQwODoxNjowMi4wMDAwMDArMDAwMCwyMDE1LTAxLTEyVDA4OjM2OjMyLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNjYsMzYuNiwyMDE1LTAxLTEwLG9yZ2FuaWMsQ2hpbmEKNzMyLE1YQ09WRVlJQUtGSDU5NCxNWENPVkVZSUFLRkg1OTQtcHphNmllY24sMjAxNS0wMS0xMlQwODoxNjowMi4wMDAwMDArMDAwMCwyMDE1LTAxLTEyVDA4OjQyOjA4LjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDU0LDM2LjYsMjAxNS0wMS0xMCxvcmdhbmljLENoaW5hCjczMyxKVkJaQ1BLWEhGTVU0OTEsSlZCWkNQS1hIRk1VNDkxLWV3Mml0NnBsLDIwMTUtMDEtMTJUMDg6MTg6NTkuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMlQwODoyMToxMS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDgsMzAuMSwyMDE1LTAxLTA3LG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwo3MzUsSlZCWkNQS1hIRk1VNDkxLEpWQlpDUEtYSEZNVTQ5MS1ldzJpdDZwbCwyMDE1LTAxLTEyVDA4OjE4OjU5LjAwMDAwMCswMDAwLDIwMTUtMDEtMTJUMDg6MzM6MTcuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA2LDMwLjEsMjAxNS0wMS0wNyxvcmdhbmljLFVuaXRlZCBTdGF0ZXMKNzM3LFBMUUVTQk5HVURLSjE1NCxQTFFFU0JOR1VES0oxNTQtcDUzMml2eTEsMjAxNS0wMS0xMlQwODo0ODowNi4wMDAwMDArMDAwMCwyMDE1LTAxLTEyVDA4OjUzOjA2LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMTIsMzYuMCwyMDE1LTAxLTEyLGZhY2Vib29rLEphcGFuCjczOCxQTFFFU0JOR1VES0oxNTQsUExRRVNCTkdVREtKMTU0LXA1MzJpdnkxLDIwMTUtMDEtMTJUMDg6NDg6MDYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMlQwODo1OTo0OC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDU0LDM2LjAsMjAxNS0wMS0xMixmYWNlYm9vayxKYXBhbgo3MzksUExRRVNCTkdVREtKMTU0LFBMUUVTQk5HVURLSjE1NC1wNTMyaXZ5MSwyMDE1LTAxLTEyVDA4OjQ4OjA2LjAwMDAwMCswMDAwLDIwMTUtMDEtMTJUMDk6MTc6MDAuMDAwMDAwKzAwMDAsYWQsYWRfMTVzZWMsMC4wOTYsMzYuMCwyMDE1LTAxLTEyLGZhY2Vib29rLEphcGFuCjc0MCxQTFFFU0JOR1VES0oxNTQsUExRRVNCTkdVREtKMTU0LXA1MzJpdnkxLDIwMTUtMDEtMTJUMDg6NDg6MDYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMlQwOToxNzoyNC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDMsMzYuMCwyMDE1LTAxLTEyLGZhY2Vib29rLEphcGFuCjc0MixWTFFIWUpDS0JPSU43MjksVkxRSFlKQ0tCT0lONzI5LTV6cnZveG55LDIwMTUtMDEtMTJUMDg6NDk6NDUuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMlQwODo1NDozOS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDM2LDExLjEsMjAxNS0wMS0xMCxvcmdhbmljLEphcGFuCjc0MyxDSEtVUkFCVEZaREUzNzIsQ0hLVVJBQlRGWkRFMzcyLWV1c25oY3Z3LDIwMTUtMDEtMTJUMTA6MDU6MDUuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMlQxMDoxNDoxNy4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDk5LDM2LjksMjAxNS0wMS0xMSxvcmdhbmljLERlbm1hcmsKNzUxLFFEVVpKSUVUQ0FHVzY1NCxRRFVaSklFVENBR1c2NTQteHZxNTR3bzcsMjAxNS0wMS0xMlQxMDo0Njo0NS4wMDAwMDArMDAwMCwyMDE1LTAxLTEyVDEwOjQ3OjAzLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNzIsMTguNSwyMDE1LTAxLTA3LGZhY2Vib29rLFN3aXR6ZXJsYW5kCjc1OCxHU1FKWElPS1lNRUE3MTIsR1NRSlhJT0tZTUVBNzEyLTlpMnJrNmFjLDIwMTUtMDEtMTJUMTM6Mzk6MDAuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMlQxMzo0NTozMC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDUsMTUuMSwyMDE1LTAxLTA3LGdvb2dsZSxHZXJtYW55Cjc1OSxOQU9KUkRNQ1NFQkkyODEsTkFPSlJETUNTRUJJMjgxLTR4aXA4Z3ZuLDIwMTUtMDEtMTJUMTQ6NTU6MTMuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMlQxNTowMTowMS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDI3LDE4LjgsMjAxNS0wMS0xMSxvcmdhbmljLE5vcndheQo3NjgsQVVXRkRSWk1YVkpIOTI4LEFVV0ZEUlpNWFZKSDkyOC13OWZoazNweiwyMDE1LTAxLTEyVDE3OjI3OjQ1LjAwMDAwMCswMDAwLDIwMTUtMDEtMTJUMTc6MzA6MTUuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAwOCwxMS41LDIwMTUtMDEtMTEsZ29vZ2xlLEluZGlhCjc2OSxBVVdGRFJaTVhWSkg5MjgsQVVXRkRSWk1YVkpIOTI4LXc5ZmhrM3B6LDIwMTUtMDEtMTJUMTc6Mjc6NDUuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMlQxNzozMzozOS4wMDAwMDArMDAwMCxhZCxhZF8xNXNlYywwLjA3OCwxMS41LDIwMTUtMDEtMTEsZ29vZ2xlLEluZGlhCjc3NixDSEtVUkFCVEZaREUzNzIsQ0hLVVJBQlRGWkRFMzcyLXF2dXc0OWc2LDIwMTUtMDEtMTJUMTg6MTk6NDkuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMlQxODoyODo0OS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDk5LDE0LjgsMjAxNS0wMS0xMSxvcmdhbmljLERlbm1hcmsKNzgwLE5BT0pSRE1DU0VCSTI4MSxOQU9KUkRNQ1NFQkkyODEtMm03dXcxODksMjAxNS0wMS0xMlQxOTo1MTo0OS4wMDAwMDArMDAwMCwyMDE1LTAxLTEyVDIwOjI2OjA3LjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDk5LDM4LjksMjAxNS0wMS0xMSxvcmdhbmljLE5vcndheQo3ODksVVpRRkhEQkVNWVBWNTk0LFVaUUZIREJFTVlQVjU5NC1rZnNyZWw2ZCwyMDE1LTAxLTEyVDIyOjM4OjE3LjAwMDAwMCswMDAwLDIwMTUtMDEtMTJUMjI6NTY6NDcuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA4NCwyNS41LDIwMTUtMDEtMTAsZ29vZ2xlLFN3aXR6ZXJsYW5kCjc5MyxHQVlJQkxVQ09FREo3MzIsR0FZSUJMVUNPRURKNzMyLW1kOWVweTc4LDIwMTUtMDEtMTJUMjI6NDQ6MDQuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMlQyMzoxMzo1Mi4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjA4LDMxLjEsMjAxNS0wMS0wMyxvcmdhbmljLFVuaXRlZCBTdGF0ZXMKODAxLEZYV0ROS0lVTUpZUjQ3MSxGWFdETktJVU1KWVI0NzEtaWhreWRqbTYsMjAxNS0wMS0xMlQyMzoyOToxMS4wMDAwMDArMDAwMCwyMDE1LTAxLTEzVDAwOjAxOjE3LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMywzNS43LDIwMTUtMDEtMTAsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjgwNyxWTFFIWUpDS0JPSU43MjksVkxRSFlKQ0tCT0lONzI5LXRlMmE3NGxpLDIwMTUtMDEtMTNUMDA6MTc6MDAuMDAwMDAwKzAwMDAsMjAxNS0wMS0xM1QwMDozNjo0OC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDE4LDI1LjQsMjAxNS0wMS0xMCxvcmdhbmljLEphcGFuCjgwOSxKVkJaQ1BLWEhGTVU0OTEsSlZCWkNQS1hIRk1VNDkxLWV3Znp4YWI1LDIwMTUtMDEtMTNUMDA6NDQ6MDEuMDAwMDAwKzAwMDAsMjAxNS0wMS0xM1QwMDo0Nzo1NS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDgsMjUuMiwyMDE1LTAxLTA3LG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwo4MTAsSlZCWkNQS1hIRk1VNDkxLEpWQlpDUEtYSEZNVTQ5MS1ld2Z6eGFiNSwyMDE1LTAxLTEzVDAwOjQ0OjAxLjAwMDAwMCswMDAwLDIwMTUtMDEtMTNUMDA6NTE6MzEuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA1LDI1LjIsMjAxNS0wMS0wNyxvcmdhbmljLFVuaXRlZCBTdGF0ZXMKODExLEpWQlpDUEtYSEZNVTQ5MSxKVkJaQ1BLWEhGTVU0OTEtZXdmenhhYjUsMjAxNS0wMS0xM1QwMDo0NDowMS4wMDAwMDArMDAwMCwyMDE1LTAxLTEzVDAwOjU3OjAxLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNiwyNS4yLDIwMTUtMDEtMDcsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjgxOCxSTU9TV0hKR0VMQ0k2NzUsUk1PU1dISkdFTENJNjc1LTdxenNyeGhhLDIwMTUtMDEtMTNUMDI6MDY6MDkuMDAwMDAwKzAwMDAsMjAxNS0wMS0xM1QwMjoyNzowOS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDUsMjQuNywyMDE1LTAxLTEwLG90aGVyX2NhbXBhaWduLEZyYW5jZQo4MTksUk1PU1dISkdFTENJNjc1LFJNT1NXSEpHRUxDSTY3NS03cXpzcnhoYSwyMDE1LTAxLTEzVDAyOjA2OjA5LjAwMDAwMCswMDAwLDIwMTUtMDEtMTNUMDI6MzA6MTUuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA2LDI0LjcsMjAxNS0wMS0xMCxvdGhlcl9jYW1wYWlnbixGcmFuY2UKODIwLE9NQ1ZVQUlLU0RUUjY1MSxPTUNWVUFJS1NEVFI2NTEtdm9rcjQ1ODIsMjAxNS0wMS0xM1QwMjoxMTo0Mi4wMDAwMDArMDAwMCwyMDE1LTAxLTEzVDAyOjEyOjI0LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4xLDI2LjMsMjAxNS0wMS0wNyxvdGhlcl9jYW1wYWlnbixVbml0ZWQgU3RhdGVzCjgyNSxPTUNWVUFJS1NEVFI2NTEsT01DVlVBSUtTRFRSNjUxLXZva3I0NTgyLDIwMTUtMDEtMTNUMDI6MTE6NDIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xM1QwMjozMTo1NC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDgsMjYuMywyMDE1LTAxLTA3LG90aGVyX2NhbXBhaWduLFVuaXRlZCBTdGF0ZXMKODI3LE9NQ1ZVQUlLU0RUUjY1MSxPTUNWVUFJS1NEVFI2NTEtdm9rcjQ1ODIsMjAxNS0wMS0xM1QwMjoxMTo0Mi4wMDAwMDArMDAwMCwyMDE1LTAxLTEzVDAyOjM2OjAwLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wOSwyNi4zLDIwMTUtMDEtMDcsb3RoZXJfY2FtcGFpZ24sVW5pdGVkIFN0YXRlcwo4MzAsRlhXRE5LSVVNSllSNDcxLEZYV0ROS0lVTUpZUjQ3MS1wamwzYm5pNSwyMDE1LTAxLTEzVDA0OjEzOjIyLjAwMDAwMCswMDAwLDIwMTUtMDEtMTNUMDQ6MjU6MjIuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAzLDIwLjIsMjAxNS0wMS0xMCxvcmdhbmljLFVuaXRlZCBTdGF0ZXMKODM0LE5BT0pSRE1DU0VCSTI4MSxOQU9KUkRNQ1NFQkkyODEtZWhpMW4yM3YsMjAxNS0wMS0xM1QwNDo1ODoyMC4wMDAwMDArMDAwMCwyMDE1LTAxLTEzVDA1OjA1OjI2LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wODEsMTQuMiwyMDE1LTAxLTExLG9yZ2FuaWMsTm9yd2F5CjgzNSxOQU9KUkRNQ1NFQkkyODEsTkFPSlJETUNTRUJJMjgxLWVoaTFuMjN2LDIwMTUtMDEtMTNUMDQ6NTg6MjAuMDAwMDAwKzAwMDAsMjAxNS0wMS0xM1QwNTowNzowMi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDksMTQuMiwyMDE1LTAxLTExLG9yZ2FuaWMsTm9yd2F5Cjg0NixSTU9TV0hKR0VMQ0k2NzUsUk1PU1dISkdFTENJNjc1LXJ6bzI4andxLDIwMTUtMDEtMTNUMDg6Mjc6MzQuMDAwMDAwKzAwMDAsMjAxNS0wMS0xM1QwODozNzozNC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDQsMjUuNCwyMDE1LTAxLTEwLG90aGVyX2NhbXBhaWduLEZyYW5jZQo4NDcsUk1PU1dISkdFTENJNjc1LFJNT1NXSEpHRUxDSTY3NS1yem8yOGp3cSwyMDE1LTAxLTEzVDA4OjI3OjM0LjAwMDAwMCswMDAwLDIwMTUtMDEtMTNUMDg6Mzc6NDAuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyLDI1LjQsMjAxNS0wMS0xMCxvdGhlcl9jYW1wYWlnbixGcmFuY2UKODQ5LFJNT1NXSEpHRUxDSTY3NSxSTU9TV0hKR0VMQ0k2NzUtcnpvMjhqd3EsMjAxNS0wMS0xM1QwODoyNzozNC4wMDAwMDArMDAwMCwyMDE1LTAxLTEzVDA4OjQ5OjUyLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNSwyNS40LDIwMTUtMDEtMTAsb3RoZXJfY2FtcGFpZ24sRnJhbmNlCjg1MixCRk5MVVJJU0pYVEg2NDcsQkZOTFVSSVNKWFRINjQ3LWh4MjlrdDQ4LDIwMTUtMDEtMTNUMDg6NTk6MjkuMDAwMDAwKzAwMDAsMjAxNS0wMS0xM1QwOTowNzoxMS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDI0LDI0LjQsMjAxNS0wMS0xMCxvcmdhbmljLEluZGlhCjg1MyxCRk5MVVJJU0pYVEg2NDcsQkZOTFVSSVNKWFRINjQ3LWh4MjlrdDQ4LDIwMTUtMDEtMTNUMDg6NTk6MjkuMDAwMDAwKzAwMDAsMjAxNS0wMS0xM1QwOToxNDoxMS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDE4LDI0LjQsMjAxNS0wMS0xMCxvcmdhbmljLEluZGlhCjg1NCxCRk5MVVJJU0pYVEg2NDcsQkZOTFVSSVNKWFRINjQ3LWh4MjlrdDQ4LDIwMTUtMDEtMTNUMDg6NTk6MjkuMDAwMDAwKzAwMDAsMjAxNS0wMS0xM1QwOToxNDoxNy4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDA0LDI0LjQsMjAxNS0wMS0xMCxvcmdhbmljLEluZGlhCjg1OCxHQVlJQkxVQ09FREo3MzIsR0FZSUJMVUNPRURKNzMyLWxiOWtyNWlzLDIwMTUtMDEtMTNUMDk6MzU6MzEuMDAwMDAwKzAwMDAsMjAxNS0wMS0xM1QwOTo1Njo0OS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDksMjQuNSwyMDE1LTAxLTAzLG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwo4NTksQ0hLVVJBQlRGWkRFMzcyLENIS1VSQUJURlpERTM3Mi1hNnYyd29zbCwyMDE1LTAxLTEzVDA5OjUyOjQyLjAwMDAwMCswMDAwLDIwMTUtMDEtMTNUMDk6NTc6NDguMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA2NiwyMi42LDIwMTUtMDEtMTEsb3JnYW5pYyxEZW5tYXJrCjg2MyxVWlFGSERCRU1ZUFY1OTQsVVpRRkhEQkVNWVBWNTk0LXYyOWJwcjRpLDIwMTUtMDEtMTNUMTA6NTU6NDIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xM1QxMTowODowNi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDcyLDEzLjksMjAxNS0wMS0xMCxnb29nbGUsU3dpdHplcmxhbmQKODY0LFFEVVpKSUVUQ0FHVzY1NCxRRFVaSklFVENBR1c2NTQtdDgxMjk0cmosMjAxNS0wMS0xM1QxMToyMTo1MS4wMDAwMDArMDAwMCwyMDE1LTAxLTEzVDExOjQ1OjAzLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMzYsMjQuMCwyMDE1LTAxLTA3LGZhY2Vib29rLFN3aXR6ZXJsYW5kCjg3NSxOQU9KUkRNQ1NFQkkyODEsTkFPSlJETUNTRUJJMjgxLWMxdnVzM2FxLDIwMTUtMDEtMTNUMTQ6MzQ6MjUuMDAwMDAwKzAwMDAsMjAxNS0wMS0xM1QxNTowMTozMS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDU0LDM1LjYsMjAxNS0wMS0xMSxvcmdhbmljLE5vcndheQo4OTQsV0VQS1lOUlhERlVUNTcyLFdFUEtZTlJYREZVVDU3Mi0xd2x0OXppeSwyMDE1LTAxLTEzVDE2OjQxOjE2LjAwMDAwMCswMDAwLDIwMTUtMDEtMTNUMTY6NTI6MzQuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA1NCwyNS42LDIwMTUtMDEtMTMsY3Jvc3Nwcm9tbyxDaGluYQo4OTYsSlVZQkZNUEVSTERXMzk0LEpVWUJGTVBFUkxEVzM5NC02czh2ZmwyeCwyMDE1LTAxLTEzVDE4OjQ1OjQ1LjAwMDAwMCswMDAwLDIwMTUtMDEtMTNUMTg6NTI6NDUuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4wOSwxOS45LDIwMTUtMDEtMTMsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjkwMCxHU1FKWElPS1lNRUE3MTIsR1NRSlhJT0tZTUVBNzEyLTNxODJ2a2c5LDIwMTUtMDEtMTNUMTk6MTY6NTEuMDAwMDAwKzAwMDAsMjAxNS0wMS0xM1QxOTo0NzozMy4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDYsMzQuMCwyMDE1LTAxLTA3LGdvb2dsZSxHZXJtYW55CjkxMSxXRVBLWU5SWERGVVQ1NzIsV0VQS1lOUlhERlVUNTcyLTZtOXdrNzRvLDIwMTUtMDEtMTNUMjI6MjY6NDguMDAwMDAwKzAwMDAsMjAxNS0wMS0xM1QyMjo0NToxOC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDY2LDI2LjQsMjAxNS0wMS0xMyxjcm9zc3Byb21vLENoaW5hCjkxMyxaUFRJSE5TVkZZQVExNDYsWlBUSUhOU1ZGWUFRMTQ2LWpjM2Q3bnJxLDIwMTUtMDEtMTNUMjI6NDM6MDMuMDAwMDAwKzAwMDAsMjAxNS0wMS0xM1QyMjo1Mzo1Ny4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDQ4LDIzLjIsMjAxNS0wMS0wNCxmYWNlYm9vayxNZXhpY28KOTE1LFBaQk5SS1NNVUxIWDIxMyxQWkJOUktTTVVMSFgyMTMtYmx3ZDN4N3EsMjAxNS0wMS0xM1QyMzoyMzoyNy4wMDAwMDArMDAwMCwyMDE1LTAxLTEzVDIzOjMzOjQ1LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMjQsMjQuNiwyMDE1LTAxLTA3LG9yZ2FuaWMsSW5kaWEKOTE3LFBaQk5SS1NNVUxIWDIxMyxQWkJOUktTTVVMSFgyMTMtYmx3ZDN4N3EsMjAxNS0wMS0xM1QyMzoyMzoyNy4wMDAwMDArMDAwMCwyMDE1LTAxLTEzVDIzOjQwOjMzLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMTgsMjQuNiwyMDE1LTAxLTA3LG9yZ2FuaWMsSW5kaWEKOTE4LFBaQk5SS1NNVUxIWDIxMyxQWkJOUktTTVVMSFgyMTMtYmx3ZDN4N3EsMjAxNS0wMS0xM1QyMzoyMzoyNy4wMDAwMDArMDAwMCwyMDE1LTAxLTEzVDIzOjQxOjI3LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMTgsMjQuNiwyMDE1LTAxLTA3LG9yZ2FuaWMsSW5kaWEKOTE5LFdCS0ZZSlhDWk5VSDU2MyxXQktGWUpYQ1pOVUg1NjMtbnpzcHI2dXQsMjAxNS0wMS0xM1QyMzoyODo1OC4wMDAwMDArMDAwMCwyMDE1LTAxLTEzVDIzOjM2OjI4LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNCwzMC43LDIwMTUtMDEtMTMsb3JnYW5pYyxDYW5hZGEKOTIxLFdCS0ZZSlhDWk5VSDU2MyxXQktGWUpYQ1pOVUg1NjMtbnpzcHI2dXQsMjAxNS0wMS0xM1QyMzoyODo1OC4wMDAwMDArMDAwMCwyMDE1LTAxLTEzVDIzOjUwOjM0LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4xLDMwLjcsMjAxNS0wMS0xMyxvcmdhbmljLENhbmFkYQo5MjQsWElBSEJOS0VDR1JPNTk4LFhJQUhCTktFQ0dSTzU5OC1sNXVmOWlwMywyMDE1LTAxLTE0VDAwOjM4OjQxLjAwMDAwMCswMDAwLDIwMTUtMDEtMTRUMDA6NDY6MjMuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyLDIwLjAsMjAxNS0wMS0xNCxnb29nbGUsRWd5cHQKOTI2LFhJQUhCTktFQ0dSTzU5OCxYSUFIQk5LRUNHUk81OTgtbDV1ZjlpcDMsMjAxNS0wMS0xNFQwMDozODo0MS4wMDAwMDArMDAwMCwyMDE1LTAxLTE0VDAwOjU4OjA1LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNTUsMjAuMCwyMDE1LTAxLTE0LGdvb2dsZSxFZ3lwdAo5MzQsTVhDT1ZFWUlBS0ZINTk0LE1YQ09WRVlJQUtGSDU5NC1pNzUyNDlmMywyMDE1LTAxLTE0VDAxOjMwOjIzLjAwMDAwMCswMDAwLDIwMTUtMDEtMTRUMDE6NDg6MTEuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4wNzIsMjEuMywyMDE1LTAxLTEwLG9yZ2FuaWMsQ2hpbmEKOTM1LEpVQkRWRkhDTlFXVDE5OCxKVUJEVkZIQ05RV1QxOTgtNXdrYnNkb2ksMjAxNS0wMS0xNFQwMjoxMDo0MC4wMDAwMDArMDAwMCwyMDE1LTAxLTE0VDAyOjE0OjQwLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMzIsMzcuMywyMDE1LTAxLTE0LG9yZ2FuaWMsUGhpbGlwcGluZXMKOTM2LEpVQkRWRkhDTlFXVDE5OCxKVUJEVkZIQ05RV1QxOTgtNXdrYnNkb2ksMjAxNS0wMS0xNFQwMjoxMDo0MC4wMDAwMDArMDAwMCwyMDE1LTAxLTE0VDAyOjI4OjQwLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMjgsMzcuMywyMDE1LTAxLTE0LG9yZ2FuaWMsUGhpbGlwcGluZXMKOTM3LEpVWUJGTVBFUkxEVzM5NCxKVVlCRk1QRVJMRFczOTQtODdsMnRiaHMsMjAxNS0wMS0xNFQwMjozMDozMC4wMDAwMDArMDAwMCwyMDE1LTAxLTE0VDAyOjM4OjM2LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4xLDE3LjgsMjAxNS0wMS0xMyxvcmdhbmljLFVuaXRlZCBTdGF0ZXMKOTQyLE1UQ0lXS09WQVNZUDkyNSxNVENJV0tPVkFTWVA5MjUtNHpxdWs1ZnIsMjAxNS0wMS0xNFQwMjo0NToyMC4wMDAwMDArMDAwMCwyMDE1LTAxLTE0VDAyOjUzOjI2LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMiwxMS41LDIwMTUtMDEtMTQsb3JnYW5pYyxHZXJtYW55Cjk0OSxaUFRJSE5TVkZZQVExNDYsWlBUSUhOU1ZGWUFRMTQ2LTFiNmloN3ZnLDIwMTUtMDEtMTRUMDI6NDg6NTYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNFQwMzoyMToxNC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDEyLDM0LjksMjAxNS0wMS0wNCxmYWNlYm9vayxNZXhpY28KOTUwLEpZRUJDTE5VWlRYUTQ1NyxKWUVCQ0xOVVpUWFE0NTctYnRvdjZpdzQsMjAxNS0wMS0xNFQwMjo1MzozNy4wMDAwMDArMDAwMCwyMDE1LTAxLTE0VDAyOjU3OjE5LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMzUsOC44LDIwMTUtMDEtMDQsb3RoZXJfY2FtcGFpZ24sRWd5cHQKOTUyLEpWQlpDUEtYSEZNVTQ5MSxKVkJaQ1BLWEhGTVU0OTEtc2F6bnVrZmksMjAxNS0wMS0xNFQwMjo1ODowOS4wMDAwMDArMDAwMCwyMDE1LTAxLTE0VDAzOjA1OjA5LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNSwzNS43LDIwMTUtMDEtMDcsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjk1NSxKVkJaQ1BLWEhGTVU0OTEsSlZCWkNQS1hIRk1VNDkxLXNhem51a2ZpLDIwMTUtMDEtMTRUMDI6NTg6MDkuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNFQwMzoxNToxNS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDgsMzUuNywyMDE1LTAxLTA3LG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwo5NTcsWElBSEJOS0VDR1JPNTk4LFhJQUhCTktFQ0dSTzU5OC1qbGhkbnM4aSwyMDE1LTAxLTE0VDA0OjMyOjE1LjAwMDAwMCswMDAwLDIwMTUtMDEtMTRUMDQ6MzQ6MzMuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAxNSwxNC4xLDIwMTUtMDEtMTQsZ29vZ2xlLEVneXB0Cjk1OCxYSUFIQk5LRUNHUk81OTgsWElBSEJOS0VDR1JPNTk4LWpsaGRuczhpLDIwMTUtMDEtMTRUMDQ6MzI6MTUuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNFQwNDo0NDowMy4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjA1LDE0LjEsMjAxNS0wMS0xNCxnb29nbGUsRWd5cHQKOTYwLEVGTE5QR1RSWlZBQzc2NSxFRkxOUEdUUlpWQUM3NjUtdHM0OW0zcTcsMjAxNS0wMS0xNFQwNDozMzoyOC4wMDAwMDArMDAwMCwyMDE1LTAxLTE0VDA0OjQ3OjQwLjAwMDAwMCswMDAwLGFkLGFkXzE1c2VjLDAuMDU4LDIwLjcsMjAxNS0wMS0xNCxvdGhlcl9jYW1wYWlnbixSdXNzaWEKOTYxLEVGTE5QR1RSWlZBQzc2NSxFRkxOUEdUUlpWQUM3NjUtdHM0OW0zcTcsMjAxNS0wMS0xNFQwNDozMzoyOC4wMDAwMDArMDAwMCwyMDE1LTAxLTE0VDA0OjUxOjE2LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMTUsMjAuNywyMDE1LTAxLTE0LG90aGVyX2NhbXBhaWduLFJ1c3NpYQo5NjIsRUZMTlBHVFJaVkFDNzY1LEVGTE5QR1RSWlZBQzc2NS10czQ5bTNxNywyMDE1LTAxLTE0VDA0OjMzOjI4LjAwMDAwMCswMDAwLDIwMTUtMDEtMTRUMDQ6NTE6NDAuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAxNSwyMC43LDIwMTUtMDEtMTQsb3RoZXJfY2FtcGFpZ24sUnVzc2lhCjk2OSxETFRGVlFXWUlYUko1ODksRExURlZRV1lJWFJKNTg5LXNreXY4MnBlLDIwMTUtMDEtMTRUMDQ6Mzk6NDkuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNFQwNDo1Mzo1NS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDU1OSwzMi43LDIwMTUtMDEtMTMsb3JnYW5pYyxTb3V0aCBBZnJpY2EKOTcwLERMVEZWUVdZSVhSSjU4OSxETFRGVlFXWUlYUko1ODktc2t5djgycGUsMjAxNS0wMS0xNFQwNDozOTo0OS4wMDAwMDArMDAwMCwyMDE1LTAxLTE0VDA0OjU1OjMxLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNDEsMzIuNywyMDE1LTAxLTEzLG9yZ2FuaWMsU291dGggQWZyaWNhCjk3MixLR1pDT0pIUEZUUVY3NTMsS0daQ09KSFBGVFFWNzUzLXJpY3p0OHBkLDIwMTUtMDEtMTRUMDU6MDY6MDIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNFQwNToyNDozMi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDgsMzguMSwyMDE1LTAxLTExLG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwo5NzQsSlZCWkNQS1hIRk1VNDkxLEpWQlpDUEtYSEZNVTQ5MS13MXEybGV1OSwyMDE1LTAxLTE0VDA1OjI4OjQ2LjAwMDAwMCswMDAwLDIwMTUtMDEtMTRUMDU6MzM6NDAuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA1LDUuMSwyMDE1LTAxLTA3LG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwo5NzUsV0JLRllKWENaTlVINTYzLFdCS0ZZSlhDWk5VSDU2My15N3JrYm5naiwyMDE1LTAxLTE0VDA2OjM3OjE1LjAwMDAwMCswMDAwLDIwMTUtMDEtMTRUMDY6Mzc6MjEuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAzLDM5LjAsMjAxNS0wMS0xMyxvcmdhbmljLENhbmFkYQo5ODEsVkxRSFlKQ0tCT0lONzI5LFZMUUhZSkNLQk9JTjcyOS0yN3BvZ21qdiwyMDE1LTAxLTE0VDA3OjA0OjMyLjAwMDAwMCswMDAwLDIwMTUtMDEtMTRUMDc6MDg6NTYuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAzLDkuMywyMDE1LTAxLTEwLG9yZ2FuaWMsSmFwYW4KOTg1LEdKQ1hOVFdFQklQUTM2OSxHSkNYTlRXRUJJUFEzNjktM3VvcGNrbnksMjAxNS0wMS0xNFQwNzo1MjoxMy4wMDAwMDArMDAwMCwyMDE1LTAxLTE0VDA4OjExOjQ5LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNiwzNS45LDIwMTUtMDEtMTQsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjk4NyxKVVlCRk1QRVJMRFczOTQsSlVZQkZNUEVSTERXMzk0LWF6bXE3dzlsLDIwMTUtMDEtMTRUMDg6MjE6MTMuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNFQwODo0NToxMy4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDQsMzAuMSwyMDE1LTAxLTEzLG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwo5ODgsUU5MVlJERU9YRllKODkyLFFOTFZSREVPWEZZSjg5Mi01dTN3bjhwNywyMDE1LTAxLTE0VDA4OjIxOjQyLjAwMDAwMCswMDAwLDIwMTUtMDEtMTRUMDg6Mjg6MTguMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA4LDM0LjYsMjAxNS0wMS0wOSxjcm9zc3Byb21vLEF1c3RyYWxpYQo5OTAsUU5MVlJERU9YRllKODkyLFFOTFZSREVPWEZZSjg5Mi01dTN3bjhwNywyMDE1LTAxLTE0VDA4OjIxOjQyLjAwMDAwMCswMDAwLDIwMTUtMDEtMTRUMDg6MzM6MjQuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA5LDM0LjYsMjAxNS0wMS0wOSxjcm9zc3Byb21vLEF1c3RyYWxpYQo5OTcsSERTQU1QVE9MQldDNDM4LEhEU0FNUFRPTEJXQzQzOC12dDh1Y3BtMywyMDE1LTAxLTE0VDA5OjAyOjMxLjAwMDAwMCswMDAwLDIwMTUtMDEtMTRUMDk6MTY6MTkuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA2LDIwLjcsMjAxNS0wMS0xNCxvcmdhbmljLFN3aXR6ZXJsYW5kCjEwMDUsTVRDSVdLT1ZBU1lQOTI1LE1UQ0lXS09WQVNZUDkyNS04YTZ4ZnFvaywyMDE1LTAxLTE0VDEwOjE4OjMyLjAwMDAwMCswMDAwLDIwMTUtMDEtMTRUMTA6MzE6MjAuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA0LDE2LjMsMjAxNS0wMS0xNCxvcmdhbmljLEdlcm1hbnkKMTAwOSxHQVlJQkxVQ09FREo3MzIsR0FZSUJMVUNPRURKNzMyLTdvY3N0MW16LDIwMTUtMDEtMTRUMTE6NDM6NTEuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNFQxMTo0NzozMy4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjEsMzUuMSwyMDE1LTAxLTAzLG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwoxMDE1LE5NUlVXSEFZSlBCUTgyNCxOTVJVV0hBWUpQQlE4MjQtMTQ1Y3I4N3EsMjAxNS0wMS0xNFQxMjowMjoyMy4wMDAwMDArMDAwMCwyMDE1LTAxLTE0VDEyOjMyOjUzLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wODQ5LDMzLjMsMjAxNS0wMS0wOCxvcmdhbmljLEhvbmcgS29uZwoxMDE2LE5NUlVXSEFZSlBCUTgyNCxOTVJVV0hBWUpQQlE4MjQtMTQ1Y3I4N3EsMjAxNS0wMS0xNFQxMjowMjoyMy4wMDAwMDArMDAwMCwyMDE1LTAxLTE0VDEyOjMzOjI5LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wOCwzMy4zLDIwMTUtMDEtMDgsb3JnYW5pYyxIb25nIEtvbmcKMTAxNyxOQU9KUkRNQ1NFQkkyODEsTkFPSlJETUNTRUJJMjgxLWd3YjlvNmRjLDIwMTUtMDEtMTRUMTI6NDk6NDUuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNFQxMjo1MTo1Ny4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDU0LDE1LjgsMjAxNS0wMS0xMSxvcmdhbmljLE5vcndheQoxMDI0LEdBWUlCTFVDT0VESjczMixHQVlJQkxVQ09FREo3MzItbHBrdXdncjQsMjAxNS0wMS0xNFQxNDo1NTozOC4wMDAwMDArMDAwMCwyMDE1LTAxLTE0VDE1OjEyOjAyLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wOCwyOS42LDIwMTUtMDEtMDMsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjEwMjcsQkZOTFVSSVNKWFRINjQ3LEJGTkxVUklTSlhUSDY0Ny16aTk2Y3BuMSwyMDE1LTAxLTE0VDE0OjU5OjQxLjAwMDAwMCswMDAwLDIwMTUtMDEtMTRUMTU6MTY6NDcuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyNCwyNC44LDIwMTUtMDEtMTAsb3JnYW5pYyxJbmRpYQoxMDMwLEJGTkxVUklTSlhUSDY0NyxCRk5MVVJJU0pYVEg2NDctemk5NmNwbjEsMjAxNS0wMS0xNFQxNDo1OTo0MS4wMDAwMDArMDAwMCwyMDE1LTAxLTE0VDE1OjIyOjE3LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMjIsMjQuOCwyMDE1LTAxLTEwLG9yZ2FuaWMsSW5kaWEKMTAzMSxYSUFIQk5LRUNHUk81OTgsWElBSEJOS0VDR1JPNTk4LXVuMWZiejk1LDIwMTUtMDEtMTRUMTY6MDY6MzcuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNFQxNjowOTo0My4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDUsMjcuMiwyMDE1LTAxLTE0LGdvb2dsZSxFZ3lwdAoxMDMyLFhJQUhCTktFQ0dSTzU5OCxYSUFIQk5LRUNHUk81OTgtdW4xZmJ6OTUsMjAxNS0wMS0xNFQxNjowNjozNy4wMDAwMDArMDAwMCwyMDE1LTAxLTE0VDE2OjE3OjE5LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNDUsMjcuMiwyMDE1LTAxLTE0LGdvb2dsZSxFZ3lwdAoxMDMzLFhJQUhCTktFQ0dSTzU5OCxYSUFIQk5LRUNHUk81OTgtdW4xZmJ6OTUsMjAxNS0wMS0xNFQxNjowNjozNy4wMDAwMDArMDAwMCwyMDE1LTAxLTE0VDE2OjI0OjEzLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNCwyNy4yLDIwMTUtMDEtMTQsZ29vZ2xlLEVneXB0CjEwMzQsWElBSEJOS0VDR1JPNTk4LFhJQUhCTktFQ0dSTzU5OC11bjFmYno5NSwyMDE1LTAxLTE0VDE2OjA2OjM3LjAwMDAwMCswMDAwLDIwMTUtMDEtMTRUMTY6MjY6NDMuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAxLDI3LjIsMjAxNS0wMS0xNCxnb29nbGUsRWd5cHQKMTAzNixYSUFIQk5LRUNHUk81OTgsWElBSEJOS0VDR1JPNTk4LXVuMWZiejk1LDIwMTUtMDEtMTRUMTY6MDY6MzcuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNFQxNjoyODowMS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDIsMjcuMiwyMDE1LTAxLTE0LGdvb2dsZSxFZ3lwdAoxMDM5LE9NQ1ZVQUlLU0RUUjY1MSxPTUNWVUFJS1NEVFI2NTEtYmZsNmRpcmosMjAxNS0wMS0xNFQxNjo0MjoxNC4wMDAwMDArMDAwMCwyMDE1LTAxLTE0VDE2OjQ1OjIwLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMywyNS40LDIwMTUtMDEtMDcsb3RoZXJfY2FtcGFpZ24sVW5pdGVkIFN0YXRlcwoxMDQwLE9NQ1ZVQUlLU0RUUjY1MSxPTUNWVUFJS1NEVFI2NTEtYmZsNmRpcmosMjAxNS0wMS0xNFQxNjo0MjoxNC4wMDAwMDArMDAwMCwyMDE1LTAxLTE0VDE2OjU2OjAyLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNiwyNS40LDIwMTUtMDEtMDcsb3RoZXJfY2FtcGFpZ24sVW5pdGVkIFN0YXRlcwoxMDQ5LFJNT1NXSEpHRUxDSTY3NSxSTU9TV0hKR0VMQ0k2NzUtMWJueGRxenAsMjAxNS0wMS0xNFQxNzoyMjo1My4wMDAwMDArMDAwMCwyMDE1LTAxLTE0VDE3OjQzOjExLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNSwyMC4zLDIwMTUtMDEtMTAsb3RoZXJfY2FtcGFpZ24sRnJhbmNlCjEwNTAsUU5MVlJERU9YRllKODkyLFFOTFZSREVPWEZZSjg5Mi1oM2pvY2xnZiwyMDE1LTAxLTE0VDE4OjIxOjE4LjAwMDAwMCswMDAwLDIwMTUtMDEtMTRUMTg6Mjc6MDAuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA1LDkuNCwyMDE1LTAxLTA5LGNyb3NzcHJvbW8sQXVzdHJhbGlhCjEwNTIsUFpCTlJLU01VTEhYMjEzLFBaQk5SS1NNVUxIWDIxMy1meG9pYmpubCwyMDE1LTAxLTE0VDE4OjMzOjU2LjAwMDAwMCswMDAwLDIwMTUtMDEtMTRUMTg6Mzg6NDQuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAxLDEzLjMsMjAxNS0wMS0wNyxvcmdhbmljLEluZGlhCjEwNTMsUFpCTlJLU01VTEhYMjEzLFBaQk5SS1NNVUxIWDIxMy1meG9pYmpubCwyMDE1LTAxLTE0VDE4OjMzOjU2LjAwMDAwMCswMDAwLDIwMTUtMDEtMTRUMTg6NDU6MjYuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAwNiwxMy4zLDIwMTUtMDEtMDcsb3JnYW5pYyxJbmRpYQoxMDY1LE1YQ09WRVlJQUtGSDU5NCxNWENPVkVZSUFLRkg1OTQtNDI5M3pzdTEsMjAxNS0wMS0xNVQwMDoxOTo0Mi4wMDAwMDArMDAwMCwyMDE1LTAxLTE1VDAwOjI0OjE4LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNDgsMjcuNywyMDE1LTAxLTEwLG9yZ2FuaWMsQ2hpbmEKMTA2OSxHSkNYTlRXRUJJUFEzNjksR0pDWE5UV0VCSVBRMzY5LWs2cW9weWJzLDIwMTUtMDEtMTVUMDA6NTQ6NDAuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNVQwMDo1NToxMC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDIsMTkuMywyMDE1LTAxLTE0LG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwoxMDcyLEdKQ1hOVFdFQklQUTM2OSxHSkNYTlRXRUJJUFEzNjktazZxb3B5YnMsMjAxNS0wMS0xNVQwMDo1NDo0MC4wMDAwMDArMDAwMCwyMDE1LTAxLTE1VDAxOjA0OjA0LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4xLDE5LjMsMjAxNS0wMS0xNCxvcmdhbmljLFVuaXRlZCBTdGF0ZXMKMTA3MyxHSkNYTlRXRUJJUFEzNjksR0pDWE5UV0VCSVBRMzY5LWs2cW9weWJzLDIwMTUtMDEtMTVUMDA6NTQ6NDAuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNVQwMTowNDoyOC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMSwxOS4zLDIwMTUtMDEtMTQsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjEwODEsTVRDSVdLT1ZBU1lQOTI1LE1UQ0lXS09WQVNZUDkyNS05ZTZhc2xoMiwyMDE1LTAxLTE1VDAyOjE1OjExLjAwMDAwMCswMDAwLDIwMTUtMDEtMTVUMDI6MzE6MTcuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAzLDM1LjMsMjAxNS0wMS0xNCxvcmdhbmljLEdlcm1hbnkKMTA4MyxNVENJV0tPVkFTWVA5MjUsTVRDSVdLT1ZBU1lQOTI1LTllNmFzbGgyLDIwMTUtMDEtMTVUMDI6MTU6MTEuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNVQwMjozMjo1OS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDYsMzUuMywyMDE1LTAxLTE0LG9yZ2FuaWMsR2VybWFueQoxMDk3LFdOVkJBWUdDTEpJUjUxNyxXTlZCQVlHQ0xKSVI1MTctZzFkYnI1ZnosMjAxNS0wMS0xNVQwMzoyNTo1OS4wMDAwMDArMDAwMCwyMDE1LTAxLTE1VDAzOjUwOjA1LjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDc3LDI4LjgsMjAxNS0wMS0xMyxmYWNlYm9vayxTd2VkZW4KMTA5OSxaTUpMUEdDUklLTkE0NzEsWk1KTFBHQ1JJS05BNDcxLXNqa2ZtYzR5LDIwMTUtMDEtMTVUMDM6Mzk6MzguMDAwMDAwKzAwMDAsMjAxNS0wMS0xNVQwMzo0MzoyNi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDYsMTcuNSwyMDE1LTAxLTEwLG9yZ2FuaWMsRWd5cHQKMTEwMCxaTUpMUEdDUklLTkE0NzEsWk1KTFBHQ1JJS05BNDcxLXNqa2ZtYzR5LDIwMTUtMDEtMTVUMDM6Mzk6MzguMDAwMDAwKzAwMDAsMjAxNS0wMS0xNVQwMzo0NTo1MC4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjA0NSwxNy41LDIwMTUtMDEtMTAsb3JnYW5pYyxFZ3lwdAoxMTAxLFpNSkxQR0NSSUtOQTQ3MSxaTUpMUEdDUklLTkE0NzEtc2prZm1jNHksMjAxNS0wMS0xNVQwMzozOTozOC4wMDAwMDArMDAwMCwyMDE1LTAxLTE1VDAzOjUyOjE0LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMSwxNy41LDIwMTUtMDEtMTAsb3JnYW5pYyxFZ3lwdAoxMTA2LEJGTkxVUklTSlhUSDY0NyxCRk5MVVJJU0pYVEg2NDctZ3N2amI3d2UsMjAxNS0wMS0xNVQwNTowMTo1MC4wMDAwMDArMDAwMCwyMDE1LTAxLTE1VDA1OjA4OjQ0LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMjIsMTMuNSwyMDE1LTAxLTEwLG9yZ2FuaWMsSW5kaWEKMTEwNyxLR1pDT0pIUEZUUVY3NTMsS0daQ09KSFBGVFFWNzUzLXo1NHhvbHdmLDIwMTUtMDEtMTVUMDU6MTU6MzMuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNVQwNToxNzo0NS4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjEsMjEuOCwyMDE1LTAxLTExLG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwoxMTA4LEtHWkNPSkhQRlRRVjc1MyxLR1pDT0pIUEZUUVY3NTMtejU0eG9sd2YsMjAxNS0wMS0xNVQwNToxNTozMy4wMDAwMDArMDAwMCwyMDE1LTAxLTE1VDA1OjI2OjA5LjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDksMjEuOCwyMDE1LTAxLTExLG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwoxMTEwLERMVEZWUVdZSVhSSjU4OSxETFRGVlFXWUlYUko1ODktbm9oZmFlMzcsMjAxNS0wMS0xNVQwNToxNjowNC4wMDAwMDArMDAwMCwyMDE1LTAxLTE1VDA1OjIyOjQ2LjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDk4LDEzLjAsMjAxNS0wMS0xMyxvcmdhbmljLFNvdXRoIEFmcmljYQoxMTExLERMVEZWUVdZSVhSSjU4OSxETFRGVlFXWUlYUko1ODktbm9oZmFlMzcsMjAxNS0wMS0xNVQwNToxNjowNC4wMDAwMDArMDAwMCwyMDE1LTAxLTE1VDA1OjI1OjM0LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNDEsMTMuMCwyMDE1LTAxLTEzLG9yZ2FuaWMsU291dGggQWZyaWNhCjExMjIsUU5MVlJERU9YRllKODkyLFFOTFZSREVPWEZZSjg5Mi05bGt0M3JvOCwyMDE1LTAxLTE1VDA2OjQ1OjM0LjAwMDAwMCswMDAwLDIwMTUtMDEtMTVUMDY6NTQ6MzQuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA5LDM1LjksMjAxNS0wMS0wOSxjcm9zc3Byb21vLEF1c3RyYWxpYQoxMTI3LFFEVVpKSUVUQ0FHVzY1NCxRRFVaSklFVENBR1c2NTQteWR3cmx2NnEsMjAxNS0wMS0xNVQwNjo0Njo1MS4wMDAwMDArMDAwMCwyMDE1LTAxLTE1VDA3OjIzOjM5LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wODQsMzguNiwyMDE1LTAxLTA3LGZhY2Vib29rLFN3aXR6ZXJsYW5kCjExMzAsVkxRSFlKQ0tCT0lONzI5LFZMUUhZSkNLQk9JTjcyOS02c2Z5d3Y3bSwyMDE1LTAxLTE1VDA4OjE4OjIwLjAwMDAwMCswMDAwLDIwMTUtMDEtMTVUMDg6MjE6MDIuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAxMiwzNC4wLDIwMTUtMDEtMTAsb3JnYW5pYyxKYXBhbgoxMTM1LFhJQUhCTktFQ0dSTzU5OCxYSUFIQk5LRUNHUk81OTgtbnE3dWVyd3osMjAxNS0wMS0xNVQwOTo1NzozMS4wMDAwMDArMDAwMCwyMDE1LTAxLTE1VDEwOjAwOjQzLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMiwzMC41LDIwMTUtMDEtMTQsZ29vZ2xlLEVneXB0CjExMzYsWElBSEJOS0VDR1JPNTk4LFhJQUhCTktFQ0dSTzU5OC1ucTd1ZXJ3eiwyMDE1LTAxLTE1VDA5OjU3OjMxLjAwMDAwMCswMDAwLDIwMTUtMDEtMTVUMTA6MDE6MTkuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAzNSwzMC41LDIwMTUtMDEtMTQsZ29vZ2xlLEVneXB0CjExMzcsWElBSEJOS0VDR1JPNTk4LFhJQUhCTktFQ0dSTzU5OC1ucTd1ZXJ3eiwyMDE1LTAxLTE1VDA5OjU3OjMxLjAwMDAwMCswMDAwLDIwMTUtMDEtMTVUMTA6MDM6MDEuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4wNiwzMC41LDIwMTUtMDEtMTQsZ29vZ2xlLEVneXB0CjExMzgsWElBSEJOS0VDR1JPNTk4LFhJQUhCTktFQ0dSTzU5OC1ucTd1ZXJ3eiwyMDE1LTAxLTE1VDA5OjU3OjMxLjAwMDAwMCswMDAwLDIwMTUtMDEtMTVUMTA6MTY6MTMuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA1LDMwLjUsMjAxNS0wMS0xNCxnb29nbGUsRWd5cHQKMTEzOSxYSUFIQk5LRUNHUk81OTgsWElBSEJOS0VDR1JPNTk4LW5xN3Vlcnd6LDIwMTUtMDEtMTVUMDk6NTc6MzEuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNVQxMDoyMToyNS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDMsMzAuNSwyMDE1LTAxLTE0LGdvb2dsZSxFZ3lwdAoxMTQxLFdFUEtZTlJYREZVVDU3MixXRVBLWU5SWERGVVQ1NzItZHo3MTZpOHMsMjAxNS0wMS0xNVQxMDoxNzo1NC4wMDAwMDArMDAwMCwyMDE1LTAxLTE1VDEwOjE4OjM2LjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDc4LDM5LjUsMjAxNS0wMS0xMyxjcm9zc3Byb21vLENoaW5hCjExNDMsV0VQS1lOUlhERlVUNTcyLFdFUEtZTlJYREZVVDU3Mi1kejcxNmk4cywyMDE1LTAxLTE1VDEwOjE3OjU0LjAwMDAwMCswMDAwLDIwMTUtMDEtMTVUMTA6MjY6MDAuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA0MiwzOS41LDIwMTUtMDEtMTMsY3Jvc3Nwcm9tbyxDaGluYQoxMTQ4LE9NQ1ZVQUlLU0RUUjY1MSxPTUNWVUFJS1NEVFI2NTEteDFndTZmZWEsMjAxNS0wMS0xNVQxMDoyMjo1NS4wMDAwMDArMDAwMCwyMDE1LTAxLTE1VDEwOjM2OjA3LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNywyOS43LDIwMTUtMDEtMDcsb3RoZXJfY2FtcGFpZ24sVW5pdGVkIFN0YXRlcwoxMTUzLEpWQlpDUEtYSEZNVTQ5MSxKVkJaQ1BLWEhGTVU0OTEtanN1YXp5dnAsMjAxNS0wMS0xNVQxMDozNzozOS4wMDAwMDArMDAwMCwyMDE1LTAxLTE1VDEwOjUxOjIxLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wOCwzOC40LDIwMTUtMDEtMDcsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjExNTcsSlZCWkNQS1hIRk1VNDkxLEpWQlpDUEtYSEZNVTQ5MS1qc3Vhenl2cCwyMDE1LTAxLTE1VDEwOjM3OjM5LjAwMDAwMCswMDAwLDIwMTUtMDEtMTVUMTE6MTE6MjcuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4wOSwzOC40LDIwMTUtMDEtMDcsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjExNTksWElBSEJOS0VDR1JPNTk4LFhJQUhCTktFQ0dSTzU5OC1hZzE5anQ4ZiwyMDE1LTAxLTE1VDExOjM0OjQyLjAwMDAwMCswMDAwLDIwMTUtMDEtMTVUMTE6Mzg6NDguMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAxLDE1LjksMjAxNS0wMS0xNCxnb29nbGUsRWd5cHQKMTE2MCxYSUFIQk5LRUNHUk81OTgsWElBSEJOS0VDR1JPNTk4LWFnMTlqdDhmLDIwMTUtMDEtMTVUMTE6MzQ6NDIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNVQxMTo0MDo1NC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDM1LDE1LjksMjAxNS0wMS0xNCxnb29nbGUsRWd5cHQKMTE2NixPQU5DSVZZWEpNUkw1OTcsT0FOQ0lWWVhKTVJMNTk3LWVpeTFmdDVhLDIwMTUtMDEtMTVUMTE6NTA6NDQuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNVQxMjoxMToyMC4wMDAwMDArMDAwMCxhZCxhZF8yMHNlYywwLjA5OCwzOC44LDIwMTUtMDEtMTUsb3RoZXJfY2FtcGFpZ24sSW5kaWEKMTE2NyxPQU5DSVZZWEpNUkw1OTcsT0FOQ0lWWVhKTVJMNTk3LWVpeTFmdDVhLDIwMTUtMDEtMTVUMTE6NTA6NDQuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNVQxMjoyNTo0NC4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjAzNCwzOC44LDIwMTUtMDEtMTUsb3RoZXJfY2FtcGFpZ24sSW5kaWEKMTE3NCxPQU5DSVZZWEpNUkw1OTcsT0FOQ0lWWVhKTVJMNTk3LWJyaTl1cGgxLDIwMTUtMDEtMTVUMTM6MjQ6MjcuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNVQxMzoyNDo1MS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDA0LDE3LjcsMjAxNS0wMS0xNSxvdGhlcl9jYW1wYWlnbixJbmRpYQoxMTc1LE9BTkNJVllYSk1STDU5NyxPQU5DSVZZWEpNUkw1OTctYnJpOXVwaDEsMjAxNS0wMS0xNVQxMzoyNDoyNy4wMDAwMDArMDAwMCwyMDE1LTAxLTE1VDEzOjI4OjE1LjAwMDAwMCswMDAwLGFkLGFkXzE1c2VjLDAuMDgsMTcuNywyMDE1LTAxLTE1LG90aGVyX2NhbXBhaWduLEluZGlhCjExNzgsSlZCWkNQS1hIRk1VNDkxLEpWQlpDUEtYSEZNVTQ5MS0zZWh5N2RxOSwyMDE1LTAxLTE1VDE2OjM3OjQ5LjAwMDAwMCswMDAwLDIwMTUtMDEtMTVUMTY6NDU6MjUuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA3LDguMCwyMDE1LTAxLTA3LG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwoxMTg0LE1UQ0lXS09WQVNZUDkyNSxNVENJV0tPVkFTWVA5MjUteXNwZGlrcWosMjAxNS0wMS0xNVQxNzowNjozMy4wMDAwMDArMDAwMCwyMDE1LTAxLTE1VDE3OjA4OjI3LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNSwzMS4wLDIwMTUtMDEtMTQsb3JnYW5pYyxHZXJtYW55CjExODYsTVRDSVdLT1ZBU1lQOTI1LE1UQ0lXS09WQVNZUDkyNS15c3BkaWtxaiwyMDE1LTAxLTE1VDE3OjA2OjMzLjAwMDAwMCswMDAwLDIwMTUtMDEtMTVUMTc6MTE6MjEuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA0LDMxLjAsMjAxNS0wMS0xNCxvcmdhbmljLEdlcm1hbnkKMTE4OCxETFRGVlFXWUlYUko1ODksRExURlZRV1lJWFJKNTg5LXI0a2J4MXl0LDIwMTUtMDEtMTVUMTg6NDg6NTIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNVQxOTowMzo0MC4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjA3NywxNy44LDIwMTUtMDEtMTMsb3JnYW5pYyxTb3V0aCBBZnJpY2EKMTE5MyxHSkNYTlRXRUJJUFEzNjksR0pDWE5UV0VCSVBRMzY5LTVpa212ZmIxLDIwMTUtMDEtMTVUMjA6NTI6NTAuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNVQyMDo1NDoyNi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDIsMzMuMiwyMDE1LTAxLTE0LG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwoxMTk0LEdKQ1hOVFdFQklQUTM2OSxHSkNYTlRXRUJJUFEzNjktNWlrbXZmYjEsMjAxNS0wMS0xNVQyMDo1Mjo1MC4wMDAwMDArMDAwMCwyMDE1LTAxLTE1VDIxOjAyOjMyLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wOSwzMy4yLDIwMTUtMDEtMTQsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjExOTksVkxRSFlKQ0tCT0lONzI5LFZMUUhZSkNLQk9JTjcyOS05ZXZqb3djdCwyMDE1LTAxLTE1VDIxOjU1OjIxLjAwMDAwMCswMDAwLDIwMTUtMDEtMTVUMjI6MDg6NTcuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAxOCwzNy4yLDIwMTUtMDEtMTAsb3JnYW5pYyxKYXBhbgoxMjAzLFpNSkxQR0NSSUtOQTQ3MSxaTUpMUEdDUklLTkE0NzEtaGk5dXI2eWIsMjAxNS0wMS0xNVQyMjo0OToyMC4wMDAwMDArMDAwMCwyMDE1LTAxLTE1VDIzOjE3OjIwLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNDUsMzkuMCwyMDE1LTAxLTEwLG9yZ2FuaWMsRWd5cHQKMTIxMCxSWVpIQUpFWE1CSUY3MjQsUllaSEFKRVhNQklGNzI0LXFwaWhtcng1LDIwMTUtMDEtMTZUMDE6MTg6MTIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNlQwMToyNTo1NC4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjA4MSwxNC4wLDIwMTUtMDEtMTUsZ29vZ2xlLFBvcnR1Z2FsCjEyMjIsSlZCWkNQS1hIRk1VNDkxLEpWQlpDUEtYSEZNVTQ5MS0yb3p1eWxrdywyMDE1LTAxLTE2VDAyOjU1OjM1LjAwMDAwMCswMDAwLDIwMTUtMDEtMTZUMDM6MjA6NTMuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA1LDM4LjIsMjAxNS0wMS0wNyxvcmdhbmljLFVuaXRlZCBTdGF0ZXMKMTIyNixYSUFIQk5LRUNHUk81OTgsWElBSEJOS0VDR1JPNTk4LTc0YXRtaXhnLDIwMTUtMDEtMTZUMDM6NDI6MzkuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNlQwMzo0NjowOS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDMsMTYuOCwyMDE1LTAxLTE0LGdvb2dsZSxFZ3lwdAoxMjI5LEJGTkxVUklTSlhUSDY0NyxCRk5MVVJJU0pYVEg2NDctZmRhc3d5cWcsMjAxNS0wMS0xNlQwMzo0NzoxNC4wMDAwMDArMDAwMCwyMDE1LTAxLTE2VDAzOjUyOjMyLjAwMDAwMCswMDAwLGFkLGFkXzIwc2VjLDAuMDg0LDEyLjEsMjAxNS0wMS0xMCxvcmdhbmljLEluZGlhCjEyMzAsQkZOTFVSSVNKWFRINjQ3LEJGTkxVUklTSlhUSDY0Ny1mZGFzd3lxZywyMDE1LTAxLTE2VDAzOjQ3OjE0LjAwMDAwMCswMDAwLDIwMTUtMDEtMTZUMDM6NTU6MDIuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAxOCwxMi4xLDIwMTUtMDEtMTAsb3JnYW5pYyxJbmRpYQoxMjM1LE9NQ1ZVQUlLU0RUUjY1MSxPTUNWVUFJS1NEVFI2NTEtcTVtNnZyNHgsMjAxNS0wMS0xNlQwNzoyODowMC4wMDAwMDArMDAwMCwyMDE1LTAxLTE2VDA3OjUwOjAwLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4xLDM2LjksMjAxNS0wMS0wNyxvdGhlcl9jYW1wYWlnbixVbml0ZWQgU3RhdGVzCjEyMzYsT01DVlVBSUtTRFRSNjUxLE9NQ1ZVQUlLU0RUUjY1MS1xNW02dnI0eCwyMDE1LTAxLTE2VDA3OjI4OjAwLjAwMDAwMCswMDAwLDIwMTUtMDEtMTZUMDc6NTM6NDguMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyLDM2LjksMjAxNS0wMS0wNyxvdGhlcl9jYW1wYWlnbixVbml0ZWQgU3RhdGVzCjEyMzcsT01DVlVBSUtTRFRSNjUxLE9NQ1ZVQUlLU0RUUjY1MS1xNW02dnI0eCwyMDE1LTAxLTE2VDA3OjI4OjAwLjAwMDAwMCswMDAwLDIwMTUtMDEtMTZUMDg6MDE6MzAuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA3LDM2LjksMjAxNS0wMS0wNyxvdGhlcl9jYW1wYWlnbixVbml0ZWQgU3RhdGVzCjEyNDMsWlBUSUhOU1ZGWUFRMTQ2LFpQVElITlNWRllBUTE0Ni1vaWwxODI2dSwyMDE1LTAxLTE2VDA3OjQ2OjQxLjAwMDAwMCswMDAwLDIwMTUtMDEtMTZUMDc6NTY6NTMuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4wOTYsMjEuOCwyMDE1LTAxLTA0LGZhY2Vib29rLE1leGljbwoxMjQ0LFpQVElITlNWRllBUTE0NixaUFRJSE5TVkZZQVExNDYtb2lsMTgyNnUsMjAxNS0wMS0xNlQwNzo0Njo0MS4wMDAwMDArMDAwMCwyMDE1LTAxLTE2VDA4OjAzOjUzLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNzIsMjEuOCwyMDE1LTAxLTA0LGZhY2Vib29rLE1leGljbwoxMjQ1LFVQRk1MSUVLV0hZWDk2NCxVUEZNTElFS1dIWVg5NjQteHJvZ21kYmssMjAxNS0wMS0xNlQwODowMzozOS4wMDAwMDArMDAwMCwyMDE1LTAxLTE2VDA4OjA4OjI3LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4xLDMzLjQsMjAxNS0wMS0xNixvcmdhbmljLEdlcm1hbnkKMTI0OCxVUEZNTElFS1dIWVg5NjQsVVBGTUxJRUtXSFlYOTY0LXhyb2dtZGJrLDIwMTUtMDEtMTZUMDg6MDM6MzkuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNlQwODoyMjoyNy4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDMsMzMuNCwyMDE1LTAxLTE2LG9yZ2FuaWMsR2VybWFueQoxMjU1LFFKR1ZPQkxBVElIVzQ1NyxRSkdWT0JMQVRJSFc0NTctdWhqN2Z4dGQsMjAxNS0wMS0xNlQwODoxNjozMy4wMDAwMDArMDAwMCwyMDE1LTAxLTE2VDA4OjI1OjIxLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMzMsMjkuNCwyMDE1LTAxLTAyLG90aGVyX2NhbXBhaWduLFN3ZWRlbgoxMjU2LFFKR1ZPQkxBVElIVzQ1NyxRSkdWT0JMQVRJSFc0NTctdWhqN2Z4dGQsMjAxNS0wMS0xNlQwODoxNjozMy4wMDAwMDArMDAwMCwyMDE1LTAxLTE2VDA4OjI5OjQ1LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMjIsMjkuNCwyMDE1LTAxLTAyLG90aGVyX2NhbXBhaWduLFN3ZWRlbgoxMjU3LFFKR1ZPQkxBVElIVzQ1NyxRSkdWT0JMQVRJSFc0NTctdWhqN2Z4dGQsMjAxNS0wMS0xNlQwODoxNjozMy4wMDAwMDArMDAwMCwyMDE1LTAxLTE2VDA4OjMyOjI3LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wODgsMjkuNCwyMDE1LTAxLTAyLG90aGVyX2NhbXBhaWduLFN3ZWRlbgoxMjY0LFJNT1NXSEpHRUxDSTY3NSxSTU9TV0hKR0VMQ0k2NzUtb2lic3luNGYsMjAxNS0wMS0xNlQwOTozMTo0Mi4wMDAwMDArMDAwMCwyMDE1LTAxLTE2VDA5OjMyOjU0LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wOSwxNi42LDIwMTUtMDEtMTAsb3RoZXJfY2FtcGFpZ24sRnJhbmNlCjEyNjcsTkFPSlJETUNTRUJJMjgxLE5BT0pSRE1DU0VCSTI4MS1ud2Z2ZDRtbywyMDE1LTAxLTE2VDEwOjAwOjEyLjAwMDAwMCswMDAwLDIwMTUtMDEtMTZUMTA6MDA6MzAuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAzNiwxNS40LDIwMTUtMDEtMTEsb3JnYW5pYyxOb3J3YXkKMTI2OSxOQU9KUkRNQ1NFQkkyODEsTkFPSlJETUNTRUJJMjgxLW53ZnZkNG1vLDIwMTUtMDEtMTZUMTA6MDA6MTIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNlQxMDowNDozNi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDI3LDE1LjQsMjAxNS0wMS0xMSxvcmdhbmljLE5vcndheQoxMjc2LE1ZUUdKS09VSVdIRjYxOSxNWVFHSktPVUlXSEY2MTktOW82cDVnaWEsMjAxNS0wMS0xNlQxMDoyMzoxNS4wMDAwMDArMDAwMCwyMDE1LTAxLTE2VDEwOjI5OjIxLjAwMDAwMCswMDAwLGFkLGFkXzE1c2VjLDAuMDc4LDE3LjQsMjAxNS0wMS0xNixvcmdhbmljLEluZGlhCjEyNzcsR0pDWE5UV0VCSVBRMzY5LEdKQ1hOVFdFQklQUTM2OS00cWd0YmhmYywyMDE1LTAxLTE2VDExOjE3OjE0LjAwMDAwMCswMDAwLDIwMTUtMDEtMTZUMTE6MzA6NTYuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyLDI2LjQsMjAxNS0wMS0xNCxvcmdhbmljLFVuaXRlZCBTdGF0ZXMKMTI3OCxHSkNYTlRXRUJJUFEzNjksR0pDWE5UV0VCSVBRMzY5LTRxZ3RiaGZjLDIwMTUtMDEtMTZUMTE6MTc6MTQuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNlQxMTozMTowOC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDQsMjYuNCwyMDE1LTAxLTE0LG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwoxMjgyLEdKQ1hOVFdFQklQUTM2OSxHSkNYTlRXRUJJUFEzNjktNHFndGJoZmMsMjAxNS0wMS0xNlQxMToxNzoxNC4wMDAwMDArMDAwMCwyMDE1LTAxLTE2VDExOjQxOjI2LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4xLDI2LjQsMjAxNS0wMS0xNCxvcmdhbmljLFVuaXRlZCBTdGF0ZXMKMTI4NyxNVENJV0tPVkFTWVA5MjUsTVRDSVdLT1ZBU1lQOTI1LWhzNGk1MnZnLDIwMTUtMDEtMTZUMTI6MjI6MjMuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNlQxMjozMDozNS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMSw0MS4wLDIwMTUtMDEtMTQsb3JnYW5pYyxHZXJtYW55CjEyODksTVRDSVdLT1ZBU1lQOTI1LE1UQ0lXS09WQVNZUDkyNS1oczRpNTJ2ZywyMDE1LTAxLTE2VDEyOjIyOjIzLjAwMDAwMCswMDAwLDIwMTUtMDEtMTZUMTI6NDg6MjMuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjEsNDEuMCwyMDE1LTAxLTE0LG9yZ2FuaWMsR2VybWFueQoxMjkyLFpQVElITlNWRllBUTE0NixaUFRJSE5TVkZZQVExNDYtdThjNG5xNzUsMjAxNS0wMS0xNlQxMjoyMzo1OS4wMDAwMDArMDAwMCwyMDE1LTAxLTE2VDEyOjMxOjIzLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNzIsMTAuMiwyMDE1LTAxLTA0LGZhY2Vib29rLE1leGljbwoxMjk0LFBMUUVTQk5HVURLSjE1NCxQTFFFU0JOR1VES0oxNTQtOHB2dGFsNm4sMjAxNS0wMS0xNlQxMjozNjozOC4wMDAwMDArMDAwMCwyMDE1LTAxLTE2VDEyOjQ2OjAyLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNDIsMzIuNiwyMDE1LTAxLTEyLGZhY2Vib29rLEphcGFuCjEzMDIsV0VQS1lOUlhERlVUNTcyLFdFUEtZTlJYREZVVDU3Mi1haDhiNms5NSwyMDE1LTAxLTE2VDEzOjExOjI2LjAwMDAwMCswMDAwLDIwMTUtMDEtMTZUMTM6MTg6MjAuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA3MiwxMi45LDIwMTUtMDEtMTMsY3Jvc3Nwcm9tbyxDaGluYQoxMzAzLEdKQ1hOVFdFQklQUTM2OSxHSkNYTlRXRUJJUFEzNjktazdweG00NTEsMjAxNS0wMS0xNlQxMzoxOToxMC4wMDAwMDArMDAwMCwyMDE1LTAxLTE2VDEzOjI2OjIyLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNCwzMy40LDIwMTUtMDEtMTQsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjEzMDYsT01DVlVBSUtTRFRSNjUxLE9NQ1ZVQUlLU0RUUjY1MS1xYjRwM3JmdiwyMDE1LTAxLTE2VDEzOjI4OjU2LjAwMDAwMCswMDAwLDIwMTUtMDEtMTZUMTM6Mjk6MzIuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA1LDQwLjQsMjAxNS0wMS0wNyxvdGhlcl9jYW1wYWlnbixVbml0ZWQgU3RhdGVzCjEzMDcsT01DVlVBSUtTRFRSNjUxLE9NQ1ZVQUlLU0RUUjY1MS1xYjRwM3JmdiwyMDE1LTAxLTE2VDEzOjI4OjU2LjAwMDAwMCswMDAwLDIwMTUtMDEtMTZUMTM6NTE6MDIuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA4LDQwLjQsMjAxNS0wMS0wNyxvdGhlcl9jYW1wYWlnbixVbml0ZWQgU3RhdGVzCjEzMTQsR0FZSUJMVUNPRURKNzMyLEdBWUlCTFVDT0VESjczMi05dmEyNHV6ZCwyMDE1LTAxLTE2VDEzOjM1OjE0LjAwMDAwMCswMDAwLDIwMTUtMDEtMTZUMTQ6MDA6NDQuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA0LDI2LjgsMjAxNS0wMS0wMyxvcmdhbmljLFVuaXRlZCBTdGF0ZXMKMTMxNSxQSk9UQk5IWExGUlEyNjUsUEpPVEJOSFhMRlJRMjY1LWJjOWlsaDR3LDIwMTUtMDEtMTZUMTQ6NDc6MzkuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNlQxNDo1Mzo1MS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMSw0MC4wLDIwMTUtMDEtMTYsb3JnYW5pYyxBdXN0cmlhCjEzMTYsUEpPVEJOSFhMRlJRMjY1LFBKT1RCTkhYTEZSUTI2NS1iYzlpbGg0dywyMDE1LTAxLTE2VDE0OjQ3OjM5LjAwMDAwMCswMDAwLDIwMTUtMDEtMTZUMTQ6NTU6MzkuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA3LDQwLjAsMjAxNS0wMS0xNixvcmdhbmljLEF1c3RyaWEKMTMyMSxHSkNYTlRXRUJJUFEzNjksR0pDWE5UV0VCSVBRMzY5LTZidmM1Z3FkLDIwMTUtMDEtMTZUMTU6MzI6MzQuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNlQxNTozMjo1Mi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDIsNS4xLDIwMTUtMDEtMTQsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjEzMjQsUFpCTlJLU01VTEhYMjEzLFBaQk5SS1NNVUxIWDIxMy1vNnh5dXZoOCwyMDE1LTAxLTE2VDE2OjI5OjEwLjAwMDAwMCswMDAwLDIwMTUtMDEtMTZUMTY6MzM6NTguMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyLDE4LjUsMjAxNS0wMS0wNyxvcmdhbmljLEluZGlhCjEzMjUsUFpCTlJLU01VTEhYMjEzLFBaQk5SS1NNVUxIWDIxMy1vNnh5dXZoOCwyMDE1LTAxLTE2VDE2OjI5OjEwLjAwMDAwMCswMDAwLDIwMTUtMDEtMTZUMTY6MzQ6MzQuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAxNiwxOC41LDIwMTUtMDEtMDcsb3JnYW5pYyxJbmRpYQoxMzI4LEtHWkNPSkhQRlRRVjc1MyxLR1pDT0pIUEZUUVY3NTMtd2gzc2U1NjcsMjAxNS0wMS0xNlQxNzozNzoyOC4wMDAwMDArMDAwMCwyMDE1LTAxLTE2VDE3OjU4OjIyLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4xLDM3LjAsMjAxNS0wMS0xMSxvcmdhbmljLFVuaXRlZCBTdGF0ZXMKMTMzNCxIRFNBTVBUT0xCV0M0MzgsSERTQU1QVE9MQldDNDM4LXg2OXRuenJ2LDIwMTUtMDEtMTZUMTk6NDI6MjIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNlQxOTo0OTo0Ni4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDk2LDE1LjksMjAxNS0wMS0xNCxvcmdhbmljLFN3aXR6ZXJsYW5kCjEzNDEsWElBSEJOS0VDR1JPNTk4LFhJQUhCTktFQ0dSTzU5OC1scGk4MnVyaywyMDE1LTAxLTE2VDIwOjM4OjIwLjAwMDAwMCswMDAwLDIwMTUtMDEtMTZUMjA6NTQ6MDguMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyLDQxLjAsMjAxNS0wMS0xNCxnb29nbGUsRWd5cHQKMTM0MyxYSUFIQk5LRUNHUk81OTgsWElBSEJOS0VDR1JPNTk4LWxwaTgydXJrLDIwMTUtMDEtMTZUMjA6Mzg6MjAuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNlQyMTowMjozMi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDIsNDEuMCwyMDE1LTAxLTE0LGdvb2dsZSxFZ3lwdAoxMzQ0LFhJQUhCTktFQ0dSTzU5OCxYSUFIQk5LRUNHUk81OTgtbHBpODJ1cmssMjAxNS0wMS0xNlQyMDozODoyMC4wMDAwMDArMDAwMCwyMDE1LTAxLTE2VDIxOjA3OjQ0LjAwMDAwMCswMDAwLGFkLGFkXzE1c2VjLDAuMDksNDEuMCwyMDE1LTAxLTE0LGdvb2dsZSxFZ3lwdAoxMzQ3LEdBWUlCTFVDT0VESjczMixHQVlJQkxVQ09FREo3MzItZWw1ajM0eHQsMjAxNS0wMS0xNlQyMDo1NjozOS4wMDAwMDArMDAwMCwyMDE1LTAxLTE2VDIxOjA0OjAzLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNywyNS41LDIwMTUtMDEtMDMsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjEzNTEsR0FZSUJMVUNPRURKNzMyLEdBWUlCTFVDT0VESjczMi1lbDVqMzR4dCwyMDE1LTAxLTE2VDIwOjU2OjM5LjAwMDAwMCswMDAwLDIwMTUtMDEtMTZUMjE6MTA6MzMuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjEsMjUuNSwyMDE1LTAxLTAzLG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwoxMzUyLE5BT0pSRE1DU0VCSTI4MSxOQU9KUkRNQ1NFQkkyODEtMW1zeXQ5MmssMjAxNS0wMS0xNlQyMTo1ODo1MC4wMDAwMDArMDAwMCwyMDE1LTAxLTE2VDIyOjA5OjQ0LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNDUsMTUuNSwyMDE1LTAxLTExLG9yZ2FuaWMsTm9yd2F5CjEzNTcsUEpPVEJOSFhMRlJRMjY1LFBKT1RCTkhYTEZSUTI2NS13bXV0cmsyaCwyMDE1LTAxLTE2VDIyOjA2OjIxLjAwMDAwMCswMDAwLDIwMTUtMDEtMTZUMjI6MzI6NTcuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyLDI2LjcsMjAxNS0wMS0xNixvcmdhbmljLEF1c3RyaWEKMTM2MixRTkxWUkRFT1hGWUo4OTIsUU5MVlJERU9YRllKODkyLXJiZnNocDhpLDIwMTUtMDEtMTZUMjM6Mjc6MDUuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNlQyMzo1MzowNS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDksMjcuNCwyMDE1LTAxLTA5LGNyb3NzcHJvbW8sQXVzdHJhbGlhCjEzNjUsSllFQkNMTlVaVFhRNDU3LEpZRUJDTE5VWlRYUTQ1Ny11bHZqa3doOCwyMDE1LTAxLTE2VDIzOjQ2OjE1LjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMDA6MTM6MjEuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4wNiwzNy43LDIwMTUtMDEtMDQsb3RoZXJfY2FtcGFpZ24sRWd5cHQKMTM2OCxETFRGVlFXWUlYUko1ODksRExURlZRV1lJWFJKNTg5LXkzdnNycWxiLDIwMTUtMDEtMTdUMDE6MzA6MTcuMDAwMDAwKzAwMDAsMjAxNS0wMS0xN1QwMTo0MDo1OS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDIxOTgsMzcuMiwyMDE1LTAxLTEzLG9yZ2FuaWMsU291dGggQWZyaWNhCjEzNzYsWkdFVlFKU0tGSUJYMzk4LFpHRVZRSlNLRklCWDM5OC1sd3V5MXhhdiwyMDE1LTAxLTE3VDAxOjU5OjE5LjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMDI6MDM6NDkuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4wOTgsMzMuNiwyMDE1LTAxLTE3LG9yZ2FuaWMsU291dGggS29yZWEKMTM3NyxaR0VWUUpTS0ZJQlgzOTgsWkdFVlFKU0tGSUJYMzk4LWx3dXkxeGF2LDIwMTUtMDEtMTdUMDE6NTk6MTkuMDAwMDAwKzAwMDAsMjAxNS0wMS0xN1QwMjoyMTo1NS4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjA3NywzMy42LDIwMTUtMDEtMTcsb3JnYW5pYyxTb3V0aCBLb3JlYQoxNDAwLFhJQUhCTktFQ0dSTzU5OCxYSUFIQk5LRUNHUk81OTgtZ3J2dTFwNmYsMjAxNS0wMS0xN1QwMzozODozNi4wMDAwMDArMDAwMCwyMDE1LTAxLTE3VDAzOjQyOjEyLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNTUsMTEuMiwyMDE1LTAxLTE0LGdvb2dsZSxFZ3lwdAoxNDA0LFBaQk5SS1NNVUxIWDIxMyxQWkJOUktTTVVMSFgyMTMtMTcyOHFmZG4sMjAxNS0wMS0xN1QwMzozODo0Ni4wMDAwMDArMDAwMCwyMDE1LTAxLTE3VDAzOjQ5OjIyLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMiwyMi41LDIwMTUtMDEtMDcsb3JnYW5pYyxJbmRpYQoxNDA1LFBaQk5SS1NNVUxIWDIxMyxQWkJOUktTTVVMSFgyMTMtMTcyOHFmZG4sMjAxNS0wMS0xN1QwMzozODo0Ni4wMDAwMDArMDAwMCwyMDE1LTAxLTE3VDAzOjUzOjQwLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMjQsMjIuNSwyMDE1LTAxLTA3LG9yZ2FuaWMsSW5kaWEKMTQwNixNWVFHSktPVUlXSEY2MTksTVlRR0pLT1VJV0hGNjE5LTVobnRtaXd5LDIwMTUtMDEtMTdUMDQ6MDM6MTMuMDAwMDAwKzAwMDAsMjAxNS0wMS0xN1QwNDowODoxMy4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDI0LDguMywyMDE1LTAxLTE2LG9yZ2FuaWMsSW5kaWEKMTQwOSxKWUVCQ0xOVVpUWFE0NTcsSllFQkNMTlVaVFhRNDU3LWRtdmt5Mm5oLDIwMTUtMDEtMTdUMDU6MzY6MzcuMDAwMDAwKzAwMDAsMjAxNS0wMS0xN1QwNTo0MjowMS4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjAzNSwxMi40LDIwMTUtMDEtMDQsb3RoZXJfY2FtcGFpZ24sRWd5cHQKMTQxMCxNWVFHSktPVUlXSEY2MTksTVlRR0pLT1VJV0hGNjE5LXRsd2NzeTc2LDIwMTUtMDEtMTdUMDY6MjM6NTguMDAwMDAwKzAwMDAsMjAxNS0wMS0xN1QwNjoyNDoxMC4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjAyOCwxMi4zLDIwMTUtMDEtMTYsb3JnYW5pYyxJbmRpYQoxNDExLE1ZUUdKS09VSVdIRjYxOSxNWVFHSktPVUlXSEY2MTktdGx3Y3N5NzYsMjAxNS0wMS0xN1QwNjoyMzo1OC4wMDAwMDArMDAwMCwyMDE1LTAxLTE3VDA2OjI5OjA0LjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDE0LDEyLjMsMjAxNS0wMS0xNixvcmdhbmljLEluZGlhCjE0MTMsUEpPVEJOSFhMRlJRMjY1LFBKT1RCTkhYTEZSUTI2NS11YXFkeTVldCwyMDE1LTAxLTE3VDA2OjM0OjEyLjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMDY6NDI6MDYuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA4LDIxLjUsMjAxNS0wMS0xNixvcmdhbmljLEF1c3RyaWEKMTQyMCxFS0lIWEJSRkdPQ0Q1NzEsRUtJSFhCUkZHT0NENTcxLW41a2UyYWw3LDIwMTUtMDEtMTdUMDg6MTY6MTYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xN1QwODoxNjo1OC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDgsMzcuMiwyMDE1LTAxLTE3LGFwcGxlLFVuaXRlZCBLaW5nZG9tCjE0MjYsV0JLRllKWENaTlVINTYzLFdCS0ZZSlhDWk5VSDU2My1sbWpudTcxZywyMDE1LTAxLTE3VDA4OjMzOjAwLjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMDg6NDY6NDIuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA1LDE0LjYsMjAxNS0wMS0xMyxvcmdhbmljLENhbmFkYQoxNDM0LEJGTkxVUklTSlhUSDY0NyxCRk5MVVJJU0pYVEg2NDctcWp1Z3BmMm4sMjAxNS0wMS0xN1QwOTo1ODoxOC4wMDAwMDArMDAwMCwyMDE1LTAxLTE3VDA5OjU5OjA2LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMTgsMjkuOCwyMDE1LTAxLTEwLG9yZ2FuaWMsSW5kaWEKMTQzNSxCRk5MVVJJU0pYVEg2NDcsQkZOTFVSSVNKWFRINjQ3LXFqdWdwZjJuLDIwMTUtMDEtMTdUMDk6NTg6MTguMDAwMDAwKzAwMDAsMjAxNS0wMS0xN1QxMDowNTowMC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDE4LDI5LjgsMjAxNS0wMS0xMCxvcmdhbmljLEluZGlhCjE0MzYsQkZOTFVSSVNKWFRINjQ3LEJGTkxVUklTSlhUSDY0Ny1xanVncGYybiwyMDE1LTAxLTE3VDA5OjU4OjE4LjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMTA6MTU6NDguMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyLDI5LjgsMjAxNS0wMS0xMCxvcmdhbmljLEluZGlhCjE0MzgsQkZOTFVSSVNKWFRINjQ3LEJGTkxVUklTSlhUSDY0Ny1xanVncGYybiwyMDE1LTAxLTE3VDA5OjU4OjE4LjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMTA6MjU6MDYuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAwNiwyOS44LDIwMTUtMDEtMTAsb3JnYW5pYyxJbmRpYQoxNDQ0LFhJQUhCTktFQ0dSTzU5OCxYSUFIQk5LRUNHUk81OTgtcW84cm16aWosMjAxNS0wMS0xN1QxMDo0MzoyOC4wMDAwMDArMDAwMCwyMDE1LTAxLTE3VDEwOjU4OjM0LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMywyOC44LDIwMTUtMDEtMTQsZ29vZ2xlLEVneXB0CjE0NDUsWElBSEJOS0VDR1JPNTk4LFhJQUhCTktFQ0dSTzU5OC1xbzhybXppaiwyMDE1LTAxLTE3VDEwOjQzOjI4LjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMTE6MDE6MDQuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAxNSwyOC44LDIwMTUtMDEtMTQsZ29vZ2xlLEVneXB0CjE0NDcsWElBSEJOS0VDR1JPNTk4LFhJQUhCTktFQ0dSTzU5OC1xbzhybXppaiwyMDE1LTAxLTE3VDEwOjQzOjI4LjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMTE6MDg6NTguMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA1LDI4LjgsMjAxNS0wMS0xNCxnb29nbGUsRWd5cHQKMTQ2MSxNVENJV0tPVkFTWVA5MjUsTVRDSVdLT1ZBU1lQOTI1LW51OWR3M2JvLDIwMTUtMDEtMTdUMTI6MDM6MjcuMDAwMDAwKzAwMDAsMjAxNS0wMS0xN1QxMjoyNjowOS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDcsMzAuMCwyMDE1LTAxLTE0LG9yZ2FuaWMsR2VybWFueQoxNDY0LE1UQ0lXS09WQVNZUDkyNSxNVENJV0tPVkFTWVA5MjUtbnU5ZHczYm8sMjAxNS0wMS0xN1QxMjowMzoyNy4wMDAwMDArMDAwMCwyMDE1LTAxLTE3VDEyOjMxOjAzLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMywzMC4wLDIwMTUtMDEtMTQsb3JnYW5pYyxHZXJtYW55CjE0NzYsRUtJSFhCUkZHT0NENTcxLEVLSUhYQlJGR09DRDU3MS02bDFkNXhqcSwyMDE1LTAxLTE3VDEyOjU5OjI0LjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMTM6MDE6MjQuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4wOSwzMy41LDIwMTUtMDEtMTcsYXBwbGUsVW5pdGVkIEtpbmdkb20KMTQ3NyxFS0lIWEJSRkdPQ0Q1NzEsRUtJSFhCUkZHT0NENTcxLTZsMWQ1eGpxLDIwMTUtMDEtMTdUMTI6NTk6MjQuMDAwMDAwKzAwMDAsMjAxNS0wMS0xN1QxMzowMjo0Mi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDYsMzMuNSwyMDE1LTAxLTE3LGFwcGxlLFVuaXRlZCBLaW5nZG9tCjE0NzgsRUtJSFhCUkZHT0NENTcxLEVLSUhYQlJGR09DRDU3MS02bDFkNXhqcSwyMDE1LTAxLTE3VDEyOjU5OjI0LjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMTM6MTk6MTIuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjEsMzMuNSwyMDE1LTAxLTE3LGFwcGxlLFVuaXRlZCBLaW5nZG9tCjE0ODEsVVBGTUxJRUtXSFlYOTY0LFVQRk1MSUVLV0hZWDk2NC0ycW9tOG5leSwyMDE1LTAxLTE3VDE0OjUyOjA5LjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMTQ6NTc6MDkuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAzLDE4LjAsMjAxNS0wMS0xNixvcmdhbmljLEdlcm1hbnkKMTQ4OSxJQ0JBVVpLR1NRUEYxNDUsSUNCQVVaS0dTUVBGMTQ1LWg5dWtuMWZ4LDIwMTUtMDEtMTdUMTY6MDg6NTcuMDAwMDAwKzAwMDAsMjAxNS0wMS0xN1QxNjozMjo0NS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDM0LDI2LjUsMjAxNS0wMS0wNixnb29nbGUsU291dGggQWZyaWNhCjE0OTcsRkdLWFBOSVJKSENZNjI1LEZHS1hQTklSSkhDWTYyNS1vdnd0amh1cywyMDE1LTAxLTE3VDE3OjAwOjMzLjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMTc6MzQ6NDUuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA4LDM3LjksMjAxNS0wMS0xNyxjcm9zc3Byb21vLEhvbmcgS29uZwoxNDk5LElDQkFVWktHU1FQRjE0NSxJQ0JBVVpLR1NRUEYxNDUtOGozb3lzdDQsMjAxNS0wMS0xN1QxNzozODoxNy4wMDAwMDArMDAwMCwyMDE1LTAxLTE3VDE3OjQ2OjIzLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMzQsMTUuOCwyMDE1LTAxLTA2LGdvb2dsZSxTb3V0aCBBZnJpY2EKMTUwMixaUFRJSE5TVkZZQVExNDYsWlBUSUhOU1ZGWUFRMTQ2LW45cGw0MjdzLDIwMTUtMDEtMTdUMTg6Mjg6MjUuMDAwMDAwKzAwMDAsMjAxNS0wMS0xN1QxODozNjo0OS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDcyLDE4LjgsMjAxNS0wMS0wNCxmYWNlYm9vayxNZXhpY28KMTUwNSxaTUpMUEdDUklLTkE0NzEsWk1KTFBHQ1JJS05BNDcxLWN1Njd6aDV0LDIwMTUtMDEtMTdUMTk6MTA6MTYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xN1QxOToxMTo0Ni4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjA4LDMyLjAsMjAxNS0wMS0xMCxvcmdhbmljLEVneXB0CjE1MDcsWk1KTFBHQ1JJS05BNDcxLFpNSkxQR0NSSUtOQTQ3MS1jdTY3emg1dCwyMDE1LTAxLTE3VDE5OjEwOjE2LjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMTk6MzA6MDQuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA1LDMyLjAsMjAxNS0wMS0xMCxvcmdhbmljLEVneXB0CjE1MDksTVRDSVdLT1ZBU1lQOTI1LE1UQ0lXS09WQVNZUDkyNS01d3YzdGEybywyMDE1LTAxLTE3VDE5OjE2OjE5LjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMTk6Mjg6NDkuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA5LDE2LjIsMjAxNS0wMS0xNCxvcmdhbmljLEdlcm1hbnkKMTUxMCxXQktGWUpYQ1pOVUg1NjMsV0JLRllKWENaTlVINTYzLWNqODRnN3NhLDIwMTUtMDEtMTdUMTk6MTY6NTIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xN1QxOToxNzo0Ni4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDQsMjYuNSwyMDE1LTAxLTEzLG9yZ2FuaWMsQ2FuYWRhCjE1MTIsV0JLRllKWENaTlVINTYzLFdCS0ZZSlhDWk5VSDU2My1jajg0ZzdzYSwyMDE1LTAxLTE3VDE5OjE2OjUyLjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMTk6MjA6NDAuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA4LDI2LjUsMjAxNS0wMS0xMyxvcmdhbmljLENhbmFkYQoxNTE5LFZMT1NDS1laQkVUSjY4NCxWTE9TQ0tZWkJFVEo2ODQtejR2NnI3d3UsMjAxNS0wMS0xN1QyMTozMjowNy4wMDAwMDArMDAwMCwyMDE1LTAxLTE3VDIxOjQ3OjE5LjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMSw0MC4yLDIwMTUtMDEtMTcsb3JnYW5pYyxGcmFuY2UKMTUyNSxKVkJaQ1BLWEhGTVU0OTEsSlZCWkNQS1hIRk1VNDkxLXd2dDQxa3hjLDIwMTUtMDEtMTdUMjI6NDE6MjkuMDAwMDAwKzAwMDAsMjAxNS0wMS0xN1QyMzowNjoyMy4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDUsMzQuOSwyMDE1LTAxLTA3LG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwoxNTI2LEpWQlpDUEtYSEZNVTQ5MSxKVkJaQ1BLWEhGTVU0OTEtd3Z0NDFreGMsMjAxNS0wMS0xN1QyMjo0MToyOS4wMDAwMDArMDAwMCwyMDE1LTAxLTE3VDIzOjA5OjA1LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wOCwzNC45LDIwMTUtMDEtMDcsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjE1MjksUFpCTlJLU01VTEhYMjEzLFBaQk5SS1NNVUxIWDIxMy1yaGNhbXp0ZiwyMDE1LTAxLTE3VDIzOjA1OjE2LjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMjM6MDk6MjIuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAxOCwxNi4xLDIwMTUtMDEtMDcsb3JnYW5pYyxJbmRpYQoxNTMwLFBaQk5SS1NNVUxIWDIxMyxQWkJOUktTTVVMSFgyMTMtcmhjYW16dGYsMjAxNS0wMS0xN1QyMzowNToxNi4wMDAwMDArMDAwMCwyMDE1LTAxLTE3VDIzOjExOjM0LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMDgsMTYuMSwyMDE1LTAxLTA3LG9yZ2FuaWMsSW5kaWEKMTUzMyxQWkJOUktTTVVMSFgyMTMsUFpCTlJLU01VTEhYMjEzLXJoY2FtenRmLDIwMTUtMDEtMTdUMjM6MDU6MTYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xN1QyMzoxOTo1Mi4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjAxNiwxNi4xLDIwMTUtMDEtMDcsb3JnYW5pYyxJbmRpYQoxNTM0LFhJQUhCTktFQ0dSTzU5OCxYSUFIQk5LRUNHUk81OTgtaWN5YTFtN3QsMjAxNS0wMS0xN1QyMzozMTo1Ny4wMDAwMDArMDAwMCwyMDE1LTAxLTE3VDIzOjM4OjM5LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNDUsMTUuMywyMDE1LTAxLTE0LGdvb2dsZSxFZ3lwdAoxNTM1LFhJQUhCTktFQ0dSTzU5OCxYSUFIQk5LRUNHUk81OTgtaWN5YTFtN3QsMjAxNS0wMS0xN1QyMzozMTo1Ny4wMDAwMDArMDAwMCwyMDE1LTAxLTE3VDIzOjQ2OjE1LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMjUsMTUuMywyMDE1LTAxLTE0LGdvb2dsZSxFZ3lwdAoxNTM5LEdBWUlCTFVDT0VESjczMixHQVlJQkxVQ09FREo3MzItMXJwaHFkd3osMjAxNS0wMS0xOFQwMDozNDoyOC4wMDAwMDArMDAwMCwyMDE1LTAxLTE4VDAwOjUyOjM0LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4xLDI4LjUsMjAxNS0wMS0wMyxvcmdhbmljLFVuaXRlZCBTdGF0ZXMKMTU0OCxQSk9UQk5IWExGUlEyNjUsUEpPVEJOSFhMRlJRMjY1LTk1dHN5bGkzLDIwMTUtMDEtMThUMDI6MDI6MzIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOFQwMjo0MToxNC4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjA3LDQwLjcsMjAxNS0wMS0xNixvcmdhbmljLEF1c3RyaWEKMTU1MCxXQktGWUpYQ1pOVUg1NjMsV0JLRllKWENaTlVINTYzLXEyZjlnaXlkLDIwMTUtMDEtMThUMDI6NTQ6NTAuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOFQwMjo1OTozOC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDYsMTYuMiwyMDE1LTAxLTEzLG9yZ2FuaWMsQ2FuYWRhCjE1NTMsV0JLRllKWENaTlVINTYzLFdCS0ZZSlhDWk5VSDU2My1xMmY5Z2l5ZCwyMDE1LTAxLTE4VDAyOjU0OjUwLjAwMDAwMCswMDAwLDIwMTUtMDEtMThUMDM6MDM6MDIuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA1LDE2LjIsMjAxNS0wMS0xMyxvcmdhbmljLENhbmFkYQoxNTU1LFdFUEtZTlJYREZVVDU3MixXRVBLWU5SWERGVVQ1NzItbTVqd3ZpdHMsMjAxNS0wMS0xOFQwMzowMzo1OS4wMDAwMDArMDAwMCwyMDE1LTAxLTE4VDAzOjA3OjM1LjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDg0LDMxLjAsMjAxNS0wMS0xMyxjcm9zc3Byb21vLENoaW5hCjE1NTcsV0VQS1lOUlhERlVUNTcyLFdFUEtZTlJYREZVVDU3Mi1tNWp3dml0cywyMDE1LTAxLTE4VDAzOjAzOjU5LjAwMDAwMCswMDAwLDIwMTUtMDEtMThUMDM6MTY6MTcuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4wNzgsMzEuMCwyMDE1LTAxLTEzLGNyb3NzcHJvbW8sQ2hpbmEKMTU1OCxXRVBLWU5SWERGVVQ1NzIsV0VQS1lOUlhERlVUNTcyLW01and2aXRzLDIwMTUtMDEtMThUMDM6MDM6NTkuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOFQwMzoxNjo0MS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDcyLDMxLjAsMjAxNS0wMS0xMyxjcm9zc3Byb21vLENoaW5hCjE1NjEsS0daQ09KSFBGVFFWNzUzLEtHWkNPSkhQRlRRVjc1My1kYnFqM2s4cCwyMDE1LTAxLTE4VDAzOjQxOjU2LjAwMDAwMCswMDAwLDIwMTUtMDEtMThUMDM6NTA6MzguMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA0LDIzLjIsMjAxNS0wMS0xMSxvcmdhbmljLFVuaXRlZCBTdGF0ZXMKMTU2NCxLR1pDT0pIUEZUUVY3NTMsS0daQ09KSFBGVFFWNzUzLWRicWozazhwLDIwMTUtMDEtMThUMDM6NDE6NTYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOFQwNDowMzoyMC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDcsMjMuMiwyMDE1LTAxLTExLG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwoxNTY5LFBKT1RCTkhYTEZSUTI2NSxQSk9UQk5IWExGUlEyNjUtbWlwOHZvMmIsMjAxNS0wMS0xOFQwNDoyNjo0NS4wMDAwMDArMDAwMCwyMDE1LTAxLTE4VDA0OjU0OjI3LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wOCwzNi40LDIwMTUtMDEtMTYsb3JnYW5pYyxBdXN0cmlhCjE1NzIsR0pDWE5UV0VCSVBRMzY5LEdKQ1hOVFdFQklQUTM2OS1hY3Mzd2ZuaywyMDE1LTAxLTE4VDA1OjAwOjAzLjAwMDAwMCswMDAwLDIwMTUtMDEtMThUMDU6MDQ6MzMuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA5LDMzLjMsMjAxNS0wMS0xNCxvcmdhbmljLFVuaXRlZCBTdGF0ZXMKMTU4MixOUE1KSVlIRVRHS1cyOTcsTlBNSklZSEVUR0tXMjk3LXRuaTc4dTllLDIwMTUtMDEtMThUMDU6MjQ6MTguMDAwMDAwKzAwMDAsMjAxNS0wMS0xOFQwNTozODowNi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDIsMTQuMywyMDE1LTAxLTE4LGdvb2dsZSxQaGlsaXBwaW5lcwoxNTkxLFpQVElITlNWRllBUTE0NixaUFRJSE5TVkZZQVExNDYtZmwyOG52Z2MsMjAxNS0wMS0xOFQwNjo0NjowMS4wMDAwMDArMDAwMCwyMDE1LTAxLTE4VDA2OjU3OjEzLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMzYsMjMuOSwyMDE1LTAxLTA0LGZhY2Vib29rLE1leGljbwoxNTkyLFpQVElITlNWRllBUTE0NixaUFRJSE5TVkZZQVExNDYtZmwyOG52Z2MsMjAxNS0wMS0xOFQwNjo0NjowMS4wMDAwMDArMDAwMCwyMDE1LTAxLTE4VDA3OjAwOjU1LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNDgsMjMuOSwyMDE1LTAxLTA0LGZhY2Vib29rLE1leGljbwoxNTk1LEtJTFdaWUhSU0pFRzMxNixLSUxXWllIUlNKRUczMTYteTc4MjRlbmQsMjAxNS0wMS0xOFQwODozODo0Mi4wMDAwMDArMDAwMCwyMDE1LTAxLTE4VDA4OjM5OjEyLjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDk5LDI2LjUsMjAxNS0wMS0wNCxvcmdhbmljLERlbm1hcmsKMTU5OSxSTU9TV0hKR0VMQ0k2NzUsUk1PU1dISkdFTENJNjc1LTh2ZzloNmxtLDIwMTUtMDEtMThUMDg6NTY6MTguMDAwMDAwKzAwMDAsMjAxNS0wMS0xOFQwODo1Njo1NC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDksMzEuOSwyMDE1LTAxLTEwLG90aGVyX2NhbXBhaWduLEZyYW5jZQoxNjA0LERMVEZWUVdZSVhSSjU4OSxETFRGVlFXWUlYUko1ODktNmdqaHl2ZDcsMjAxNS0wMS0xOFQwOTowMDozNi4wMDAwMDArMDAwMCwyMDE1LTAxLTE4VDA5OjEzOjI0LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNzcsMzcuNSwyMDE1LTAxLTEzLG9yZ2FuaWMsU291dGggQWZyaWNhCjE2MDYsRExURlZRV1lJWFJKNTg5LERMVEZWUVdZSVhSSjU4OS02Z2poeXZkNywyMDE1LTAxLTE4VDA5OjAwOjM2LjAwMDAwMCswMDAwLDIwMTUtMDEtMThUMDk6Mzc6MDAuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA3NywzNy41LDIwMTUtMDEtMTMsb3JnYW5pYyxTb3V0aCBBZnJpY2EKMTYwOCxKWUVCQ0xOVVpUWFE0NTcsSllFQkNMTlVaVFhRNDU3LWo3c252bzhpLDIwMTUtMDEtMThUMDk6MTM6MDIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOFQwOToxOTowOC4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjA3LDE4LjgsMjAxNS0wMS0wNCxvdGhlcl9jYW1wYWlnbixFZ3lwdAoxNjA5LEpZRUJDTE5VWlRYUTQ1NyxKWUVCQ0xOVVpUWFE0NTctajdzbnZvOGksMjAxNS0wMS0xOFQwOToxMzowMi4wMDAwMDArMDAwMCwyMDE1LTAxLTE4VDA5OjIzOjU2LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNDUsMTguOCwyMDE1LTAxLTA0LG90aGVyX2NhbXBhaWduLEVneXB0CjE2MTAsSllFQkNMTlVaVFhRNDU3LEpZRUJDTE5VWlRYUTQ1Ny1qN3Nudm84aSwyMDE1LTAxLTE4VDA5OjEzOjAyLjAwMDAwMCswMDAwLDIwMTUtMDEtMThUMDk6Mjg6MzIuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAzNSwxOC44LDIwMTUtMDEtMDQsb3RoZXJfY2FtcGFpZ24sRWd5cHQKMTYyNSxNVENJV0tPVkFTWVA5MjUsTVRDSVdLT1ZBU1lQOTI1LXBjbjhrdDJtLDIwMTUtMDEtMThUMTE6MTQ6MjkuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOFQxMToyMDoxMS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDgsMjUuOSwyMDE1LTAxLTE0LG9yZ2FuaWMsR2VybWFueQoxNjI4LE1UQ0lXS09WQVNZUDkyNSxNVENJV0tPVkFTWVA5MjUtcGNuOGt0Mm0sMjAxNS0wMS0xOFQxMToxNDoyOS4wMDAwMDArMDAwMCwyMDE1LTAxLTE4VDExOjM2OjIzLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNiwyNS45LDIwMTUtMDEtMTQsb3JnYW5pYyxHZXJtYW55CjE2MzQsWkdFVlFKU0tGSUJYMzk4LFpHRVZRSlNLRklCWDM5OC0ycndoMXB2NiwyMDE1LTAxLTE4VDEzOjMzOjMxLjAwMDAwMCswMDAwLDIwMTUtMDEtMThUMTM6NTI6MDEuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA2MywzMC43LDIwMTUtMDEtMTcsb3JnYW5pYyxTb3V0aCBLb3JlYQoxNjM1LFpHRVZRSlNLRklCWDM5OCxaR0VWUUpTS0ZJQlgzOTgtMnJ3aDFwdjYsMjAxNS0wMS0xOFQxMzozMzozMS4wMDAwMDArMDAwMCwyMDE1LTAxLTE4VDEzOjU4OjU1LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMjgsMzAuNywyMDE1LTAxLTE3LG9yZ2FuaWMsU291dGggS29yZWEKMTY0MSxaTUpMUEdDUklLTkE0NzEsWk1KTFBHQ1JJS05BNDcxLW56anViZmdyLDIwMTUtMDEtMThUMTM6NTU6MTAuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOFQxMzo1OToyOC4wMDAwMDArMDAwMCxhZCxhZF8xNXNlYywwLjA4NCw2LjIsMjAxNS0wMS0xMCxvcmdhbmljLEVneXB0CjE2NDQsRkdLWFBOSVJKSENZNjI1LEZHS1hQTklSSkhDWTYyNS1vZ3VmcmFpaiwyMDE1LTAxLTE4VDEzOjU5OjM0LjAwMDAwMCswMDAwLDIwMTUtMDEtMThUMTQ6MTE6NDAuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAzNCwzMi4xLDIwMTUtMDEtMTcsY3Jvc3Nwcm9tbyxIb25nIEtvbmcKMTY1MSxHSkNYTlRXRUJJUFEzNjksR0pDWE5UV0VCSVBRMzY5LXlibmFjcTM0LDIwMTUtMDEtMThUMTQ6MzQ6MDQuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOFQxNDo1ODoyMi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDMsMjkuNiwyMDE1LTAxLTE0LG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwoxNjU1LFJZWkhBSkVYTUJJRjcyNCxSWVpIQUpFWE1CSUY3MjQtcTFqOGNmb3UsMjAxNS0wMS0xOFQxNToxNzozNy4wMDAwMDArMDAwMCwyMDE1LTAxLTE4VDE1OjI5OjQ5LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMzYsMTUuMiwyMDE1LTAxLTE1LGdvb2dsZSxQb3J0dWdhbAoxNjU2LFJZWkhBSkVYTUJJRjcyNCxSWVpIQUpFWE1CSUY3MjQtcTFqOGNmb3UsMjAxNS0wMS0xOFQxNToxNzozNy4wMDAwMDArMDAwMCwyMDE1LTAxLTE4VDE1OjMyOjM3LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wODEsMTUuMiwyMDE1LTAxLTE1LGdvb2dsZSxQb3J0dWdhbAoxNjU5LEVLSUhYQlJGR09DRDU3MSxFS0lIWEJSRkdPQ0Q1NzEtZHZxZ3htNTYsMjAxNS0wMS0xOFQxNToyOToyMi4wMDAwMDArMDAwMCwyMDE1LTAxLTE4VDE1OjM2OjE2LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNSwzNS45LDIwMTUtMDEtMTcsYXBwbGUsVW5pdGVkIEtpbmdkb20KMTY2NCxQTFFFU0JOR1VES0oxNTQsUExRRVNCTkdVREtKMTU0LTNscTZpN29mLDIwMTUtMDEtMThUMTU6NDY6NDEuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOFQxNTo1MToxMS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDQ4LDM1LjIsMjAxNS0wMS0xMixmYWNlYm9vayxKYXBhbgoxNjY4LEhEU0FNUFRPTEJXQzQzOCxIRFNBTVBUT0xCV0M0MzgtZWJhNjI5eHQsMjAxNS0wMS0xOFQxNzozMDoyNi4wMDAwMDArMDAwMCwyMDE1LTAxLTE4VDE3OjM1OjUwLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wODQsMTYuNiwyMDE1LTAxLTE0LG9yZ2FuaWMsU3dpdHplcmxhbmQKMTY3OCxNVENJV0tPVkFTWVA5MjUsTVRDSVdLT1ZBU1lQOTI1LW45Z2xiaDI3LDIwMTUtMDEtMThUMjA6MTA6NDIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOFQyMDoyMDoyNC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMSwyMC42LDIwMTUtMDEtMTQsb3JnYW5pYyxHZXJtYW55CjE2NzksTVRDSVdLT1ZBU1lQOTI1LE1UQ0lXS09WQVNZUDkyNS1uOWdsYmgyNywyMDE1LTAxLTE4VDIwOjEwOjQyLjAwMDAwMCswMDAwLDIwMTUtMDEtMThUMjA6MzA6MDYuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA5LDIwLjYsMjAxNS0wMS0xNCxvcmdhbmljLEdlcm1hbnkKMTY4MSxNVENJV0tPVkFTWVA5MjUsTVRDSVdLT1ZBU1lQOTI1LW45Z2xiaDI3LDIwMTUtMDEtMThUMjA6MTA6NDIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOFQyMDozMDozMC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDIsMjAuNiwyMDE1LTAxLTE0LG9yZ2FuaWMsR2VybWFueQoxNjg2LFhJQUhCTktFQ0dSTzU5OCxYSUFIQk5LRUNHUk81OTgtZXlndHdwbTcsMjAxNS0wMS0xOFQyMjoxNzo1NC4wMDAwMDArMDAwMCwyMDE1LTAxLTE4VDIyOjIzOjM2LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNDUsMzYuMiwyMDE1LTAxLTE0LGdvb2dsZSxFZ3lwdAoxNjg5LE1UQ0lXS09WQVNZUDkyNSxNVENJV0tPVkFTWVA5MjUtOHJwemQ2bXcsMjAxNS0wMS0xOFQyMzozNDo0MS4wMDAwMDArMDAwMCwyMDE1LTAxLTE4VDIzOjM0OjUzLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wOCwyOS42LDIwMTUtMDEtMTQsb3JnYW5pYyxHZXJtYW55CjE2OTEsTVRDSVdLT1ZBU1lQOTI1LE1UQ0lXS09WQVNZUDkyNS04cnB6ZDZtdywyMDE1LTAxLTE4VDIzOjM0OjQxLjAwMDAwMCswMDAwLDIwMTUtMDEtMTlUMDA6MDM6NDcuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyLDI5LjYsMjAxNS0wMS0xNCxvcmdhbmljLEdlcm1hbnkKMTcwMCxRRFVaSklFVENBR1c2NTQsUURVWkpJRVRDQUdXNjU0LWZrNnhtOXV6LDIwMTUtMDEtMThUMjM6NDk6MDcuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOVQwMDowOTowMS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDQ4LDIxLjcsMjAxNS0wMS0wNyxmYWNlYm9vayxTd2l0emVybGFuZAoxNzA1LFdFUEtZTlJYREZVVDU3MixXRVBLWU5SWERGVVQ1NzItajNhdnVsNzUsMjAxNS0wMS0xOVQwMDozNzoyNy4wMDAwMDArMDAwMCwyMDE1LTAxLTE5VDAwOjQxOjAzLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMTIsMjkuOSwyMDE1LTAxLTEzLGNyb3NzcHJvbW8sQ2hpbmEKMTcwNixXRVBLWU5SWERGVVQ1NzIsV0VQS1lOUlhERlVUNTcyLWozYXZ1bDc1LDIwMTUtMDEtMTlUMDA6Mzc6MjcuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOVQwMDo0Mjo0NS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDEyLDI5LjksMjAxNS0wMS0xMyxjcm9zc3Byb21vLENoaW5hCjE3MDgsV0VQS1lOUlhERlVUNTcyLFdFUEtZTlJYREZVVDU3Mi1qM2F2dWw3NSwyMDE1LTAxLTE5VDAwOjM3OjI3LjAwMDAwMCswMDAwLDIwMTUtMDEtMTlUMDA6NDk6MDkuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA0OCwyOS45LDIwMTUtMDEtMTMsY3Jvc3Nwcm9tbyxDaGluYQoxNzEwLFhJQUhCTktFQ0dSTzU5OCxYSUFIQk5LRUNHUk81OTgteWlsc3hmNXAsMjAxNS0wMS0xOVQwMDo1MjozMi4wMDAwMDArMDAwMCwyMDE1LTAxLTE5VDAwOjU2OjAyLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNSwzMC40LDIwMTUtMDEtMTQsZ29vZ2xlLEVneXB0CjE3MTEsWElBSEJOS0VDR1JPNTk4LFhJQUhCTktFQ0dSTzU5OC15aWxzeGY1cCwyMDE1LTAxLTE5VDAwOjUyOjMyLjAwMDAwMCswMDAwLDIwMTUtMDEtMTlUMDE6MDI6MjAuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA0LDMwLjQsMjAxNS0wMS0xNCxnb29nbGUsRWd5cHQKMTcxMixYSUFIQk5LRUNHUk81OTgsWElBSEJOS0VDR1JPNTk4LXlpbHN4ZjVwLDIwMTUtMDEtMTlUMDA6NTI6MzIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOVQwMTowNDowOC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDE1LDMwLjQsMjAxNS0wMS0xNCxnb29nbGUsRWd5cHQKMTcxMyxYSUFIQk5LRUNHUk81OTgsWElBSEJOS0VDR1JPNTk4LXlpbHN4ZjVwLDIwMTUtMDEtMTlUMDA6NTI6MzIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOVQwMTowNTowOC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDE1LDMwLjQsMjAxNS0wMS0xNCxnb29nbGUsRWd5cHQKMTcxNixRSkdWT0JMQVRJSFc0NTcsUUpHVk9CTEFUSUhXNDU3LWNtZWxhNHo4LDIwMTUtMDEtMTlUMDE6MTE6NDEuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOVQwMToyMToxMS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDQ0LDQwLjksMjAxNS0wMS0wMixvdGhlcl9jYW1wYWlnbixTd2VkZW4KMTcxOSxHQVlJQkxVQ09FREo3MzIsR0FZSUJMVUNPRURKNzMyLTEzOHo3Z3ByLDIwMTUtMDEtMTlUMDE6Mjc6NDQuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOVQwMTozMDo1Ni4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDcsMzAuOCwyMDE1LTAxLTAzLG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwoxNzIwLEdBWUlCTFVDT0VESjczMixHQVlJQkxVQ09FREo3MzItMTM4ejdncHIsMjAxNS0wMS0xOVQwMToyNzo0NC4wMDAwMDArMDAwMCwyMDE1LTAxLTE5VDAxOjMxOjA4LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMywzMC44LDIwMTUtMDEtMDMsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjE3MjYsWElBSEJOS0VDR1JPNTk4LFhJQUhCTktFQ0dSTzU5OC0zN2Vvc3poOCwyMDE1LTAxLTE5VDAzOjE3OjAzLjAwMDAwMCswMDAwLDIwMTUtMDEtMTlUMDM6MjU6NDUuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA0NSwzOS45LDIwMTUtMDEtMTQsZ29vZ2xlLEVneXB0CjE3MjgsWElBSEJOS0VDR1JPNTk4LFhJQUhCTktFQ0dSTzU5OC0zN2Vvc3poOCwyMDE1LTAxLTE5VDAzOjE3OjAzLjAwMDAwMCswMDAwLDIwMTUtMDEtMTlUMDM6Mjk6MzMuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAzNSwzOS45LDIwMTUtMDEtMTQsZ29vZ2xlLEVneXB0CjE3MzcsTVRDSVdLT1ZBU1lQOTI1LE1UQ0lXS09WQVNZUDkyNS1lcWJjdnlndCwyMDE1LTAxLTE5VDA0OjM4OjU0LjAwMDAwMCswMDAwLDIwMTUtMDEtMTlUMDQ6Mzk6MTIuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyLDkuNCwyMDE1LTAxLTE0LG9yZ2FuaWMsR2VybWFueQoxNzQyLEZHS1hQTklSSkhDWTYyNSxGR0tYUE5JUkpIQ1k2MjUtMmQxOG80aWosMjAxNS0wMS0xOVQwNTowMDo1Ni4wMDAwMDArMDAwMCwyMDE1LTAxLTE5VDA1OjEwOjMyLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNDIsMTEuMywyMDE1LTAxLTE3LGNyb3NzcHJvbW8sSG9uZyBLb25nCg==" download="extract_0002.csv"><button style="background-color: #67C2DC; color: #FFFFFF; border: none; padding: 5px; font-weight: bold; cursor: pointer; border-radius: 4px;">CSV</button></a></td>
  </tr>
  <tr>
    <td style="height: 40px; background-color: #FF3300; color: transparent;font-size: 0px;" class="gt_row gt_left">#FF3300</td>
    <td style="height: 40px; color: #666666;font-size: 13px;font-weight: bold;" class="gt_row gt_right">3</td>
    <td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_left">
        <div style="margin: 0; padding: 0; display: inline-block; height: 30px; vertical-align: middle; width: 16%;">
            <!--?xml version="1.0" encoding="UTF-8"?--><?xml version="1.0" encoding="UTF-8"?>
<svg width="30px" height="30px" viewBox="0 0 67 67" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="background: #FFFFFF;">
    <title>col_vals_gt</title>
    <g id="Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="col_vals_gt" transform="translate(1.500000, 1.500000)" fill-rule="nonzero">
            <path d="M55,0 C57.4852813,0 59.7352813,1.00735931 61.363961,2.63603897 C62.9926407,4.26471863 64,6.51471863 64,9 L64,9 L64,64 L9,64 C6.51471862,64 4.26471862,62.9926407 2.63603897,61.363961 C1.00735931,59.7352814 0,57.4852814 0,55 L0,55 L0,9 C0,6.51471863 1.00735931,4.26471863 2.63603897,2.63603897 C4.26471862,1.00735931 6.51471862,0 9,0 L9,0 L55,0 Z" id="rectangle" stroke="#000000" stroke-width="2" fill="#FFFFFF"></path>
            <path d="M48.7619048,10 L15.2380953,10 C12.3466667,10 10,12.3466667 10,15.2380952 L10,48.7619048 C10,51.6533333 12.3466667,54 15.2380953,54 L48.7619048,54 C51.6533333,54 54,51.6533333 54,48.7619048 L54,15.2380952 C54,12.3466667 51.6533333,10 48.7619048,10 Z M25.2638095,44.3828571 L24.0695238,42.6647619 L39.5847619,32 L24.0695238,21.3352381 L25.2638095,19.6171429 L43.2828572,32 L25.2638095,44.3828571 Z" id="greater_than" fill="#000000"></path>
        </g>
    </g>
</svg>
        </div>
        <div style="font-family: 'IBM Plex Mono', monospace, courier; color: black; font-size: 11px; display: inline-block; vertical-align: middle;">
            <div>col_vals_gt()</div>
        </div>
        <div style="font-size: 9px; font-family: 'IBM Plex Sans'; text-wrap: balance; margin-top: 3px;"><p style="font-size: inherit; margin: 0;">Expect that values in <code>session_duration</code> should be &gt; <code>15</code>.</p>
</div>
        </td>
    <td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">session_duration</td>
    <td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">15</td>
    <td style="height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;" class="gt_row gt_center"><svg width="25px" height="25px" viewBox="0 0 25 25" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="vertical-align: middle;">
    <g id="unchanged" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="unchanged" transform="translate(0.500000, 0.570147)">
            <rect id="Rectangle" x="0.125132506" y="0" width="23.749735" height="23.7894737"></rect>
            <path d="M5.80375046,8.18194736 C3.77191832,8.18194736 2.11875046,9.83495328 2.11875046,11.8669474 C2.11875046,13.8989414 3.77191832,15.5519474 5.80375046,15.5519474 C7.8355826,15.5519474 9.48875046,13.8989414 9.48875046,11.8669474 C9.48875046,9.83495328 7.83552863,8.18194736 5.80375046,8.18194736 Z M5.80375046,14.814915 C4.17821997,14.814915 2.85578285,13.4924778 2.85578285,11.8669474 C2.85578285,10.2414169 4.17821997,8.91897975 5.80375046,8.91897975 C7.42928095,8.91897975 8.75171807,10.2414169 8.75171807,11.8669474 C8.75171807,13.4924778 7.42928095,14.814915 5.80375046,14.814915 Z" id="Shape" fill="#000000" fill-rule="nonzero"></path>
            <path d="M13.9638189,8.699335 C13.9364621,8.70430925 13.9091059,8.71176968 13.8842359,8.71923074 C13.7822704,8.73663967 13.6877654,8.77643115 13.6056956,8.83860518 L10.2433156,11.3852598 C10.0766886,11.5046343 9.97720993,11.6986181 9.97720993,11.9025491 C9.97720993,12.1064807 10.0766886,12.3004639 10.2433156,12.4198383 L13.6056956,14.966493 C13.891697,15.1803725 14.2970729,15.1231721 14.5109517,14.8371707 C14.7248313,14.5511692 14.6676309,14.145794 14.3816294,13.9319145 L12.5313257,12.5392127 L21.8812495,12.5392127 L21.8812495,11.2658854 L12.5313257,11.2658854 L14.3816294,9.87318364 C14.6377872,9.71650453 14.7497006,9.40066014 14.6477351,9.11714553 C14.5482564,8.83363156 14.262255,8.65954352 13.9638189,8.699335 Z" id="arrow" fill="#000000" transform="translate(15.929230, 11.894737) rotate(-180.000000) translate(-15.929230, -11.894737) "></path>
        </g>
    </g>
</svg></td>
    <td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color:#4CA64C;">&check;</span></td>
    <td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_right">2000</td>
    <td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">1675<br />0.84</td>
    <td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">325<br />0.16</td>
    <td style="height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color: #AAAAAA;">&#9679;</span></td>
    <td style="height: 40px; background-color: #FCFCFC;" class="gt_row gt_center"><span style="color: #EBBC14;">&#9679;</span></td>
    <td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color: #FF3300;">&#9679;</span></td>
    <td style="height: 40px;" class="gt_row gt_center"><a href="data:text/csv;base64,X3Jvd19udW1fLHBsYXllcl9pZCxzZXNzaW9uX2lkLHNlc3Npb25fc3RhcnQsdGltZSxpdGVtX3R5cGUsaXRlbV9uYW1lLGl0ZW1fcmV2ZW51ZSxzZXNzaW9uX2R1cmF0aW9uLHN0YXJ0X2RheSxhY3F1aXNpdGlvbixjb3VudHJ5CjE1LENQWlZNR1dRU0lPSDEzMixDUFpWTUdXUVNJT0gxMzItZnlzOXg2MnYsMjAxNS0wMS0wMVQxNTo1MjoyNC4wMDAwMDArMDAwMCwyMDE1LTAxLTAxVDE1OjU5OjEyLjAwMDAwMCswMDAwLGlhcCxnb2xkMiwxLjU5LDEzLjgsMjAxNS0wMS0wMSxjcm9zc3Byb21vLFNvdXRoIEtvcmVhCjE2LENQWlZNR1dRU0lPSDEzMixDUFpWTUdXUVNJT0gxMzItZnlzOXg2MnYsMjAxNS0wMS0wMVQxNTo1MjoyNC4wMDAwMDArMDAwMCwyMDE1LTAxLTAxVDE2OjA2OjEyLjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDc3LDEzLjgsMjAxNS0wMS0wMSxjcm9zc3Byb21vLFNvdXRoIEtvcmVhCjE3LEZYV1VPUkdZTkpBRTI3MSxGWFdVT1JHWU5KQUUyNzEtN3djZGVhaXAsMjAxNS0wMS0wMVQyMjoxNzoyNy4wMDAwMDArMDAwMCwyMDE1LTAxLTAxVDIyOjE5OjAzLjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMTUsMTMuMSwyMDE1LTAxLTAxLG9yZ2FuaWMsQ2FuYWRhCjE4LEZYV1VPUkdZTkpBRTI3MSxGWFdVT1JHWU5KQUUyNzEtN3djZGVhaXAsMjAxNS0wMS0wMVQyMjoxNzoyNy4wMDAwMDArMDAwMCwyMDE1LTAxLTAxVDIyOjIyOjU3LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wOCwxMy4xLDIwMTUtMDEtMDEsb3JnYW5pYyxDYW5hZGEKMTksRlhXVU9SR1lOSkFFMjcxLEZYV1VPUkdZTkpBRTI3MS03d2NkZWFpcCwyMDE1LTAxLTAxVDIyOjE3OjI3LjAwMDAwMCswMDAwLDIwMTUtMDEtMDFUMjI6Mjc6NTEuMDAwMDAwKzAwMDAsaWFwLGdlbXM1LDkwLjk5LDEzLjEsMjAxNS0wMS0wMSxvcmdhbmljLENhbmFkYQo1OSxMU0dOQURKRkVLWUI5NTEsTFNHTkFESkZFS1lCOTUxLTFicmY1aGpjLDIwMTUtMDEtMDNUMDA6MDY6MzMuMDAwMDAwKzAwMDAsMjAxNS0wMS0wM1QwMDowOTowMy4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjE0Nyw1LjEsMjAxNS0wMS0wMyxvcmdhbmljLEhvbmcgS29uZwo2MCxDUFpWTUdXUVNJT0gxMzIsQ1BaVk1HV1FTSU9IMTMyLXJtMTM3YzhxLDIwMTUtMDEtMDNUMDA6NDg6MjYuMDAwMDAwKzAwMDAsMjAxNS0wMS0wM1QwMDo0ODozMi4wMDAwMDArMDAwMCxhZCxhZF8xNXNlYywwLjE1LDYuMywyMDE1LTAxLTAxLGNyb3NzcHJvbW8sU291dGggS29yZWEKNjQsR0FZSUJMVUNPRURKNzMyLEdBWUlCTFVDT0VESjczMi1jZHBsMjMxeiwyMDE1LTAxLTAzVDAzOjA2OjUyLjAwMDAwMCswMDAwLDIwMTUtMDEtMDNUMDM6MTA6MzQuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4xNCwxMy41LDIwMTUtMDEtMDMsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjY1LEdBWUlCTFVDT0VESjczMixHQVlJQkxVQ09FREo3MzItY2RwbDIzMXosMjAxNS0wMS0wM1QwMzowNjo1Mi4wMDAwMDArMDAwMCwyMDE1LTAxLTAzVDAzOjE1OjI4LjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMTcsMTMuNSwyMDE1LTAxLTAzLG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwo3MCxFQ1BBTk9JWExaSEY4OTYsRUNQQU5PSVhMWkhGODk2LWVvYndnbDRuLDIwMTUtMDEtMDNUMDY6MTE6MTAuMDAwMDAwKzAwMDAsMjAxNS0wMS0wM1QwNjoxNjoyOC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDcsMTAuNiwyMDE1LTAxLTAxLGdvb2dsZSxHZXJtYW55CjcxLEZLUkNIRUxZVFBCUTYzMSxGS1JDSEVMWVRQQlE2MzEtdTdoazJ3ZnAsMjAxNS0wMS0wM1QxMzozOTowMi4wMDAwMDArMDAwMCwyMDE1LTAxLTAzVDEzOjQzOjU2LjAwMDAwMCswMDAwLGlhcCxnb2xkMiwwLjc5LDYuOSwyMDE1LTAxLTAzLG9yZ2FuaWMsTWV4aWNvCjcyLFFKR1ZPQkxBVElIVzQ1NyxRSkdWT0JMQVRJSFc0NTcteXp2NHBkYXcsMjAxNS0wMS0wM1QxNDozMDoxNy4wMDAwMDArMDAwMCwyMDE1LTAxLTAzVDE0OjM0OjU5LjAwMDAwMCswMDAwLGlhcCxnZW1zMiw5Ljk5LDEyLjAsMjAxNS0wMS0wMixvdGhlcl9jYW1wYWlnbixTd2VkZW4KNzMsUUpHVk9CTEFUSUhXNDU3LFFKR1ZPQkxBVElIVzQ1Ny15enY0cGRhdywyMDE1LTAxLTAzVDE0OjMwOjE3LjAwMDAwMCswMDAwLDIwMTUtMDEtMDNUMTQ6MzU6NTkuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAzMywxMi4wLDIwMTUtMDEtMDIsb3RoZXJfY2FtcGFpZ24sU3dlZGVuCjc0LENQWlZNR1dRU0lPSDEzMixDUFpWTUdXUVNJT0gxMzItbHNxMWp2ZWYsMjAxNS0wMS0wM1QxODo0MzoxOC4wMDAwMDArMDAwMCwyMDE1LTAxLTAzVDE4OjQ3OjQ4LjAwMDAwMCswMDAwLGFkLGFkX3N1cnZleSwwLjg2OCw3LjcsMjAxNS0wMS0wMSxjcm9zc3Byb21vLFNvdXRoIEtvcmVhCjc1LEdBWUlCTFVDT0VESjczMixHQVlJQkxVQ09FREo3MzItaTl0Z24zYXEsMjAxNS0wMS0wM1QxODo0NjowOS4wMDAwMDArMDAwMCwyMDE1LTAxLTAzVDE4OjQ4OjE1LjAwMDAwMCswMDAwLGFkLGFkX3N1cnZleSwxLjUsOC41LDIwMTUtMDEtMDMsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjc2LEZLUkNIRUxZVFBCUTYzMSxGS1JDSEVMWVRQQlE2MzEtZzVqa3dhdXIsMjAxNS0wMS0wM1QyMTozNDo1MS4wMDAwMDArMDAwMCwyMDE1LTAxLTAzVDIxOjM4OjM5LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMywxMy45LDIwMTUtMDEtMDMsb3JnYW5pYyxNZXhpY28KMTEyLEVDUEFOT0lYTFpIRjg5NixFQ1BBTk9JWExaSEY4OTYtcmZscTcyaTMsMjAxNS0wMS0wNFQxODo0Mzo0Ni4wMDAwMDArMDAwMCwyMDE1LTAxLTA0VDE4OjQ4OjIyLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4xMSwxMS40LDIwMTUtMDEtMDEsZ29vZ2xlLEdlcm1hbnkKMTEzLEVDUEFOT0lYTFpIRjg5NixFQ1BBTk9JWExaSEY4OTYtcmZscTcyaTMsMjAxNS0wMS0wNFQxODo0Mzo0Ni4wMDAwMDArMDAwMCwyMDE1LTAxLTA0VDE4OjUxOjA0LjAwMDAwMCswMDAwLGlhcCxnb2xkNCwxNy45OSwxMS40LDIwMTUtMDEtMDEsZ29vZ2xlLEdlcm1hbnkKMTE4LFJLTU9WREpHRVNYWTEzNSxSS01PVkRKR0VTWFkxMzUtbHo5Z25vMnEsMjAxNS0wMS0wNFQyMDo1MjozMC4wMDAwMDArMDAwMCwyMDE1LTAxLTA0VDIwOjU0OjQyLjAwMDAwMCswMDAwLGFkLGFkXzIwc2VjLDAuNDA2LDYuNywyMDE1LTAxLTA0LGdvb2dsZSxTb3V0aCBLb3JlYQoxMTksUktNT1ZESkdFU1hZMTM1LFJLTU9WREpHRVNYWTEzNS1sejlnbm8ycSwyMDE1LTAxLTA0VDIwOjUyOjMwLjAwMDAwMCswMDAwLDIwMTUtMDEtMDRUMjA6NTQ6NTQuMDAwMDAwKzAwMDAsaWFwLG9mZmVyNSwyMy4xOSw2LjcsMjAxNS0wMS0wNCxnb29nbGUsU291dGggS29yZWEKMTI2LEdBWUlCTFVDT0VESjczMixHQVlJQkxVQ09FREo3MzItcDE2c2J2MmQsMjAxNS0wMS0wNVQwODo0MDo0MC4wMDAwMDArMDAwMCwyMDE1LTAxLTA1VDA4OjQzOjEwLjAwMDAwMCswMDAwLGlhcCxnZW1zMSwxLjc0LDEzLjksMjAxNS0wMS0wMyxvcmdhbmljLFVuaXRlZCBTdGF0ZXMKMTY4LEhLSlBPTVFXTFZESTY3NCxIS0pQT01RV0xWREk2NzQtNWZ4YjkxNnUsMjAxNS0wMS0wNlQxMToyNDowMS4wMDAwMDArMDAwMCwyMDE1LTAxLTA2VDExOjI1OjU1LjAwMDAwMCswMDAwLGlhcCxnb2xkMiwxLjU5LDYuNiwyMDE1LTAxLTA2LG90aGVyX2NhbXBhaWduLFNwYWluCjE3OSxES09BWEVMU0ZQV0M3MjMsREtPQVhFTFNGUFdDNzIzLWpjcmI5dHFtLDIwMTUtMDEtMDZUMTY6MzQ6MjUuMDAwMDAwKzAwMDAsMjAxNS0wMS0wNlQxNjozNDozNy4wMDAwMDArMDAwMCxhZCxhZF9zdXJ2ZXksMC42MywxMy42LDIwMTUtMDEtMDUsZmFjZWJvb2ssSmFwYW4KMTg4LEtJTFdaWUhSU0pFRzMxNixLSUxXWllIUlNKRUczMTYteTRlNXh1NmQsMjAxNS0wMS0wNlQyMDozNjozMi4wMDAwMDArMDAwMCwyMDE1LTAxLTA2VDIwOjM5OjAyLjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMjMxLDkuNCwyMDE1LTAxLTA0LG9yZ2FuaWMsRGVubWFyawoyMjUsUUpHVk9CTEFUSUhXNDU3LFFKR1ZPQkxBVElIVzQ1Ny1jMzE3YWx3aiwyMDE1LTAxLTA3VDA1OjUzOjM2LjAwMDAwMCswMDAwLDIwMTUtMDEtMDdUMDU6NTg6NDIuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA3NywxNC4yLDIwMTUtMDEtMDIsb3RoZXJfY2FtcGFpZ24sU3dlZGVuCjIyNixKVkJaQ1BLWEhGTVU0OTEsSlZCWkNQS1hIRk1VNDkxLTZ0cWY3NTkzLDIwMTUtMDEtMDdUMDY6NTU6NTMuMDAwMDAwKzAwMDAsMjAxNS0wMS0wN1QwNzowMjoxMS4wMDAwMDArMDAwMCxhZCxhZF8xNXNlYywwLjI5LDkuNywyMDE1LTAxLTA3LG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwoyMjcsSlZCWkNQS1hIRk1VNDkxLEpWQlpDUEtYSEZNVTQ5MS02dHFmNzU5MywyMDE1LTAxLTA3VDA2OjU1OjUzLjAwMDAwMCswMDAwLDIwMTUtMDEtMDdUMDc6MDM6NTkuMDAwMDAwKzAwMDAsaWFwLG9mZmVyNCwxMy45OSw5LjcsMjAxNS0wMS0wNyxvcmdhbmljLFVuaXRlZCBTdGF0ZXMKMjI4LEpWQlpDUEtYSEZNVTQ5MSxKVkJaQ1BLWEhGTVU0OTEtNnRxZjc1OTMsMjAxNS0wMS0wN1QwNjo1NTo1My4wMDAwMDArMDAwMCwyMDE1LTAxLTA3VDA3OjA1OjE3LjAwMDAwMCswMDAwLGlhcCxnZW1zMywxNy40OSw5LjcsMjAxNS0wMS0wNyxvcmdhbmljLFVuaXRlZCBTdGF0ZXMKMjc4LEhLSlBPTVFXTFZESTY3NCxIS0pQT01RV0xWREk2NzQtcHh5OTdqNmYsMjAxNS0wMS0wN1QxNTowMDo0My4wMDAwMDArMDAwMCwyMDE1LTAxLTA3VDE1OjA0OjM3LjAwMDAwMCswMDAwLGlhcCxvZmZlcjMsMTEuOTksNi44LDIwMTUtMDEtMDYsb3RoZXJfY2FtcGFpZ24sU3BhaW4KMjc5LEhLSlBPTVFXTFZESTY3NCxIS0pQT01RV0xWREk2NzQtcHh5OTdqNmYsMjAxNS0wMS0wN1QxNTowMDo0My4wMDAwMDArMDAwMCwyMDE1LTAxLTA3VDE1OjA3OjEzLjAwMDAwMCswMDAwLGFkLGFkXzE1c2VjLDAuMTM1LDYuOCwyMDE1LTAxLTA2LG90aGVyX2NhbXBhaWduLFNwYWluCjMyMixQWkJOUktTTVVMSFgyMTMsUFpCTlJLU01VTEhYMjEzLXNpeHU4bzZqLDIwMTUtMDEtMDhUMDA6MzY6MTMuMDAwMDAwKzAwMDAsMjAxNS0wMS0wOFQwMDozOTowNy4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDIsMTIuMCwyMDE1LTAxLTA3LG9yZ2FuaWMsSW5kaWEKMzIzLFBaQk5SS1NNVUxIWDIxMyxQWkJOUktTTVVMSFgyMTMtc2l4dThvNmosMjAxNS0wMS0wOFQwMDozNjoxMy4wMDAwMDArMDAwMCwyMDE1LTAxLTA4VDAwOjM5OjI1LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMjIsMTIuMCwyMDE1LTAxLTA3LG9yZ2FuaWMsSW5kaWEKMzI0LFBaQk5SS1NNVUxIWDIxMyxQWkJOUktTTVVMSFgyMTMtc2l4dThvNmosMjAxNS0wMS0wOFQwMDozNjoxMy4wMDAwMDArMDAwMCwyMDE1LTAxLTA4VDAwOjQ2OjAxLjAwMDAwMCswMDAwLGlhcCxnZW1zNSw1MS45OSwxMi4wLDIwMTUtMDEtMDcsb3JnYW5pYyxJbmRpYQozMjUsUFpCTlJLU01VTEhYMjEzLFBaQk5SS1NNVUxIWDIxMy1zaXh1OG82aiwyMDE1LTAxLTA4VDAwOjM2OjEzLjAwMDAwMCswMDAwLDIwMTUtMDEtMDhUMDA6NDg6MDEuMDAwMDAwKzAwMDAsaWFwLG9mZmVyNCw3Ljk5LDEyLjAsMjAxNS0wMS0wNyxvcmdhbmljLEluZGlhCjMzOCxQTUZIVk5DVUVZTFQ5MTMsUE1GSFZOQ1VFWUxUOTEzLXp4ZXlwYXNtLDIwMTUtMDEtMDhUMDU6MDk6MDQuMDAwMDAwKzAwMDAsMjAxNS0wMS0wOFQwNToxNjo0MC4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjA3LDkuOCwyMDE1LTAxLTA0LG9yZ2FuaWMsQXVzdHJpYQozNDEsTk1SVVdIQVlKUEJRODI0LE5NUlVXSEFZSlBCUTgyNC13dXQ4ZDZjMywyMDE1LTAxLTA4VDA3OjE3OjUzLjAwMDAwMCswMDAwLDIwMTUtMDEtMDhUMDc6MTk6MjkuMDAwMDAwKzAwMDAsYWQsYWRfMTVzZWMsMC4yNTksNS42LDIwMTUtMDEtMDgsb3JnYW5pYyxIb25nIEtvbmcKMzQyLFFKR1ZPQkxBVElIVzQ1NyxRSkdWT0JMQVRJSFc0NTctaXVrMWhwZzcsMjAxNS0wMS0wOFQwNzoyNzo1MC4wMDAwMDArMDAwMCwyMDE1LTAxLTA4VDA3OjMwOjM4LjAwMDAwMCswMDAwLGlhcCxvZmZlcjEsNC45OSw5LjYsMjAxNS0wMS0wMixvdGhlcl9jYW1wYWlnbixTd2VkZW4KMzQzLFFKR1ZPQkxBVElIVzQ1NyxRSkdWT0JMQVRJSFc0NTctaXVrMWhwZzcsMjAxNS0wMS0wOFQwNzoyNzo1MC4wMDAwMDArMDAwMCwyMDE1LTAxLTA4VDA3OjMyOjMyLjAwMDAwMCswMDAwLGFkLGFkXzE1c2VjLDAuMjY0LDkuNiwyMDE1LTAxLTAyLG90aGVyX2NhbXBhaWduLFN3ZWRlbgozNDQsSllFQkNMTlVaVFhRNDU3LEpZRUJDTE5VWlRYUTQ1Ny10am9ka2d4OCwyMDE1LTAxLTA4VDEwOjAwOjMyLjAwMDAwMCswMDAwLDIwMTUtMDEtMDhUMTA6MDY6NTAuMDAwMDAwKzAwMDAsYWQsYWRfMzBzZWMsMC4zOTYsMTEuMiwyMDE1LTAxLTA0LG90aGVyX2NhbXBhaWduLEVneXB0CjM0NSxKWUVCQ0xOVVpUWFE0NTcsSllFQkNMTlVaVFhRNDU3LXRqb2RrZ3g4LDIwMTUtMDEtMDhUMTA6MDA6MzIuMDAwMDAwKzAwMDAsMjAxNS0wMS0wOFQxMDoxMTozOC4wMDAwMDArMDAwMCxpYXAsZ2VtczIsNC45OSwxMS4yLDIwMTUtMDEtMDQsb3RoZXJfY2FtcGFpZ24sRWd5cHQKMzYxLEtCRVFaR0ZTUlBISjQ3OSxLQkVRWkdGU1JQSEo0NzktbTVpcHF3MmIsMjAxNS0wMS0wOFQxNTowNzo0NS4wMDAwMDArMDAwMCwyMDE1LTAxLTA4VDE1OjE1OjQ1LjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDMsOS4yLDIwMTUtMDEtMDcsb3JnYW5pYyxSdXNzaWEKMzY2LENOSVpZS1BIR1VMRjY1OSxDTklaWUtQSEdVTEY2NTktZHU4NGVyaWosMjAxNS0wMS0wOFQxNzozNzo0OS4wMDAwMDArMDAwMCwyMDE1LTAxLTA4VDE3OjM4OjEzLjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMiwxNS4wLDIwMTUtMDEtMDgsb3JnYW5pYyxDYW5hZGEKMzY3LENOSVpZS1BIR1VMRjY1OSxDTklaWUtQSEdVTEY2NTktZHU4NGVyaWosMjAxNS0wMS0wOFQxNzozNzo0OS4wMDAwMDArMDAwMCwyMDE1LTAxLTA4VDE3OjQ5OjE5LjAwMDAwMCswMDAwLGFkLGFkXzE1c2VjLDAuMiwxNS4wLDIwMTUtMDEtMDgsb3JnYW5pYyxDYW5hZGEKMzY4LENOSVpZS1BIR1VMRjY1OSxDTklaWUtQSEdVTEY2NTktZHU4NGVyaWosMjAxNS0wMS0wOFQxNzozNzo0OS4wMDAwMDArMDAwMCwyMDE1LTAxLTA4VDE3OjUxOjMxLjAwMDAwMCswMDAwLGFkLGFkXzE1c2VjLDAuMywxNS4wLDIwMTUtMDEtMDgsb3JnYW5pYyxDYW5hZGEKMzczLEhLSlBPTVFXTFZESTY3NCxIS0pQT01RV0xWREk2NzQtdmV4Z3FqcDYsMjAxNS0wMS0wOFQxOTowNjowMS4wMDAwMDArMDAwMCwyMDE1LTAxLTA4VDE5OjA4OjEzLjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMjA3LDEyLjksMjAxNS0wMS0wNixvdGhlcl9jYW1wYWlnbixTcGFpbgozODcsSEtKUE9NUVdMVkRJNjc0LEhLSlBPTVFXTFZESTY3NC1ybXh6aG9hYiwyMDE1LTAxLTA4VDIzOjI0OjIyLjAwMDAwMCswMDAwLDIwMTUtMDEtMDhUMjM6MjU6MzQuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4xNzEsMTAuMSwyMDE1LTAxLTA2LG90aGVyX2NhbXBhaWduLFNwYWluCjM4OCxIS0pQT01RV0xWREk2NzQsSEtKUE9NUVdMVkRJNjc0LXJteHpob2FiLDIwMTUtMDEtMDhUMjM6MjQ6MjIuMDAwMDAwKzAwMDAsMjAxNS0wMS0wOFQyMzoyNjozNC4wMDAwMDArMDAwMCxhZCxhZF8xNXNlYywwLjQzMiwxMC4xLDIwMTUtMDEtMDYsb3RoZXJfY2FtcGFpZ24sU3BhaW4KMzk5LFFEVVpKSUVUQ0FHVzY1NCxRRFVaSklFVENBR1c2NTQtZ21pNmJvZjEsMjAxNS0wMS0wOVQwMzowNDowNS4wMDAwMDArMDAwMCwyMDE1LTAxLTA5VDAzOjA1OjUzLjAwMDAwMCswMDAwLGFkLGFkXzE1c2VjLDAuNTUyLDExLjMsMjAxNS0wMS0wNyxmYWNlYm9vayxTd2l0emVybGFuZAo0MDAsUURVWkpJRVRDQUdXNjU0LFFEVVpKSUVUQ0FHVzY1NC1nbWk2Ym9mMSwyMDE1LTAxLTA5VDAzOjA0OjA1LjAwMDAwMCswMDAwLDIwMTUtMDEtMDlUMDM6MTA6MDUuMDAwMDAwKzAwMDAsaWFwLG9mZmVyMywxNi40ODksMTEuMywyMDE1LTAxLTA3LGZhY2Vib29rLFN3aXR6ZXJsYW5kCjQwMSxRRFVaSklFVENBR1c2NTQsUURVWkpJRVRDQUdXNjU0LWdtaTZib2YxLDIwMTUtMDEtMDlUMDM6MDQ6MDUuMDAwMDAwKzAwMDAsMjAxNS0wMS0wOVQwMzoxMDowNS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDYsMTEuMywyMDE1LTAxLTA3LGZhY2Vib29rLFN3aXR6ZXJsYW5kCjQwOCxPTUNWVUFJS1NEVFI2NTEsT01DVlVBSUtTRFRSNjUxLWhlc3p4eTJiLDIwMTUtMDEtMDlUMDU6NDQ6MjcuMDAwMDAwKzAwMDAsMjAxNS0wMS0wOVQwNTo0NjowMy4wMDAwMDArMDAwMCxpYXAsZ2VtczUsOTAuOTksNy4zLDIwMTUtMDEtMDcsb3RoZXJfY2FtcGFpZ24sVW5pdGVkIFN0YXRlcwo0MDksT01DVlVBSUtTRFRSNjUxLE9NQ1ZVQUlLU0RUUjY1MS1oZXN6eHkyYiwyMDE1LTAxLTA5VDA1OjQ0OjI3LjAwMDAwMCswMDAwLDIwMTUtMDEtMDlUMDU6NDg6NDUuMDAwMDAwKzAwMDAsaWFwLG9mZmVyMiw2Ljk5LDcuMywyMDE1LTAxLTA3LG90aGVyX2NhbXBhaWduLFVuaXRlZCBTdGF0ZXMKNDEwLEVRVUROR1pJQ01BSzQ4MixFUVVETkdaSUNNQUs0ODItbjRlamRndncsMjAxNS0wMS0wOVQwNzoxMTozNS4wMDAwMDArMDAwMCwyMDE1LTAxLTA5VDA3OjEyOjU5LjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMTksNi44LDIwMTUtMDEtMDQsZ29vZ2xlLEdlcm1hbnkKNDExLFFOTFZSREVPWEZZSjg5MixRTkxWUkRFT1hGWUo4OTItc2Y3d2VoejksMjAxNS0wMS0wOVQwNzoyNzoxNC4wMDAwMDArMDAwMCwyMDE1LTAxLTA5VDA3OjI5OjMyLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMyw4LjEsMjAxNS0wMS0wOSxjcm9zc3Byb21vLEF1c3RyYWxpYQo0MjksR0FZSUJMVUNPRURKNzMyLEdBWUlCTFVDT0VESjczMi1zeWlocWJubywyMDE1LTAxLTA5VDEzOjU1OjUyLjAwMDAwMCswMDAwLDIwMTUtMDEtMDlUMTM6NTc6MDQuMDAwMDAwKzAwMDAsaWFwLG9mZmVyNCwxMy45OSw1LjksMjAxNS0wMS0wMyxvcmdhbmljLFVuaXRlZCBTdGF0ZXMKNDMwLEdBWUlCTFVDT0VESjczMixHQVlJQkxVQ09FREo3MzItc3lpaHFibm8sMjAxNS0wMS0wOVQxMzo1NTo1Mi4wMDAwMDArMDAwMCwyMDE1LTAxLTA5VDEzOjU3OjUyLjAwMDAwMCswMDAwLGlhcCxvZmZlcjIsNi45OSw1LjksMjAxNS0wMS0wMyxvcmdhbmljLFVuaXRlZCBTdGF0ZXMKNDMxLEdBWUlCTFVDT0VESjczMixHQVlJQkxVQ09FREo3MzItc3lpaHFibm8sMjAxNS0wMS0wOVQxMzo1NTo1Mi4wMDAwMDArMDAwMCwyMDE1LTAxLTA5VDE0OjAxOjA0LjAwMDAwMCswMDAwLGFkLGFkXzMwc2VjLDAuOTgsNS45LDIwMTUtMDEtMDMsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjQzMixTRkpDWk9US0dBSUQ2NDUsU0ZKQ1pPVEtHQUlENjQ1LXE4MTZtNHpnLDIwMTUtMDEtMDlUMTQ6MDA6MjIuMDAwMDAwKzAwMDAsMjAxNS0wMS0wOVQxNDoxMjo0Ni4wMDAwMDArMDAwMCxpYXAsb2ZmZXI0LDE3Ljk5MSwxNC40LDIwMTUtMDEtMDYsZ29vZ2xlLEZyYW5jZQo0MzMsU0ZKQ1pPVEtHQUlENjQ1LFNGSkNaT1RLR0FJRDY0NS1xODE2bTR6ZywyMDE1LTAxLTA5VDE0OjAwOjIyLjAwMDAwMCswMDAwLDIwMTUtMDEtMDlUMTQ6MTM6MzQuMDAwMDAwKzAwMDAsYWQsYWRfMjBzZWMsMC45NSwxNC40LDIwMTUtMDEtMDYsZ29vZ2xlLEZyYW5jZQo0ODIsVVpRRkhEQkVNWVBWNTk0LFVaUUZIREJFTVlQVjU5NC1ha2NwenR1bywyMDE1LTAxLTEwVDA1OjQ4OjQ2LjAwMDAwMCswMDAwLDIwMTUtMDEtMTBUMDU6NDg6NTguMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA3Miw4LjEsMjAxNS0wMS0xMCxnb29nbGUsU3dpdHplcmxhbmQKNTA3LE5NUlVXSEFZSlBCUTgyNCxOTVJVV0hBWUpQQlE4MjQtejVpYjJvZmosMjAxNS0wMS0xMFQwOTo1NDoxNy4wMDAwMDArMDAwMCwyMDE1LTAxLTEwVDA5OjU1OjExLjAwMDAwMCswMDAwLGFkLGFkXzE1c2VjLDAuMjE3LDYuMCwyMDE1LTAxLTA4LG9yZ2FuaWMsSG9uZyBLb25nCjUyNSxFUVVETkdaSUNNQUs0ODIsRVFVRE5HWklDTUFLNDgyLWk1a3JnOW5mLDIwMTUtMDEtMTBUMTQ6MTI6MDkuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMFQxNDoxOTozOS4wMDAwMDArMDAwMCxpYXAsb2ZmZXIzLDEzLjQ5MSwxMC42LDIwMTUtMDEtMDQsZ29vZ2xlLEdlcm1hbnkKNTI2LEVRVUROR1pJQ01BSzQ4MixFUVVETkdaSUNNQUs0ODItaTVrcmc5bmYsMjAxNS0wMS0xMFQxNDoxMjowOS4wMDAwMDArMDAwMCwyMDE1LTAxLTEwVDE0OjIwOjA5LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMywxMC42LDIwMTUtMDEtMDQsZ29vZ2xlLEdlcm1hbnkKNTQ5LFFOTFZSREVPWEZZSjg5MixRTkxWUkRFT1hGWUo4OTItbHo1Zm1yNmssMjAxNS0wMS0xMFQxNjo0NDoxNy4wMDAwMDArMDAwMCwyMDE1LTAxLTEwVDE2OjQ1OjI5LjAwMDAwMCswMDAwLGlhcCxnb2xkMywzLjQ5LDMuNywyMDE1LTAxLTA5LGNyb3NzcHJvbW8sQXVzdHJhbGlhCjU2OSxLQkVRWkdGU1JQSEo0NzksS0JFUVpHRlNSUEhKNDc5LXJxZWdqbGYzLDIwMTUtMDEtMTBUMjA6MTg6NDcuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMFQyMDoyMDo0Ny4wMDAwMDArMDAwMCxhZCxhZF8xNXNlYywwLjEzNSwxMC41LDIwMTUtMDEtMDcsb3JnYW5pYyxSdXNzaWEKNTcwLEtCRVFaR0ZTUlBISjQ3OSxLQkVRWkdGU1JQSEo0NzktcnFlZ2psZjMsMjAxNS0wMS0xMFQyMDoxODo0Ny4wMDAwMDArMDAwMCwyMDE1LTAxLTEwVDIwOjIzOjQ3LjAwMDAwMCswMDAwLGlhcCxnb2xkMiwwLjc5NiwxMC41LDIwMTUtMDEtMDcsb3JnYW5pYyxSdXNzaWEKNTg1LFFEVVpKSUVUQ0FHVzY1NCxRRFVaSklFVENBR1c2NTQtY2ZvN3ZudGUsMjAxNS0wMS0xMVQwMDo1NzoxMy4wMDAwMDArMDAwMCwyMDE1LTAxLTExVDAxOjA1OjEzLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4xNDQsMTAuMywyMDE1LTAxLTA3LGZhY2Vib29rLFN3aXR6ZXJsYW5kCjU4NixRRFVaSklFVENBR1c2NTQsUURVWkpJRVRDQUdXNjU0LWNmbzd2bnRlLDIwMTUtMDEtMTFUMDA6NTc6MTMuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMVQwMTowNTozMS4wMDAwMDArMDAwMCxpYXAsZ2VtczEsMi43NCwxMC4zLDIwMTUtMDEtMDcsZmFjZWJvb2ssU3dpdHplcmxhbmQKNTkzLEdTUUpYSU9LWU1FQTcxMixHU1FKWElPS1lNRUE3MTItaTU3djRmYngsMjAxNS0wMS0xMVQwMzowODo0Ni4wMDAwMDArMDAwMCwyMDE1LTAxLTExVDAzOjEzOjIyLjAwMDAwMCswMDAwLGlhcCxnZW1zMSwyLjI0LDEwLjgsMjAxNS0wMS0wNyxnb29nbGUsR2VybWFueQo1OTQsR1NRSlhJT0tZTUVBNzEyLEdTUUpYSU9LWU1FQTcxMi1pNTd2NGZieCwyMDE1LTAxLTExVDAzOjA4OjQ2LjAwMDAwMCswMDAwLDIwMTUtMDEtMTFUMDM6MTY6MDQuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjExLDEwLjgsMjAxNS0wMS0wNyxnb29nbGUsR2VybWFueQo1OTUsR1NRSlhJT0tZTUVBNzEyLEdTUUpYSU9LWU1FQTcxMi1pNTd2NGZieCwyMDE1LTAxLTExVDAzOjA4OjQ2LjAwMDAwMCswMDAwLDIwMTUtMDEtMTFUMDM6MTc6MjIuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA4LDEwLjgsMjAxNS0wMS0wNyxnb29nbGUsR2VybWFueQo1OTksUUpHVk9CTEFUSUhXNDU3LFFKR1ZPQkxBVElIVzQ1Ny1yMWliNGV3YywyMDE1LTAxLTExVDAzOjQ1OjI3LjAwMDAwMCswMDAwLDIwMTUtMDEtMTFUMDM6NDk6MDMuMDAwMDAwKzAwMDAsYWQsYWRfMzBzZWMsMS4zMzEsNS43LDIwMTUtMDEtMDIsb3RoZXJfY2FtcGFpZ24sU3dlZGVuCjYxMSxSTU9TV0hKR0VMQ0k2NzUsUk1PU1dISkdFTENJNjc1LTh1bHdka3Z0LDIwMTUtMDEtMTFUMDY6MTU6MzYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMVQwNjoxNTo1NC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDIsOS40LDIwMTUtMDEtMTAsb3RoZXJfY2FtcGFpZ24sRnJhbmNlCjYxOCxKVkJaQ1BLWEhGTVU0OTEsSlZCWkNQS1hIRk1VNDkxLTF0YWVnNml5LDIwMTUtMDEtMTFUMDc6MDk6MzQuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMVQwNzoxNDoyMi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDIsNy45LDIwMTUtMDEtMDcsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjYxOSxKVkJaQ1BLWEhGTVU0OTEsSlZCWkNQS1hIRk1VNDkxLTF0YWVnNml5LDIwMTUtMDEtMTFUMDc6MDk6MzQuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMVQwNzoxNTo1Mi4wMDAwMDArMDAwMCxpYXAsb2ZmZXIxLDMuNDksNy45LDIwMTUtMDEtMDcsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjYyMCxSTU9TV0hKR0VMQ0k2NzUsUk1PU1dISkdFTENJNjc1LXQ0eThiamN1LDIwMTUtMDEtMTFUMDc6MjQ6MjQuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMVQwNzoyNToxOC4wMDAwMDArMDAwMCxpYXAsb2ZmZXI0LDE3Ljk5MSw1LjAsMjAxNS0wMS0xMCxvdGhlcl9jYW1wYWlnbixGcmFuY2UKNjIxLFJNT1NXSEpHRUxDSTY3NSxSTU9TV0hKR0VMQ0k2NzUtdDR5OGJqY3UsMjAxNS0wMS0xMVQwNzoyNDoyNC4wMDAwMDArMDAwMCwyMDE1LTAxLTExVDA3OjI2OjI0LjAwMDAwMCswMDAwLGlhcCxvZmZlcjUsMjYuMDksNS4wLDIwMTUtMDEtMTAsb3RoZXJfY2FtcGFpZ24sRnJhbmNlCjYyMixSTU9TV0hKR0VMQ0k2NzUsUk1PU1dISkdFTENJNjc1LXQ0eThiamN1LDIwMTUtMDEtMTFUMDc6MjQ6MjQuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMVQwNzoyODozNi4wMDAwMDArMDAwMCxhZCxhZF8xNXNlYywwLjUzLDUuMCwyMDE1LTAxLTEwLG90aGVyX2NhbXBhaWduLEZyYW5jZQo2MzQsQVVXRkRSWk1YVkpIOTI4LEFVV0ZEUlpNWFZKSDkyOC00bjZneHZlbywyMDE1LTAxLTExVDEwOjE3OjIyLjAwMDAwMCswMDAwLDIwMTUtMDEtMTFUMTA6MTg6NTguMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyLDEzLjYsMjAxNS0wMS0xMSxnb29nbGUsSW5kaWEKNjM1LEFVV0ZEUlpNWFZKSDkyOCxBVVdGRFJaTVhWSkg5MjgtNG42Z3h2ZW8sMjAxNS0wMS0xMVQxMDoxNzoyMi4wMDAwMDArMDAwMCwyMDE1LTAxLTExVDEwOjI3OjIyLjAwMDAwMCswMDAwLGlhcCxvZmZlcjUsMTEuNTksMTMuNiwyMDE1LTAxLTExLGdvb2dsZSxJbmRpYQo2NTcsS0JFUVpHRlNSUEhKNDc5LEtCRVFaR0ZTUlBISjQ3OS05cnA4aHRnMiwyMDE1LTAxLTExVDE0OjQ4OjA0LjAwMDAwMCswMDAwLDIwMTUtMDEtMTFUMTQ6NTE6NDYuMDAwMDAwKzAwMDAsYWQsYWRfMzBzZWMsMC40NDcsOS45LDIwMTUtMDEtMDcsb3JnYW5pYyxSdXNzaWEKNjYyLE5BT0pSRE1DU0VCSTI4MSxOQU9KUkRNQ1NFQkkyODEtZDRzYXk2cTUsMjAxNS0wMS0xMVQxNTo0Nzo0Ni4wMDAwMDArMDAwMCwyMDE1LTAxLTExVDE1OjU2OjE2LjAwMDAwMCswMDAwLGFkLGFkX3N1cnZleSwwLjksMTIuNCwyMDE1LTAxLTExLG9yZ2FuaWMsTm9yd2F5CjY2MyxHRkxZSkhBUE1aV0Q2MzEsR0ZMWUpIQVBNWldENjMxLWkydjFibDdhLDIwMTUtMDEtMTFUMTY6MTM6MjQuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMVQxNjoxNDo1NC4wMDAwMDArMDAwMCxpYXAsZ2VtczIsMy45OSwzLjYsMjAxNS0wMS0wOSxvcmdhbmljLEluZGlhCjY3NCxHRkxZSkhBUE1aV0Q2MzEsR0ZMWUpIQVBNWldENjMxLWtxN3RqbW9lLDIwMTUtMDEtMTFUMTg6MjM6MjIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMVQxODoyNDo0Ni4wMDAwMDArMDAwMCxpYXAsb2ZmZXI0LDcuOTksMTIuMiwyMDE1LTAxLTA5LG9yZ2FuaWMsSW5kaWEKNjc1LEdGTFlKSEFQTVpXRDYzMSxHRkxZSkhBUE1aV0Q2MzEta3E3dGptb2UsMjAxNS0wMS0xMVQxODoyMzoyMi4wMDAwMDArMDAwMCwyMDE1LTAxLTExVDE4OjI2OjQ2LjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDI2LDEyLjIsMjAxNS0wMS0wOSxvcmdhbmljLEluZGlhCjY3NixOQU9KUkRNQ1NFQkkyODEsTkFPSlJETUNTRUJJMjgxLWYzcWh1c3c5LDIwMTUtMDEtMTFUMTg6NDc6MzEuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMVQxODo0ODowMS4wMDAwMDArMDAwMCxhZCxhZF8zMHNlYywwLjk4MSw2LjksMjAxNS0wMS0xMSxvcmdhbmljLE5vcndheQo2NzcsSUNCQVVaS0dTUVBGMTQ1LElDQkFVWktHU1FQRjE0NS16dW8yajk1NCwyMDE1LTAxLTExVDE5OjA0OjM2LjAwMDAwMCswMDAwLDIwMTUtMDEtMTFUMTk6MTI6MjQuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA0OSw4LjEsMjAxNS0wMS0wNixnb29nbGUsU291dGggQWZyaWNhCjY3OCxHQVlJQkxVQ09FREo3MzIsR0FZSUJMVUNPRURKNzMyLXZwZ2N6bTlzLDIwMTUtMDEtMTFUMTk6MjM6MjQuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMVQxOToyNjoxOC4wMDAwMDArMDAwMCxhZCxhZF8xNXNlYywwLjI4LDEzLjcsMjAxNS0wMS0wMyxvcmdhbmljLFVuaXRlZCBTdGF0ZXMKNjc5LENOSVpZS1BIR1VMRjY1OSxDTklaWUtQSEdVTEY2NTktMWhyZ3hpYm0sMjAxNS0wMS0xMVQxOTozMzozNS4wMDAwMDArMDAwMCwyMDE1LTAxLTExVDE5OjM1OjM1LjAwMDAwMCswMDAwLGFkLGFkXzE1c2VjLDAuNSw3LjQsMjAxNS0wMS0wOCxvcmdhbmljLENhbmFkYQo2ODMsTVhDT1ZFWUlBS0ZINTk0LE1YQ09WRVlJQUtGSDU5NC02Z212dXg1NywyMDE1LTAxLTExVDIxOjA1OjM4LjAwMDAwMCswMDAwLDIwMTUtMDEtMTFUMjE6MDY6MDguMDAwMDAwKzAwMDAsYWQsYWRfcGxheWFibGUsMC43OTgsNy41LDIwMTUtMDEtMTAsb3JnYW5pYyxDaGluYQo2ODYsUk1PU1dISkdFTENJNjc1LFJNT1NXSEpHRUxDSTY3NS11cWc0bzdldiwyMDE1LTAxLTExVDIxOjM3OjI3LjAwMDAwMCswMDAwLDIwMTUtMDEtMTFUMjE6Mzk6MjEuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA5LDguMiwyMDE1LTAxLTEwLG90aGVyX2NhbXBhaWduLEZyYW5jZQo2OTgsR0ZMWUpIQVBNWldENjMxLEdGTFlKSEFQTVpXRDYzMS1wZDZqczE1bSwyMDE1LTAxLTExVDIzOjI4OjA5LjAwMDAwMCswMDAwLDIwMTUtMDEtMTFUMjM6MzE6NTEuMDAwMDAwKzAwMDAsYWQsYWRfMTVzZWMsMC4wNDIsOS4wLDIwMTUtMDEtMDksb3JnYW5pYyxJbmRpYQo3MDIsSElBTEJYRUdZWlJXNzM4LEhJQUxCWEVHWVpSVzczOC14Y3N5cGVvNywyMDE1LTAxLTEyVDAwOjM4OjQ3LjAwMDAwMCswMDAwLDIwMTUtMDEtMTJUMDA6NDI6NTkuMDAwMDAwKzAwMDAsaWFwLG9mZmVyNCw3Ljk5LDkuNSwyMDE1LTAxLTEyLG9yZ2FuaWMsQ2hpbmEKNzAzLEhJQUxCWEVHWVpSVzczOCxISUFMQlhFR1laUlc3MzgteGNzeXBlbzcsMjAxNS0wMS0xMlQwMDozODo0Ny4wMDAwMDArMDAwMCwyMDE1LTAxLTEyVDAwOjQ4OjExLjAwMDAwMCswMDAwLGlhcCxvZmZlcjQsNy45OSw5LjUsMjAxNS0wMS0xMixvcmdhbmljLENoaW5hCjcwNixKWUVCQ0xOVVpUWFE0NTcsSllFQkNMTlVaVFhRNDU3LXBtajhldmhzLDIwMTUtMDEtMTJUMDI6NDI6MzQuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMlQwMjo0NTo0MC4wMDAwMDArMDAwMCxhZCxhZF8yMHNlYywwLjI3LDExLjAsMjAxNS0wMS0wNCxvdGhlcl9jYW1wYWlnbixFZ3lwdAo3MjYsSUNCQVVaS0dTUVBGMTQ1LElDQkFVWktHU1FQRjE0NS1rdnVoM2N6cywyMDE1LTAxLTEyVDA4OjA0OjM2LjAwMDAwMCswMDAwLDIwMTUtMDEtMTJUMDg6MDU6MTguMDAwMDAwKzAwMDAsYWQsYWRfc3VydmV5LDEuMDIyLDEzLjksMjAxNS0wMS0wNixnb29nbGUsU291dGggQWZyaWNhCjcyNyxJQ0JBVVpLR1NRUEYxNDUsSUNCQVVaS0dTUVBGMTQ1LWt2dWgzY3pzLDIwMTUtMDEtMTJUMDg6MDQ6MzYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMlQwODoxMjoxOC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDg0OSwxMy45LDIwMTUtMDEtMDYsZ29vZ2xlLFNvdXRoIEFmcmljYQo3MjgsSUNCQVVaS0dTUVBGMTQ1LElDQkFVWktHU1FQRjE0NS1rdnVoM2N6cywyMDE1LTAxLTEyVDA4OjA0OjM2LjAwMDAwMCswMDAwLDIwMTUtMDEtMTJUMDg6MTY6NDIuMDAwMDAwKzAwMDAsaWFwLGdlbXMyLDYuOTksMTMuOSwyMDE1LTAxLTA2LGdvb2dsZSxTb3V0aCBBZnJpY2EKNzQyLFZMUUhZSkNLQk9JTjcyOSxWTFFIWUpDS0JPSU43MjktNXpydm94bnksMjAxNS0wMS0xMlQwODo0OTo0NS4wMDAwMDArMDAwMCwyMDE1LTAxLTEyVDA4OjU0OjM5LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMzYsMTEuMSwyMDE1LTAxLTEwLG9yZ2FuaWMsSmFwYW4KNzU1LFFOTFZSREVPWEZZSjg5MixRTkxWUkRFT1hGWUo4OTItZXNkYmF5OWgsMjAxNS0wMS0xMlQxMjoxNDoxNC4wMDAwMDArMDAwMCwyMDE1LTAxLTEyVDEyOjE4OjIwLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4xMSw4LjcsMjAxNS0wMS0wOSxjcm9zc3Byb21vLEF1c3RyYWxpYQo3NjMsR1NRSlhJT0tZTUVBNzEyLEdTUUpYSU9LWU1FQTcxMi03dzJiNWt5diwyMDE1LTAxLTEyVDE2OjI0OjA5LjAwMDAwMCswMDAwLDIwMTUtMDEtMTJUMTY6MzA6NTEuMDAwMDAwKzAwMDAsYWQsYWRfc3VydmV5LDAuNjksMTIuOSwyMDE1LTAxLTA3LGdvb2dsZSxHZXJtYW55Cjc2NCxHU1FKWElPS1lNRUE3MTIsR1NRSlhJT0tZTUVBNzEyLTd3MmI1a3l2LDIwMTUtMDEtMTJUMTY6MjQ6MDkuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMlQxNjozMzowOS4wMDAwMDArMDAwMCxhZCxhZF8xNXNlYywwLjQ1LDEyLjksMjAxNS0wMS0wNyxnb29nbGUsR2VybWFueQo3NjUsUURVWkpJRVRDQUdXNjU0LFFEVVpKSUVUQ0FHVzY1NC0ybWplb2JycCwyMDE1LTAxLTEyVDE2OjUzOjA4LjAwMDAwMCswMDAwLDIwMTUtMDEtMTJUMTY6NTc6MjYuMDAwMDAwKzAwMDAsaWFwLG9mZmVyNCwyMS45OSw3LjYsMjAxNS0wMS0wNyxmYWNlYm9vayxTd2l0emVybGFuZAo3NjYsUURVWkpJRVRDQUdXNjU0LFFEVVpKSUVUQ0FHVzY1NC0ybWplb2JycCwyMDE1LTAxLTEyVDE2OjUzOjA4LjAwMDAwMCswMDAwLDIwMTUtMDEtMTJUMTY6NTk6NTYuMDAwMDAwKzAwMDAsYWQsYWRfMTVzZWMsMC42Niw3LjYsMjAxNS0wMS0wNyxmYWNlYm9vayxTd2l0emVybGFuZAo3NjcsQVVXRkRSWk1YVkpIOTI4LEFVV0ZEUlpNWFZKSDkyOC13OWZoazNweiwyMDE1LTAxLTEyVDE3OjI3OjQ1LjAwMDAwMCswMDAwLDIwMTUtMDEtMTJUMTc6Mjk6MzkuMDAwMDAwKzAwMDAsaWFwLG9mZmVyNCw3Ljk5LDExLjUsMjAxNS0wMS0xMSxnb29nbGUsSW5kaWEKNzY4LEFVV0ZEUlpNWFZKSDkyOCxBVVdGRFJaTVhWSkg5MjgtdzlmaGszcHosMjAxNS0wMS0xMlQxNzoyNzo0NS4wMDAwMDArMDAwMCwyMDE1LTAxLTEyVDE3OjMwOjE1LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMDgsMTEuNSwyMDE1LTAxLTExLGdvb2dsZSxJbmRpYQo3NjksQVVXRkRSWk1YVkpIOTI4LEFVV0ZEUlpNWFZKSDkyOC13OWZoazNweiwyMDE1LTAxLTEyVDE3OjI3OjQ1LjAwMDAwMCswMDAwLDIwMTUtMDEtMTJUMTc6MzM6MzkuMDAwMDAwKzAwMDAsYWQsYWRfMTVzZWMsMC4wNzgsMTEuNSwyMDE1LTAxLTExLGdvb2dsZSxJbmRpYQo3NzAsQVVXRkRSWk1YVkpIOTI4LEFVV0ZEUlpNWFZKSDkyOC13OWZoazNweiwyMDE1LTAxLTEyVDE3OjI3OjQ1LjAwMDAwMCswMDAwLDIwMTUtMDEtMTJUMTc6MzY6NDUuMDAwMDAwKzAwMDAsaWFwLGdlbXMzLDkuOTksMTEuNSwyMDE1LTAxLTExLGdvb2dsZSxJbmRpYQo3NzEsRlhXRE5LSVVNSllSNDcxLEZYV0ROS0lVTUpZUjQ3MS1oOWdwY243bSwyMDE1LTAxLTEyVDE3OjM2OjA0LjAwMDAwMCswMDAwLDIwMTUtMDEtMTJUMTc6MzY6MjguMDAwMDAwKzAwMDAsYWQsYWRfc3VydmV5LDEuMzksNy44LDIwMTUtMDEtMTAsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjc3MixCRk5MVVJJU0pYVEg2NDcsQkZOTFVSSVNKWFRINjQ3LTZvNWh4Mjd6LDIwMTUtMDEtMTJUMTc6Mzc6MzkuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMlQxNzozOToyNy4wMDAwMDArMDAwMCxpYXAsb2ZmZXI1LDExLjU5LDQuMSwyMDE1LTAxLTEwLG9yZ2FuaWMsSW5kaWEKNzczLEJGTkxVUklTSlhUSDY0NyxCRk5MVVJJU0pYVEg2NDctNm81aHgyN3osMjAxNS0wMS0xMlQxNzozNzozOS4wMDAwMDArMDAwMCwyMDE1LTAxLTEyVDE3OjQxOjQ1LjAwMDAwMCswMDAwLGlhcCxnZW1zMyw5Ljk5LDQuMSwyMDE1LTAxLTEwLG9yZ2FuaWMsSW5kaWEKNzc0LENIS1VSQUJURlpERTM3MixDSEtVUkFCVEZaREUzNzItcXZ1dzQ5ZzYsMjAxNS0wMS0xMlQxODoxOTo0OS4wMDAwMDArMDAwMCwyMDE1LTAxLTEyVDE4OjIzOjAxLjAwMDAwMCswMDAwLGlhcCxnZW1zNCw2NS45OSwxNC44LDIwMTUtMDEtMTEsb3JnYW5pYyxEZW5tYXJrCjc3NSxDSEtVUkFCVEZaREUzNzIsQ0hLVVJBQlRGWkRFMzcyLXF2dXc0OWc2LDIwMTUtMDEtMTJUMTg6MTk6NDkuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMlQxODoyNjowNy4wMDAwMDArMDAwMCxpYXAsb2ZmZXI0LDIxLjk5LDE0LjgsMjAxNS0wMS0xMSxvcmdhbmljLERlbm1hcmsKNzc2LENIS1VSQUJURlpERTM3MixDSEtVUkFCVEZaREUzNzItcXZ1dzQ5ZzYsMjAxNS0wMS0xMlQxODoxOTo0OS4wMDAwMDArMDAwMCwyMDE1LTAxLTEyVDE4OjI4OjQ5LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wOTksMTQuOCwyMDE1LTAxLTExLG9yZ2FuaWMsRGVubWFyawo3ODEsS0daQ09KSFBGVFFWNzUzLEtHWkNPSkhQRlRRVjc1My15MWxzY2JtMiwyMDE1LTAxLTEyVDE5OjU1OjMxLjAwMDAwMCswMDAwLDIwMTUtMDEtMTJUMTk6NTc6NDMuMDAwMDAwKzAwMDAsYWQsYWRfMTVzZWMsMC4yNywxMS41LDIwMTUtMDEtMTEsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjc4MixLR1pDT0pIUEZUUVY3NTMsS0daQ09KSFBGVFFWNzUzLXkxbHNjYm0yLDIwMTUtMDEtMTJUMTk6NTU6MzEuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMlQyMDowNjoxOS4wMDAwMDArMDAwMCxhZCxhZF9zdXJ2ZXksMS4wMiwxMS41LDIwMTUtMDEtMTEsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjgyOCxLR1pDT0pIUEZUUVY3NTMsS0daQ09KSFBGVFFWNzUzLTFncXBhdWhvLDIwMTUtMDEtMTNUMDM6MjE6MjUuMDAwMDAwKzAwMDAsMjAxNS0wMS0xM1QwMzoyNzo0My4wMDAwMDArMDAwMCxhZCxhZF9zdXJ2ZXksMS4yOSwxNC40LDIwMTUtMDEtMTEsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjgyOSxLR1pDT0pIUEZUUVY3NTMsS0daQ09KSFBGVFFWNzUzLTFncXBhdWhvLDIwMTUtMDEtMTNUMDM6MjE6MjUuMDAwMDAwKzAwMDAsMjAxNS0wMS0xM1QwMzozMTo1NS4wMDAwMDArMDAwMCxhZCxhZF9zdXJ2ZXksMC44MSwxNC40LDIwMTUtMDEtMTEsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjgzNCxOQU9KUkRNQ1NFQkkyODEsTkFPSlJETUNTRUJJMjgxLWVoaTFuMjN2LDIwMTUtMDEtMTNUMDQ6NTg6MjAuMDAwMDAwKzAwMDAsMjAxNS0wMS0xM1QwNTowNToyNi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDgxLDE0LjIsMjAxNS0wMS0xMSxvcmdhbmljLE5vcndheQo4MzUsTkFPSlJETUNTRUJJMjgxLE5BT0pSRE1DU0VCSTI4MS1laGkxbjIzdiwyMDE1LTAxLTEzVDA0OjU4OjIwLjAwMDAwMCswMDAwLDIwMTUtMDEtMTNUMDU6MDc6MDIuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA5LDE0LjIsMjAxNS0wMS0xMSxvcmdhbmljLE5vcndheQo4NTAsV05WQkFZR0NMSklSNTE3LFdOVkJBWUdDTEpJUjUxNy1rN2Jtc2VxNSwyMDE1LTAxLTEzVDA4OjU0OjMxLjAwMDAwMCswMDAwLDIwMTUtMDEtMTNUMDg6NTQ6MzcuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4xODcsMTUuMCwyMDE1LTAxLTEzLGZhY2Vib29rLFN3ZWRlbgo4NTEsV05WQkFZR0NMSklSNTE3LFdOVkJBWUdDTEpJUjUxNy1rN2Jtc2VxNSwyMDE1LTAxLTEzVDA4OjU0OjMxLjAwMDAwMCswMDAwLDIwMTUtMDEtMTNUMDk6MDE6MDcuMDAwMDAwKzAwMDAsYWQsYWRfc3VydmV5LDEuNTE4LDE1LjAsMjAxNS0wMS0xMyxmYWNlYm9vayxTd2VkZW4KODYzLFVaUUZIREJFTVlQVjU5NCxVWlFGSERCRU1ZUFY1OTQtdjI5YnByNGksMjAxNS0wMS0xM1QxMDo1NTo0Mi4wMDAwMDArMDAwMCwyMDE1LTAxLTEzVDExOjA4OjA2LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNzIsMTMuOSwyMDE1LTAxLTEwLGdvb2dsZSxTd2l0emVybGFuZAo4NjUsSlVZQkZNUEVSTERXMzk0LEpVWUJGTVBFUkxEVzM5NC1xZXIzNW14aywyMDE1LTAxLTEzVDExOjQzOjIwLjAwMDAwMCswMDAwLDIwMTUtMDEtMTNUMTE6NDY6MjAuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4xOCwxNC4yLDIwMTUtMDEtMTMsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjg2NixKVVlCRk1QRVJMRFczOTQsSlVZQkZNUEVSTERXMzk0LXFlcjM1bXhrLDIwMTUtMDEtMTNUMTE6NDM6MjAuMDAwMDAwKzAwMDAsMjAxNS0wMS0xM1QxMTo1NjowOC4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjE5LDE0LjIsMjAxNS0wMS0xMyxvcmdhbmljLFVuaXRlZCBTdGF0ZXMKODg3LEdBWUlCTFVDT0VESjczMixHQVlJQkxVQ09FREo3MzItbWwyN3NoM3osMjAxNS0wMS0xM1QxNTo0NDo1Ny4wMDAwMDArMDAwMCwyMDE1LTAxLTEzVDE1OjQ3OjIxLjAwMDAwMCswMDAwLGFkLGFkXzMwc2VjLDAuNzksNi40LDIwMTUtMDEtMDMsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjg4OCxHQVlJQkxVQ09FREo3MzIsR0FZSUJMVUNPRURKNzMyLW1sMjdzaDN6LDIwMTUtMDEtMTNUMTU6NDQ6NTcuMDAwMDAwKzAwMDAsMjAxNS0wMS0xM1QxNTo0NzozMy4wMDAwMDArMDAwMCxpYXAsb2ZmZXI0LDEzLjk5LDYuNCwyMDE1LTAxLTAzLG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwo4ODksR0FZSUJMVUNPRURKNzMyLEdBWUlCTFVDT0VESjczMi1tbDI3c2gzeiwyMDE1LTAxLTEzVDE1OjQ0OjU3LjAwMDAwMCswMDAwLDIwMTUtMDEtMTNUMTU6NTA6MDkuMDAwMDAwKzAwMDAsaWFwLGdlbXMzLDE3LjQ5LDYuNCwyMDE1LTAxLTAzLG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwo5MDEsR1NRSlhJT0tZTUVBNzEyLEdTUUpYSU9LWU1FQTcxMi10OThhYzdvdSwyMDE1LTAxLTEzVDIwOjM1OjQ5LjAwMDAwMCswMDAwLDIwMTUtMDEtMTNUMjA6MzY6MjUuMDAwMDAwKzAwMDAsYWQsYWRfc3VydmV5LDEuMTksMTIuMiwyMDE1LTAxLTA3LGdvb2dsZSxHZXJtYW55CjkwMixHU1FKWElPS1lNRUE3MTIsR1NRSlhJT0tZTUVBNzEyLXQ5OGFjN291LDIwMTUtMDEtMTNUMjA6MzU6NDkuMDAwMDAwKzAwMDAsMjAxNS0wMS0xM1QyMDozODowMS4wMDAwMDArMDAwMCxhZCxhZF8xNXNlYywwLjM0OTcsMTIuMiwyMDE1LTAxLTA3LGdvb2dsZSxHZXJtYW55CjkwMyxHU1FKWElPS1lNRUE3MTIsR1NRSlhJT0tZTUVBNzEyLXQ5OGFjN291LDIwMTUtMDEtMTNUMjA6MzU6NDkuMDAwMDAwKzAwMDAsMjAxNS0wMS0xM1QyMDo0NjowMS4wMDAwMDArMDAwMCxpYXAsb2ZmZXI1LDI2LjA5LDEyLjIsMjAxNS0wMS0wNyxnb29nbGUsR2VybWFueQo5MDgsS0lMV1pZSFJTSkVHMzE2LEtJTFdaWUhSU0pFRzMxNi11a2U3ZGhxaiwyMDE1LTAxLTEzVDIyOjE2OjI5LjAwMDAwMCswMDAwLDIwMTUtMDEtMTNUMjI6MTc6MzUuMDAwMDAwKzAwMDAsaWFwLG9mZmVyMiwxMC45OSwzLjIsMjAxNS0wMS0wNCxvcmdhbmljLERlbm1hcmsKOTI3LEdTUUpYSU9LWU1FQTcxMixHU1FKWElPS1lNRUE3MTItOGY1MTRrZGMsMjAxNS0wMS0xNFQwMDo1OToxMC4wMDAwMDArMDAwMCwyMDE1LTAxLTE0VDAwOjU5OjQwLjAwMDAwMCswMDAwLGlhcCxnZW1zMSwyLjI0LDguNCwyMDE1LTAxLTA3LGdvb2dsZSxHZXJtYW55CjkyOCxHU1FKWElPS1lNRUE3MTIsR1NRSlhJT0tZTUVBNzEyLThmNTE0a2RjLDIwMTUtMDEtMTRUMDA6NTk6MTAuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNFQwMTowMDowNC4wMDAwMDArMDAwMCxhZCxhZF8zMHNlYywxLjE4LDguNCwyMDE1LTAxLTA3LGdvb2dsZSxHZXJtYW55CjkyOSxIRFNBTVBUT0xCV0M0MzgsSERTQU1QVE9MQldDNDM4LWFpNG02amNoLDIwMTUtMDEtMTRUMDE6MjY6NDQuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNFQwMTozMDo1MC4wMDAwMDArMDAwMCxpYXAsb2ZmZXIyLDEwLjk5LDYuNSwyMDE1LTAxLTE0LG9yZ2FuaWMsU3dpdHplcmxhbmQKOTMwLEhEU0FNUFRPTEJXQzQzOCxIRFNBTVBUT0xCV0M0MzgtYWk0bTZqY2gsMjAxNS0wMS0xNFQwMToyNjo0NC4wMDAwMDArMDAwMCwyMDE1LTAxLTE0VDAxOjMyOjAyLjAwMDAwMCswMDAwLGlhcCxnb2xkNiw2NS45OSw2LjUsMjAxNS0wMS0xNCxvcmdhbmljLFN3aXR6ZXJsYW5kCjkzMSxIRFNBTVBUT0xCV0M0MzgsSERTQU1QVE9MQldDNDM4LWFpNG02amNoLDIwMTUtMDEtMTRUMDE6MjY6NDQuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNFQwMTozMjowMi4wMDAwMDArMDAwMCxpYXAsZ29sZDIsMi4xOSw2LjUsMjAxNS0wMS0xNCxvcmdhbmljLFN3aXR6ZXJsYW5kCjk0MSxNVENJV0tPVkFTWVA5MjUsTVRDSVdLT1ZBU1lQOTI1LTR6cXVrNWZyLDIwMTUtMDEtMTRUMDI6NDU6MjAuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNFQwMjo0ODoyNi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMTEsMTEuNSwyMDE1LTAxLTE0LG9yZ2FuaWMsR2VybWFueQo5NDIsTVRDSVdLT1ZBU1lQOTI1LE1UQ0lXS09WQVNZUDkyNS00enF1azVmciwyMDE1LTAxLTE0VDAyOjQ1OjIwLjAwMDAwMCswMDAwLDIwMTUtMDEtMTRUMDI6NTM6MjYuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyLDExLjUsMjAxNS0wMS0xNCxvcmdhbmljLEdlcm1hbnkKOTQzLE1UQ0lXS09WQVNZUDkyNSxNVENJV0tPVkFTWVA5MjUtNHpxdWs1ZnIsMjAxNS0wMS0xNFQwMjo0NToyMC4wMDAwMDArMDAwMCwyMDE1LTAxLTE0VDAyOjU2OjUwLjAwMDAwMCswMDAwLGlhcCxnb2xkMiwxLjc5LDExLjUsMjAxNS0wMS0xNCxvcmdhbmljLEdlcm1hbnkKOTUwLEpZRUJDTE5VWlRYUTQ1NyxKWUVCQ0xOVVpUWFE0NTctYnRvdjZpdzQsMjAxNS0wMS0xNFQwMjo1MzozNy4wMDAwMDArMDAwMCwyMDE1LTAxLTE0VDAyOjU3OjE5LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMzUsOC44LDIwMTUtMDEtMDQsb3RoZXJfY2FtcGFpZ24sRWd5cHQKOTU3LFhJQUhCTktFQ0dSTzU5OCxYSUFIQk5LRUNHUk81OTgtamxoZG5zOGksMjAxNS0wMS0xNFQwNDozMjoxNS4wMDAwMDArMDAwMCwyMDE1LTAxLTE0VDA0OjM0OjMzLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMTUsMTQuMSwyMDE1LTAxLTE0LGdvb2dsZSxFZ3lwdAo5NTgsWElBSEJOS0VDR1JPNTk4LFhJQUhCTktFQ0dSTzU5OC1qbGhkbnM4aSwyMDE1LTAxLTE0VDA0OjMyOjE1LjAwMDAwMCswMDAwLDIwMTUtMDEtMTRUMDQ6NDQ6MDMuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4wNSwxNC4xLDIwMTUtMDEtMTQsZ29vZ2xlLEVneXB0Cjk2MyxJQ0JBVVpLR1NRUEYxNDUsSUNCQVVaS0dTUVBGMTQ1LTlldTd3emtxLDIwMTUtMDEtMTRUMDQ6MzY6NDEuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNFQwNDozNjo0Ny4wMDAwMDArMDAwMCxhZCxhZF9zdXJ2ZXksMC40NzYsMTMuOSwyMDE1LTAxLTA2LGdvb2dsZSxTb3V0aCBBZnJpY2EKOTY0LElDQkFVWktHU1FQRjE0NSxJQ0JBVVpLR1NRUEYxNDUtOWV1N3d6a3EsMjAxNS0wMS0xNFQwNDozNjo0MS4wMDAwMDArMDAwMCwyMDE1LTAxLTE0VDA0OjM3OjI5LjAwMDAwMCswMDAwLGFkLGFkXzMwc2VjLDAuNTUzLDEzLjksMjAxNS0wMS0wNixnb29nbGUsU291dGggQWZyaWNhCjk3MyxKVkJaQ1BLWEhGTVU0OTEsSlZCWkNQS1hIRk1VNDkxLXcxcTJsZXU5LDIwMTUtMDEtMTRUMDU6Mjg6NDYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNFQwNTozMToyOC4wMDAwMDArMDAwMCxpYXAsb2ZmZXI1LDIwLjI5LDUuMSwyMDE1LTAxLTA3LG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwo5NzQsSlZCWkNQS1hIRk1VNDkxLEpWQlpDUEtYSEZNVTQ5MS13MXEybGV1OSwyMDE1LTAxLTE0VDA1OjI4OjQ2LjAwMDAwMCswMDAwLDIwMTUtMDEtMTRUMDU6MzM6NDAuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA1LDUuMSwyMDE1LTAxLTA3LG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwo5ODEsVkxRSFlKQ0tCT0lONzI5LFZMUUhZSkNLQk9JTjcyOS0yN3BvZ21qdiwyMDE1LTAxLTE0VDA3OjA0OjMyLjAwMDAwMCswMDAwLDIwMTUtMDEtMTRUMDc6MDg6NTYuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAzLDkuMywyMDE1LTAxLTEwLG9yZ2FuaWMsSmFwYW4KMTAwNyxRTkxWUkRFT1hGWUo4OTIsUU5MVlJERU9YRllKODkyLTkzaGVscjV1LDIwMTUtMDEtMTRUMTE6MzE6NDYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNFQxMTozMzo0MC4wMDAwMDArMDAwMCxpYXAsZ2VtczQsNDEuOTksNi41LDIwMTUtMDEtMDksY3Jvc3Nwcm9tbyxBdXN0cmFsaWEKMTAwOCxRTkxWUkRFT1hGWUo4OTIsUU5MVlJERU9YRllKODkyLTkzaGVscjV1LDIwMTUtMDEtMTRUMTE6MzE6NDYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNFQxMTozNDoxMC4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjE1LDYuNSwyMDE1LTAxLTA5LGNyb3NzcHJvbW8sQXVzdHJhbGlhCjEwMTksUk1PU1dISkdFTENJNjc1LFJNT1NXSEpHRUxDSTY3NS1uMXk0cjZvOSwyMDE1LTAxLTE0VDE0OjQwOjQzLjAwMDAwMCswMDAwLDIwMTUtMDEtMTRUMTQ6NDE6MzcuMDAwMDAwKzAwMDAsaWFwLGdvbGQ1LDI2LjA5LDUuOSwyMDE1LTAxLTEwLG90aGVyX2NhbXBhaWduLEZyYW5jZQoxMDM3LEpVQkRWRkhDTlFXVDE5OCxKVUJEVkZIQ05RV1QxOTgtOWg0eHMycGIsMjAxNS0wMS0xNFQxNjowODoyNS4wMDAwMDArMDAwMCwyMDE1LTAxLTE0VDE2OjA4OjQzLjAwMDAwMCswMDAwLGlhcCxvZmZlcjUsOC42OSwzLjMsMjAxNS0wMS0xNCxvcmdhbmljLFBoaWxpcHBpbmVzCjEwMzgsSlVCRFZGSENOUVdUMTk4LEpVQkRWRkhDTlFXVDE5OC05aDR4czJwYiwyMDE1LTAxLTE0VDE2OjA4OjI1LjAwMDAwMCswMDAwLDIwMTUtMDEtMTRUMTY6MTE6MDEuMDAwMDAwKzAwMDAsaWFwLG9mZmVyNCw1Ljk5LDMuMywyMDE1LTAxLTE0LG9yZ2FuaWMsUGhpbGlwcGluZXMKMTA1MCxRTkxWUkRFT1hGWUo4OTIsUU5MVlJERU9YRllKODkyLWgzam9jbGdmLDIwMTUtMDEtMTRUMTg6MjE6MTguMDAwMDAwKzAwMDAsMjAxNS0wMS0xNFQxODoyNzowMC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDUsOS40LDIwMTUtMDEtMDksY3Jvc3Nwcm9tbyxBdXN0cmFsaWEKMTA1MSxQWkJOUktTTVVMSFgyMTMsUFpCTlJLU01VTEhYMjEzLWZ4b2liam5sLDIwMTUtMDEtMTRUMTg6MzM6NTYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNFQxODozNDoyNi4wMDAwMDArMDAwMCxpYXAsZ29sZDYsMjMuOTksMTMuMywyMDE1LTAxLTA3LG9yZ2FuaWMsSW5kaWEKMTA1MixQWkJOUktTTVVMSFgyMTMsUFpCTlJLU01VTEhYMjEzLWZ4b2liam5sLDIwMTUtMDEtMTRUMTg6MzM6NTYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNFQxODozODo0NC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDEsMTMuMywyMDE1LTAxLTA3LG9yZ2FuaWMsSW5kaWEKMTA1MyxQWkJOUktTTVVMSFgyMTMsUFpCTlJLU01VTEhYMjEzLWZ4b2liam5sLDIwMTUtMDEtMTRUMTg6MzM6NTYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNFQxODo0NToyNi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDA2LDEzLjMsMjAxNS0wMS0wNyxvcmdhbmljLEluZGlhCjEwNTcsUUpHVk9CTEFUSUhXNDU3LFFKR1ZPQkxBVElIVzQ1Ny16YmxlaG1pdywyMDE1LTAxLTE0VDE5OjQ3OjM0LjAwMDAwMCswMDAwLDIwMTUtMDEtMTRUMTk6NTI6MTAuMDAwMDAwKzAwMDAsaWFwLG9mZmVyNCwxOS45OSwxMi4wLDIwMTUtMDEtMDIsb3RoZXJfY2FtcGFpZ24sU3dlZGVuCjEwNTgsUUpHVk9CTEFUSUhXNDU3LFFKR1ZPQkxBVElIVzQ1Ny16YmxlaG1pdywyMDE1LTAxLTE0VDE5OjQ3OjM0LjAwMDAwMCswMDAwLDIwMTUtMDEtMTRUMTk6NTI6NTguMDAwMDAwKzAwMDAsYWQsYWRfMTVzZWMsMC40ODQsMTIuMCwyMDE1LTAxLTAyLG90aGVyX2NhbXBhaWduLFN3ZWRlbgoxMDU5LFFKR1ZPQkxBVElIVzQ1NyxRSkdWT0JMQVRJSFc0NTctemJsZWhtaXcsMjAxNS0wMS0xNFQxOTo0NzozNC4wMDAwMDArMDAwMCwyMDE1LTAxLTE0VDE5OjU0OjIyLjAwMDAwMCswMDAwLGlhcCxnZW1zMywyNC45OSwxMi4wLDIwMTUtMDEtMDIsb3RoZXJfY2FtcGFpZ24sU3dlZGVuCjEwODUsQ0hLVVJBQlRGWkRFMzcyLENIS1VSQUJURlpERTM3Mi02Y3B6YXhuaiwyMDE1LTAxLTE1VDAyOjM4OjA4LjAwMDAwMCswMDAwLDIwMTUtMDEtMTVUMDI6NDQ6MjYuMDAwMDAwKzAwMDAsaWFwLGdvbGQ3LDEzMS45OSw5LjcsMjAxNS0wMS0xMSxvcmdhbmljLERlbm1hcmsKMTA4NixDSEtVUkFCVEZaREUzNzIsQ0hLVVJBQlRGWkRFMzcyLTZjcHpheG5qLDIwMTUtMDEtMTVUMDI6Mzg6MDguMDAwMDAwKzAwMDAsMjAxNS0wMS0xNVQwMjo0NDo1Ni4wMDAwMDArMDAwMCxhZCxhZF8xNXNlYywwLjE4Nyw5LjcsMjAxNS0wMS0xMSxvcmdhbmljLERlbm1hcmsKMTA4NyxLR1pDT0pIUEZUUVY3NTMsS0daQ09KSFBGVFFWNzUzLWxkdW90cW5mLDIwMTUtMDEtMTVUMDI6NDU6NTguMDAwMDAwKzAwMDAsMjAxNS0wMS0xNVQwMjo0OToxNi4wMDAwMDArMDAwMCxpYXAsb2ZmZXIzLDEwLjQ5LDYuMiwyMDE1LTAxLTExLG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwoxMDg4LEtHWkNPSkhQRlRRVjc1MyxLR1pDT0pIUEZUUVY3NTMtbGR1b3RxbmYsMjAxNS0wMS0xNVQwMjo0NTo1OC4wMDAwMDArMDAwMCwyMDE1LTAxLTE1VDAyOjUxOjQwLjAwMDAwMCswMDAwLGlhcCxvZmZlcjMsMTAuNDksNi4yLDIwMTUtMDEtMTEsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjEwODksTkFPSlJETUNTRUJJMjgxLE5BT0pSRE1DU0VCSTI4MS1jNTFiZXBueSwyMDE1LTAxLTE1VDAyOjQ4OjE4LjAwMDAwMCswMDAwLDIwMTUtMDEtMTVUMDI6NTA6MzAuMDAwMDAwKzAwMDAsYWQsYWRfMjBzZWMsMC42MDMsMTEuMCwyMDE1LTAxLTExLG9yZ2FuaWMsTm9yd2F5CjEwOTAsTkFPSlJETUNTRUJJMjgxLE5BT0pSRE1DU0VCSTI4MS1jNTFiZXBueSwyMDE1LTAxLTE1VDAyOjQ4OjE4LjAwMDAwMCswMDAwLDIwMTUtMDEtMTVUMDI6NTE6MzAuMDAwMDAwKzAwMDAsaWFwLG9mZmVyMSw1LjQ5LDExLjAsMjAxNS0wMS0xMSxvcmdhbmljLE5vcndheQoxMDkxLE5BT0pSRE1DU0VCSTI4MSxOQU9KUkRNQ1NFQkkyODEtYzUxYmVwbnksMjAxNS0wMS0xNVQwMjo0ODoxOC4wMDAwMDArMDAwMCwyMDE1LTAxLTE1VDAyOjUyOjQ4LjAwMDAwMCswMDAwLGFkLGFkXzE1c2VjLDAuMjQzLDExLjAsMjAxNS0wMS0xMSxvcmdhbmljLE5vcndheQoxMDkyLFFKR1ZPQkxBVElIVzQ1NyxRSkdWT0JMQVRJSFc0NTctcGxtMzl5dGMsMjAxNS0wMS0xNVQwMjo1NjoxNi4wMDAwMDArMDAwMCwyMDE1LTAxLTE1VDAyOjU3OjEwLjAwMDAwMCswMDAwLGFkLGFkX3N1cnZleSwxLjEyMiwxMy44LDIwMTUtMDEtMDIsb3RoZXJfY2FtcGFpZ24sU3dlZGVuCjEwOTMsUUpHVk9CTEFUSUhXNDU3LFFKR1ZPQkxBVElIVzQ1Ny1wbG0zOXl0YywyMDE1LTAxLTE1VDAyOjU2OjE2LjAwMDAwMCswMDAwLDIwMTUtMDEtMTVUMDI6NTg6NTIuMDAwMDAwKzAwMDAsYWQsYWRfMTVzZWMsMC40NjIsMTMuOCwyMDE1LTAxLTAyLG90aGVyX2NhbXBhaWduLFN3ZWRlbgoxMDk0LFFKR1ZPQkxBVElIVzQ1NyxRSkdWT0JMQVRJSFc0NTctcGxtMzl5dGMsMjAxNS0wMS0xNVQwMjo1NjoxNi4wMDAwMDArMDAwMCwyMDE1LTAxLTE1VDAzOjAyOjQwLjAwMDAwMCswMDAwLGlhcCxnb2xkMSwwLjk5LDEzLjgsMjAxNS0wMS0wMixvdGhlcl9jYW1wYWlnbixTd2VkZW4KMTEwNSxCRk5MVVJJU0pYVEg2NDcsQkZOTFVSSVNKWFRINjQ3LWdzdmpiN3dlLDIwMTUtMDEtMTVUMDU6MDE6NTAuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNVQwNTowNTowMi4wMDAwMDArMDAwMCxpYXAsZ29sZDUsMTEuNTksMTMuNSwyMDE1LTAxLTEwLG9yZ2FuaWMsSW5kaWEKMTEwNixCRk5MVVJJU0pYVEg2NDcsQkZOTFVSSVNKWFRINjQ3LWdzdmpiN3dlLDIwMTUtMDEtMTVUMDU6MDE6NTAuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNVQwNTowODo0NC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDIyLDEzLjUsMjAxNS0wMS0xMCxvcmdhbmljLEluZGlhCjExMTAsRExURlZRV1lJWFJKNTg5LERMVEZWUVdZSVhSSjU4OS1ub2hmYWUzNywyMDE1LTAxLTE1VDA1OjE2OjA0LjAwMDAwMCswMDAwLDIwMTUtMDEtMTVUMDU6MjI6NDYuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4wOTgsMTMuMCwyMDE1LTAxLTEzLG9yZ2FuaWMsU291dGggQWZyaWNhCjExMTEsRExURlZRV1lJWFJKNTg5LERMVEZWUVdZSVhSSjU4OS1ub2hmYWUzNywyMDE1LTAxLTE1VDA1OjE2OjA0LjAwMDAwMCswMDAwLDIwMTUtMDEtMTVUMDU6MjU6MzQuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA0MSwxMy4wLDIwMTUtMDEtMTMsb3JnYW5pYyxTb3V0aCBBZnJpY2EKMTExOCxIRFNBTVBUT0xCV0M0MzgsSERTQU1QVE9MQldDNDM4LTI4dXE3bGFoLDIwMTUtMDEtMTVUMDY6MTM6MjcuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNVQwNjoxNTowOS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMTA4LDEwLjQsMjAxNS0wMS0xNCxvcmdhbmljLFN3aXR6ZXJsYW5kCjExMTksSERTQU1QVE9MQldDNDM4LEhEU0FNUFRPTEJXQzQzOC0yOHVxN2xhaCwyMDE1LTAxLTE1VDA2OjEzOjI3LjAwMDAwMCswMDAwLDIwMTUtMDEtMTVUMDY6MjE6NTcuMDAwMDAwKzAwMDAsaWFwLGdlbXM0LDY1Ljk5LDEwLjQsMjAxNS0wMS0xNCxvcmdhbmljLFN3aXR6ZXJsYW5kCjExMjgsSUNCQVVaS0dTUVBGMTQ1LElDQkFVWktHU1FQRjE0NS11OGVnZmE1aywyMDE1LTAxLTE1VDA3OjI1OjUyLjAwMDAwMCswMDAwLDIwMTUtMDEtMTVUMDc6Mjg6MjguMDAwMDAwKzAwMDAsYWQsYWRfMzBzZWMsMC43Nyw2LjQsMjAxNS0wMS0wNixnb29nbGUsU291dGggQWZyaWNhCjExNTgsRExURlZRV1lJWFJKNTg5LERMVEZWUVdZSVhSSjU4OS1zNmJranF5MywyMDE1LTAxLTE1VDExOjA4OjM3LjAwMDAwMCswMDAwLDIwMTUtMDEtMTVUMTE6MDk6MDcuMDAwMDAwKzAwMDAsaWFwLGdlbXMyLDYuOTksMTIuMSwyMDE1LTAxLTEzLG9yZ2FuaWMsU291dGggQWZyaWNhCjExNjQsSUNCQVVaS0dTUVBGMTQ1LElDQkFVWktHU1FQRjE0NS1ueXIxZDZrcCwyMDE1LTAxLTE1VDExOjQ3OjE4LjAwMDAwMCswMDAwLDIwMTUtMDEtMTVUMTE6NDg6NDIuMDAwMDAwKzAwMDAsaWFwLGdlbXMzLDE3LjQ5LDUuNCwyMDE1LTAxLTA2LGdvb2dsZSxTb3V0aCBBZnJpY2EKMTE3NyxKVkJaQ1BLWEhGTVU0OTEsSlZCWkNQS1hIRk1VNDkxLTNlaHk3ZHE5LDIwMTUtMDEtMTVUMTY6Mzc6NDkuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNVQxNjo0MTo1NS4wMDAwMDArMDAwMCxpYXAsZ29sZDcsODMuOTksOC4wLDIwMTUtMDEtMDcsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjExNzgsSlZCWkNQS1hIRk1VNDkxLEpWQlpDUEtYSEZNVTQ5MS0zZWh5N2RxOSwyMDE1LTAxLTE1VDE2OjM3OjQ5LjAwMDAwMCswMDAwLDIwMTUtMDEtMTVUMTY6NDU6MjUuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA3LDguMCwyMDE1LTAxLTA3LG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwoxMTg5LEJTRU5UQ1dMSk1QSTI1OCxCU0VOVENXTEpNUEkyNTgtODl4dWRxYWIsMjAxNS0wMS0xNVQyMDoxOTo1NC4wMDAwMDArMDAwMCwyMDE1LTAxLTE1VDIwOjIxOjM2LjAwMDAwMCswMDAwLGlhcCxvZmZlcjEsMi40OSw3LjMsMjAxNS0wMS0xNSxvcmdhbmljLEVneXB0CjExOTAsQlNFTlRDV0xKTVBJMjU4LEJTRU5UQ1dMSk1QSTI1OC04OXh1ZHFhYiwyMDE1LTAxLTE1VDIwOjE5OjU0LjAwMDAwMCswMDAwLDIwMTUtMDEtMTVUMjA6MjM6MTguMDAwMDAwKzAwMDAsYWQsYWRfc3VydmV5LDAuNjksNy4zLDIwMTUtMDEtMTUsb3JnYW5pYyxFZ3lwdAoxMTkxLFJZWkhBSkVYTUJJRjcyNCxSWVpIQUpFWE1CSUY3MjQtcGVobGI4MzYsMjAxNS0wMS0xNVQyMDoyODoxMi4wMDAwMDArMDAwMCwyMDE1LTAxLTE1VDIwOjMwOjMwLjAwMDAwMCswMDAwLGlhcCxvZmZlcjUsMjAuMjksNi4yLDIwMTUtMDEtMTUsZ29vZ2xlLFBvcnR1Z2FsCjExOTIsUllaSEFKRVhNQklGNzI0LFJZWkhBSkVYTUJJRjcyNC1wZWhsYjgzNiwyMDE1LTAxLTE1VDIwOjI4OjEyLjAwMDAwMCswMDAwLDIwMTUtMDEtMTVUMjA6MzE6MTguMDAwMDAwKzAwMDAsaWFwLGdlbXM0LDQxLjk5LDYuMiwyMDE1LTAxLTE1LGdvb2dsZSxQb3J0dWdhbAoxMjAwLFJZWkhBSkVYTUJJRjcyNCxSWVpIQUpFWE1CSUY3MjQtM3ptMWFiaTIsMjAxNS0wMS0xNVQyMjozNDowNi4wMDAwMDArMDAwMCwyMDE1LTAxLTE1VDIyOjM1OjE4LjAwMDAwMCswMDAwLGFkLGFkXzIwc2VjLDAuNTQsNi4wLDIwMTUtMDEtMTUsZ29vZ2xlLFBvcnR1Z2FsCjEyMDksUURVWkpJRVRDQUdXNjU0LFFEVVpKSUVUQ0FHVzY1NC03bHZ6cnQ4aywyMDE1LTAxLTE2VDAwOjIwOjQ3LjAwMDAwMCswMDAwLDIwMTUtMDEtMTZUMDA6MzE6NTMuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjE0NCwxNC4zLDIwMTUtMDEtMDcsZmFjZWJvb2ssU3dpdHplcmxhbmQKMTIxMCxSWVpIQUpFWE1CSUY3MjQsUllaSEFKRVhNQklGNzI0LXFwaWhtcng1LDIwMTUtMDEtMTZUMDE6MTg6MTIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNlQwMToyNTo1NC4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjA4MSwxNC4wLDIwMTUtMDEtMTUsZ29vZ2xlLFBvcnR1Z2FsCjEyMjMsV0JLRllKWENaTlVINTYzLFdCS0ZZSlhDWk5VSDU2My1obXVhNjU3MywyMDE1LTAxLTE2VDAzOjAyOjIyLjAwMDAwMCswMDAwLDIwMTUtMDEtMTZUMDM6MDM6NDYuMDAwMDAwKzAwMDAsYWQsYWRfMzBzZWMsMC45NCwxMy44LDIwMTUtMDEtMTMsb3JnYW5pYyxDYW5hZGEKMTIyNCxXQktGWUpYQ1pOVUg1NjMsV0JLRllKWENaTlVINTYzLWhtdWE2NTczLDIwMTUtMDEtMTZUMDM6MDI6MjIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNlQwMzoxNTo0MC4wMDAwMDArMDAwMCxpYXAsZ29sZDEsMC42OSwxMy44LDIwMTUtMDEtMTMsb3JnYW5pYyxDYW5hZGEKMTIyNSxGWFdETktJVU1KWVI0NzEsRlhXRE5LSVVNSllSNDcxLTZ0aHZ5cW5pLDIwMTUtMDEtMTZUMDM6MjE6MDYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNlQwMzoyNjozNi4wMDAwMDArMDAwMCxhZCxhZF9zdXJ2ZXksMC42Nyw4LjIsMjAxNS0wMS0xMCxvcmdhbmljLFVuaXRlZCBTdGF0ZXMKMTIyOCxCRk5MVVJJU0pYVEg2NDcsQkZOTFVSSVNKWFRINjQ3LWZkYXN3eXFnLDIwMTUtMDEtMTZUMDM6NDc6MTQuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNlQwMzo1MjoyNi4wMDAwMDArMDAwMCxpYXAsb2ZmZXIzLDUuOTksMTIuMSwyMDE1LTAxLTEwLG9yZ2FuaWMsSW5kaWEKMTIyOSxCRk5MVVJJU0pYVEg2NDcsQkZOTFVSSVNKWFRINjQ3LWZkYXN3eXFnLDIwMTUtMDEtMTZUMDM6NDc6MTQuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNlQwMzo1MjozMi4wMDAwMDArMDAwMCxhZCxhZF8yMHNlYywwLjA4NCwxMi4xLDIwMTUtMDEtMTAsb3JnYW5pYyxJbmRpYQoxMjMwLEJGTkxVUklTSlhUSDY0NyxCRk5MVVJJU0pYVEg2NDctZmRhc3d5cWcsMjAxNS0wMS0xNlQwMzo0NzoxNC4wMDAwMDArMDAwMCwyMDE1LTAxLTE2VDAzOjU1OjAyLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMTgsMTIuMSwyMDE1LTAxLTEwLG9yZ2FuaWMsSW5kaWEKMTI1NCxLSUxXWllIUlNKRUczMTYsS0lMV1pZSFJTSkVHMzE2LWx2Z2g0cWF1LDIwMTUtMDEtMTZUMDg6MTA6MzQuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNlQwODoxNDo0Ni4wMDAwMDArMDAwMCxhZCxhZF8zMHNlYywxLjAzNCw4LjAsMjAxNS0wMS0wNCxvcmdhbmljLERlbm1hcmsKMTI3MCxQSk9UQk5IWExGUlEyNjUsUEpPVEJOSFhMRlJRMjY1LWxha2lzdDhwLDIwMTUtMDEtMTZUMTA6MTI6NTAuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNlQxMDoxNzo0NC4wMDAwMDArMDAwMCxhZCxhZF9zdXJ2ZXksMC41MywxNC40LDIwMTUtMDEtMTYsb3JnYW5pYyxBdXN0cmlhCjEyNzEsUEpPVEJOSFhMRlJRMjY1LFBKT1RCTkhYTEZSUTI2NS1sYWtpc3Q4cCwyMDE1LTAxLTE2VDEwOjEyOjUwLjAwMDAwMCswMDAwLDIwMTUtMDEtMTZUMTA6MTc6NTAuMDAwMDAwKzAwMDAsYWQsYWRfc3VydmV5LDEuMjEsMTQuNCwyMDE1LTAxLTE2LG9yZ2FuaWMsQXVzdHJpYQoxMjcyLFBKT1RCTkhYTEZSUTI2NSxQSk9UQk5IWExGUlEyNjUtbGFraXN0OHAsMjAxNS0wMS0xNlQxMDoxMjo1MC4wMDAwMDArMDAwMCwyMDE1LTAxLTE2VDEwOjIwOjA4LjAwMDAwMCswMDAwLGlhcCxnZW1zMSwyLjI0LDE0LjQsMjAxNS0wMS0xNixvcmdhbmljLEF1c3RyaWEKMTI4NSxXTlZCQVlHQ0xKSVI1MTcsV05WQkFZR0NMSklSNTE3LXFqbmYzcHI2LDIwMTUtMDEtMTZUMTI6MTU6MDEuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNlQxMjoyMjozMS4wMDAwMDArMDAwMCxhZCxhZF8xNXNlYywwLjI2NCw4LjYsMjAxNS0wMS0xMyxmYWNlYm9vayxTd2VkZW4KMTI5MSxaUFRJSE5TVkZZQVExNDYsWlBUSUhOU1ZGWUFRMTQ2LXU4YzRucTc1LDIwMTUtMDEtMTZUMTI6MjM6NTkuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNlQxMjozMToyMy4wMDAwMDArMDAwMCxpYXAsZ29sZDMsMS45OSwxMC4yLDIwMTUtMDEtMDQsZmFjZWJvb2ssTWV4aWNvCjEyOTIsWlBUSUhOU1ZGWUFRMTQ2LFpQVElITlNWRllBUTE0Ni11OGM0bnE3NSwyMDE1LTAxLTE2VDEyOjIzOjU5LjAwMDAwMCswMDAwLDIwMTUtMDEtMTZUMTI6MzE6MjMuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA3MiwxMC4yLDIwMTUtMDEtMDQsZmFjZWJvb2ssTWV4aWNvCjEyOTMsWlBUSUhOU1ZGWUFRMTQ2LFpQVElITlNWRllBUTE0Ni11OGM0bnE3NSwyMDE1LTAxLTE2VDEyOjIzOjU5LjAwMDAwMCswMDAwLDIwMTUtMDEtMTZUMTI6MzI6MTcuMDAwMDAwKzAwMDAsYWQsYWRfcGxheWFibGUsMC45MiwxMC4yLDIwMTUtMDEtMDQsZmFjZWJvb2ssTWV4aWNvCjEzMDEsV0VQS1lOUlhERlVUNTcyLFdFUEtZTlJYREZVVDU3Mi1haDhiNms5NSwyMDE1LTAxLTE2VDEzOjExOjI2LjAwMDAwMCswMDAwLDIwMTUtMDEtMTZUMTM6MTg6MDIuMDAwMDAwKzAwMDAsYWQsYWRfc3VydmV5LDAuNiwxMi45LDIwMTUtMDEtMTMsY3Jvc3Nwcm9tbyxDaGluYQoxMzAyLFdFUEtZTlJYREZVVDU3MixXRVBLWU5SWERGVVQ1NzItYWg4YjZrOTUsMjAxNS0wMS0xNlQxMzoxMToyNi4wMDAwMDArMDAwMCwyMDE1LTAxLTE2VDEzOjE4OjIwLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNzIsMTIuOSwyMDE1LTAxLTEzLGNyb3NzcHJvbW8sQ2hpbmEKMTMxOCxLR1pDT0pIUEZUUVY3NTMsS0daQ09KSFBGVFFWNzUzLTZrOXhpdWdyLDIwMTUtMDEtMTZUMTQ6NTU6MzIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNlQxNTowMDozMi4wMDAwMDArMDAwMCxhZCxhZF9wbGF5YWJsZSwxLjA3LDUuMCwyMDE1LTAxLTExLG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwoxMzE5LE1YQ09WRVlJQUtGSDU5NCxNWENPVkVZSUFLRkg1OTQtamhuYzJydjUsMjAxNS0wMS0xNlQxNTowMjo1NS4wMDAwMDArMDAwMCwyMDE1LTAxLTE2VDE1OjA0OjE5LjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMTIsMTQuNiwyMDE1LTAxLTEwLG9yZ2FuaWMsQ2hpbmEKMTMyMCxNVENJV0tPVkFTWVA5MjUsTVRDSVdLT1ZBU1lQOTI1LWZ0Y2JzMjE3LDIwMTUtMDEtMTZUMTU6Mjc6MjQuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNlQxNTozMDoyNC4wMDAwMDArMDAwMCxhZCxhZF8yMHNlYywwLjc5LDcuMSwyMDE1LTAxLTE0LG9yZ2FuaWMsR2VybWFueQoxMzIxLEdKQ1hOVFdFQklQUTM2OSxHSkNYTlRXRUJJUFEzNjktNmJ2YzVncWQsMjAxNS0wMS0xNlQxNTozMjozNC4wMDAwMDArMDAwMCwyMDE1LTAxLTE2VDE1OjMyOjUyLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMiw1LjEsMjAxNS0wMS0xNCxvcmdhbmljLFVuaXRlZCBTdGF0ZXMKMTMyMixHSkNYTlRXRUJJUFEzNjksR0pDWE5UV0VCSVBRMzY5LTZidmM1Z3FkLDIwMTUtMDEtMTZUMTU6MzI6MzQuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNlQxNTozMzoyOC4wMDAwMDArMDAwMCxpYXAsZ2VtczMsMTcuNDksNS4xLDIwMTUtMDEtMTQsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjEzMjMsR0pDWE5UV0VCSVBRMzY5LEdKQ1hOVFdFQklQUTM2OS02YnZjNWdxZCwyMDE1LTAxLTE2VDE1OjMyOjM0LjAwMDAwMCswMDAwLDIwMTUtMDEtMTZUMTU6MzQ6NTIuMDAwMDAwKzAwMDAsaWFwLG9mZmVyNSwyMC4yOSw1LjEsMjAxNS0wMS0xNCxvcmdhbmljLFVuaXRlZCBTdGF0ZXMKMTMzMCxLSUxXWllIUlNKRUczMTYsS0lMV1pZSFJTSkVHMzE2LXpvaWF2OHl0LDIwMTUtMDEtMTZUMTc6NDQ6MTAuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNlQxNzo0NjoyMi4wMDAwMDArMDAwMCxpYXAsb2ZmZXI0LDIxLjk5LDcuMSwyMDE1LTAxLTA0LG9yZ2FuaWMsRGVubWFyawoxMzM3LElDQkFVWktHU1FQRjE0NSxJQ0JBVVpLR1NRUEYxNDUtbXh3MW9ndXAsMjAxNS0wMS0xNlQyMDoyOTowMy4wMDAwMDArMDAwMCwyMDE1LTAxLTE2VDIwOjI5OjM5LjAwMDAwMCswMDAwLGFkLGFkXzE1c2VjLDAuMTQ5OSw4LjAsMjAxNS0wMS0wNixnb29nbGUsU291dGggQWZyaWNhCjEzMzgsSUNCQVVaS0dTUVBGMTQ1LElDQkFVWktHU1FQRjE0NS1teHcxb2d1cCwyMDE1LTAxLTE2VDIwOjI5OjAzLjAwMDAwMCswMDAwLDIwMTUtMDEtMTZUMjA6MzA6MzMuMDAwMDAwKzAwMDAsaWFwLGdvbGQxLDAuNjksOC4wLDIwMTUtMDEtMDYsZ29vZ2xlLFNvdXRoIEFmcmljYQoxMzM5LElDQkFVWktHU1FQRjE0NSxJQ0JBVVpLR1NRUEYxNDUtbXh3MW9ndXAsMjAxNS0wMS0xNlQyMDoyOTowMy4wMDAwMDArMDAwMCwyMDE1LTAxLTE2VDIwOjMyOjA5LjAwMDAwMCswMDAwLGlhcCxnZW1zMSwxLjc0LDguMCwyMDE1LTAxLTA2LGdvb2dsZSxTb3V0aCBBZnJpY2EKMTM0MCxJQ0JBVVpLR1NRUEYxNDUsSUNCQVVaS0dTUVBGMTQ1LW14dzFvZ3VwLDIwMTUtMDEtMTZUMjA6Mjk6MDMuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNlQyMDozMzoxNS4wMDAwMDArMDAwMCxpYXAsZ29sZDIsMS4zOSw4LjAsMjAxNS0wMS0wNixnb29nbGUsU291dGggQWZyaWNhCjEzNTgsSUNCQVVaS0dTUVBGMTQ1LElDQkFVWktHU1FQRjE0NS1nNnZodzcyaSwyMDE1LTAxLTE2VDIyOjU3OjEzLjAwMDAwMCswMDAwLDIwMTUtMDEtMTZUMjM6MDI6MTkuMDAwMDAwKzAwMDAsYWQsYWRfc3VydmV5LDEuMDAxLDYuMiwyMDE1LTAxLTA2LGdvb2dsZSxTb3V0aCBBZnJpY2EKMTM2NyxHSkNYTlRXRUJJUFEzNjksR0pDWE5UV0VCSVBRMzY5LXh1aHNyNXQyLDIwMTUtMDEtMTdUMDE6MTQ6NDIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xN1QwMToxNTowNi4wMDAwMDArMDAwMCxhZCxhZF8xNXNlYywwLjU1LDkuMSwyMDE1LTAxLTE0LG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwoxMzc0LEZYV0ROS0lVTUpZUjQ3MSxGWFdETktJVU1KWVI0NzEtdHluazRybW8sMjAxNS0wMS0xN1QwMTozNzowMy4wMDAwMDArMDAwMCwyMDE1LTAxLTE3VDAxOjQzOjUxLjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMiwxMS44LDIwMTUtMDEtMTAsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjEzNzksSERTQU1QVE9MQldDNDM4LEhEU0FNUFRPTEJXQzQzOC1kb3Q5MjFsaywyMDE1LTAxLTE3VDAyOjMzOjU2LjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMDI6Mzc6MjAuMDAwMDAwKzAwMDAsaWFwLGdvbGQ2LDY1Ljk5LDEyLjIsMjAxNS0wMS0xNCxvcmdhbmljLFN3aXR6ZXJsYW5kCjEzODAsSERTQU1QVE9MQldDNDM4LEhEU0FNUFRPTEJXQzQzOC1kb3Q5MjFsaywyMDE1LTAxLTE3VDAyOjMzOjU2LjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMDI6Mzg6MTQuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4xMzIsMTIuMiwyMDE1LTAxLTE0LG9yZ2FuaWMsU3dpdHplcmxhbmQKMTM4MSxIRFNBTVBUT0xCV0M0MzgsSERTQU1QVE9MQldDNDM4LWRvdDkyMWxrLDIwMTUtMDEtMTdUMDI6MzM6NTYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xN1QwMjo0MDo0NC4wMDAwMDArMDAwMCxhZCxhZF8xNXNlYywwLjU4OCwxMi4yLDIwMTUtMDEtMTQsb3JnYW5pYyxTd2l0emVybGFuZAoxMzgyLEhEU0FNUFRPTEJXQzQzOCxIRFNBTVBUT0xCV0M0MzgtZG90OTIxbGssMjAxNS0wMS0xN1QwMjozMzo1Ni4wMDAwMDArMDAwMCwyMDE1LTAxLTE3VDAyOjQ0OjAyLjAwMDAwMCswMDAwLGlhcCxnZW1zNCw2NS45OSwxMi4yLDIwMTUtMDEtMTQsb3JnYW5pYyxTd2l0emVybGFuZAoxMzg2LFpHRVZRSlNLRklCWDM5OCxaR0VWUUpTS0ZJQlgzOTgtdWhzejRydmQsMjAxNS0wMS0xN1QwMzowOToyMy4wMDAwMDArMDAwMCwyMDE1LTAxLTE3VDAzOjEzOjE3LjAwMDAwMCswMDAwLGFkLGFkXzIwc2VjLDAuNzcsOC4wLDIwMTUtMDEtMTcsb3JnYW5pYyxTb3V0aCBLb3JlYQoxMzg3LFpHRVZRSlNLRklCWDM5OCxaR0VWUUpTS0ZJQlgzOTgtdWhzejRydmQsMjAxNS0wMS0xN1QwMzowOToyMy4wMDAwMDArMDAwMCwyMDE1LTAxLTE3VDAzOjE2OjA1LjAwMDAwMCswMDAwLGlhcCxvZmZlcjIsNy45OSw4LjAsMjAxNS0wMS0xNyxvcmdhbmljLFNvdXRoIEtvcmVhCjE0MDAsWElBSEJOS0VDR1JPNTk4LFhJQUhCTktFQ0dSTzU5OC1ncnZ1MXA2ZiwyMDE1LTAxLTE3VDAzOjM4OjM2LjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMDM6NDI6MTIuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA1NSwxMS4yLDIwMTUtMDEtMTQsZ29vZ2xlLEVneXB0CjE0MDEsWElBSEJOS0VDR1JPNTk4LFhJQUhCTktFQ0dSTzU5OC1ncnZ1MXA2ZiwyMDE1LTAxLTE3VDAzOjM4OjM2LjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMDM6NDU6NDguMDAwMDAwKzAwMDAsaWFwLG9mZmVyMiw0Ljk5LDExLjIsMjAxNS0wMS0xNCxnb29nbGUsRWd5cHQKMTQwNixNWVFHSktPVUlXSEY2MTksTVlRR0pLT1VJV0hGNjE5LTVobnRtaXd5LDIwMTUtMDEtMTdUMDQ6MDM6MTMuMDAwMDAwKzAwMDAsMjAxNS0wMS0xN1QwNDowODoxMy4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDI0LDguMywyMDE1LTAxLTE2LG9yZ2FuaWMsSW5kaWEKMTQwOCxKWUVCQ0xOVVpUWFE0NTcsSllFQkNMTlVaVFhRNDU3LWRtdmt5Mm5oLDIwMTUtMDEtMTdUMDU6MzY6MzcuMDAwMDAwKzAwMDAsMjAxNS0wMS0xN1QwNTozOTo1NS4wMDAwMDArMDAwMCxhZCxhZF8xNXNlYywwLjI0LDEyLjQsMjAxNS0wMS0wNCxvdGhlcl9jYW1wYWlnbixFZ3lwdAoxNDA5LEpZRUJDTE5VWlRYUTQ1NyxKWUVCQ0xOVVpUWFE0NTctZG12a3kybmgsMjAxNS0wMS0xN1QwNTozNjozNy4wMDAwMDArMDAwMCwyMDE1LTAxLTE3VDA1OjQyOjAxLjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDM1LDEyLjQsMjAxNS0wMS0wNCxvdGhlcl9jYW1wYWlnbixFZ3lwdAoxNDEwLE1ZUUdKS09VSVdIRjYxOSxNWVFHSktPVUlXSEY2MTktdGx3Y3N5NzYsMjAxNS0wMS0xN1QwNjoyMzo1OC4wMDAwMDArMDAwMCwyMDE1LTAxLTE3VDA2OjI0OjEwLjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDI4LDEyLjMsMjAxNS0wMS0xNixvcmdhbmljLEluZGlhCjE0MTEsTVlRR0pLT1VJV0hGNjE5LE1ZUUdKS09VSVdIRjYxOS10bHdjc3k3NiwyMDE1LTAxLTE3VDA2OjIzOjU4LjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMDY6Mjk6MDQuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4wMTQsMTIuMywyMDE1LTAxLTE2LG9yZ2FuaWMsSW5kaWEKMTQyNSxXQktGWUpYQ1pOVUg1NjMsV0JLRllKWENaTlVINTYzLWxtam51NzFnLDIwMTUtMDEtMTdUMDg6MzM6MDAuMDAwMDAwKzAwMDAsMjAxNS0wMS0xN1QwODozNTozMC4wMDAwMDArMDAwMCxhZCxhZF8xNXNlYywwLjQyLDE0LjYsMjAxNS0wMS0xMyxvcmdhbmljLENhbmFkYQoxNDI2LFdCS0ZZSlhDWk5VSDU2MyxXQktGWUpYQ1pOVUg1NjMtbG1qbnU3MWcsMjAxNS0wMS0xN1QwODozMzowMC4wMDAwMDArMDAwMCwyMDE1LTAxLTE3VDA4OjQ2OjQyLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNSwxNC42LDIwMTUtMDEtMTMsb3JnYW5pYyxDYW5hZGEKMTQ0MCxLSUxXWllIUlNKRUczMTYsS0lMV1pZSFJTSkVHMzE2LTMxcGh6Zjg3LDIwMTUtMDEtMTdUMTA6MjQ6NTIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xN1QxMDoyNDo1OC4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjE3NiwxNC45LDIwMTUtMDEtMDQsb3JnYW5pYyxEZW5tYXJrCjE0NDEsS0lMV1pZSFJTSkVHMzE2LEtJTFdaWUhSU0pFRzMxNi0zMXBoemY4NywyMDE1LTAxLTE3VDEwOjI0OjUyLjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMTA6Mjk6NTIuMDAwMDAwKzAwMDAsaWFwLG9mZmVyMiwxMC45OSwxNC45LDIwMTUtMDEtMDQsb3JnYW5pYyxEZW5tYXJrCjE0NTMsUEpPVEJOSFhMRlJRMjY1LFBKT1RCTkhYTEZSUTI2NS05MjdvbWc0eiwyMDE1LTAxLTE3VDExOjA3OjE3LjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMTE6MTA6NDcuMDAwMDAwKzAwMDAsYWQsYWRfMTVzZWMsMC40MiwxMi41LDIwMTUtMDEtMTYsb3JnYW5pYyxBdXN0cmlhCjE0NTQsUEpPVEJOSFhMRlJRMjY1LFBKT1RCTkhYTEZSUTI2NS05MjdvbWc0eiwyMDE1LTAxLTE3VDExOjA3OjE3LjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMTE6MTY6MTcuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4xOSwxMi41LDIwMTUtMDEtMTYsb3JnYW5pYyxBdXN0cmlhCjE0NTUsR0pDWE5UV0VCSVBRMzY5LEdKQ1hOVFdFQklQUTM2OS00NmNkanp5NywyMDE1LTAxLTE3VDExOjI1OjI1LjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMTE6Mjg6MDEuMDAwMDAwKzAwMDAsaWFwLG9mZmVyNCwxMy45OSw0LjYsMjAxNS0wMS0xNCxvcmdhbmljLFVuaXRlZCBTdGF0ZXMKMTQ4MixaUFRJSE5TVkZZQVExNDYsWlBUSUhOU1ZGWUFRMTQ2LTJ2cjR5enNqLDIwMTUtMDEtMTdUMTU6MDg6NTcuMDAwMDAwKzAwMDAsMjAxNS0wMS0xN1QxNToxMTo0NS4wMDAwMDArMDAwMCxhZCxhZF8xNXNlYywwLjEyLDE0LjAsMjAxNS0wMS0wNCxmYWNlYm9vayxNZXhpY28KMTQ4MyxaUFRJSE5TVkZZQVExNDYsWlBUSUhOU1ZGWUFRMTQ2LTJ2cjR5enNqLDIwMTUtMDEtMTdUMTU6MDg6NTcuMDAwMDAwKzAwMDAsMjAxNS0wMS0xN1QxNToxNDoyNy4wMDAwMDArMDAwMCxpYXAsZ2VtczMsOS45OSwxNC4wLDIwMTUtMDEtMDQsZmFjZWJvb2ssTWV4aWNvCjE0ODQsWlBUSUhOU1ZGWUFRMTQ2LFpQVElITlNWRllBUTE0Ni0ydnI0eXpzaiwyMDE1LTAxLTE3VDE1OjA4OjU3LjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMTU6MjI6MDMuMDAwMDAwKzAwMDAsYWQsYWRfMTVzZWMsMC4zNTQsMTQuMCwyMDE1LTAxLTA0LGZhY2Vib29rLE1leGljbwoxNDkwLFFEVVpKSUVUQ0FHVzY1NCxRRFVaSklFVENBR1c2NTQtdm8zaGt1MjgsMjAxNS0wMS0xN1QxNjoxNDoyOC4wMDAwMDArMDAwMCwyMDE1LTAxLTE3VDE2OjIxOjU4LjAwMDAwMCswMDAwLGlhcCxnb2xkMiwyLjE5LDguNiwyMDE1LTAxLTA3LGZhY2Vib29rLFN3aXR6ZXJsYW5kCjE1MTUsUk1PU1dISkdFTENJNjc1LFJNT1NXSEpHRUxDSTY3NS1qdjJxbnlvNiwyMDE1LTAxLTE3VDIwOjM5OjA5LjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMjA6NDQ6MzkuMDAwMDAwKzAwMDAsYWQsYWRfc3VydmV5LDAuOTQsOC42LDIwMTUtMDEtMTAsb3RoZXJfY2FtcGFpZ24sRnJhbmNlCjE1MTYsT01DVlVBSUtTRFRSNjUxLE9NQ1ZVQUlLU0RUUjY1MS15c285ZTFiMiwyMDE1LTAxLTE3VDIwOjU4OjM0LjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMjE6MDE6MzQuMDAwMDAwKzAwMDAsaWFwLG9mZmVyMywxMC40OSw0LjIsMjAxNS0wMS0wNyxvdGhlcl9jYW1wYWlnbixVbml0ZWQgU3RhdGVzCjE1MTcsT01DVlVBSUtTRFRSNjUxLE9NQ1ZVQUlLU0RUUjY1MS15c285ZTFiMiwyMDE1LTAxLTE3VDIwOjU4OjM0LjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMjE6MDI6MzQuMDAwMDAwKzAwMDAsaWFwLG9mZmVyNSwyMC4yOSw0LjIsMjAxNS0wMS0wNyxvdGhlcl9jYW1wYWlnbixVbml0ZWQgU3RhdGVzCjE1NDksUURVWkpJRVRDQUdXNjU0LFFEVVpKSUVUQ0FHVzY1NC01bWFrODQ2NywyMDE1LTAxLTE4VDAyOjAyOjU4LjAwMDAwMCswMDAwLDIwMTUtMDEtMThUMDI6MDY6MTYuMDAwMDAwKzAwMDAsYWQsYWRfc3VydmV5LDEuNTI0LDUuMywyMDE1LTAxLTA3LGZhY2Vib29rLFN3aXR6ZXJsYW5kCjE1NTQsUU5MVlJERU9YRllKODkyLFFOTFZSREVPWEZZSjg5Mi1mM2p0NGg1OSwyMDE1LTAxLTE4VDAzOjAyOjE2LjAwMDAwMCswMDAwLDIwMTUtMDEtMThUMDM6MDY6MjIuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4xNyw3LjMsMjAxNS0wMS0wOSxjcm9zc3Byb21vLEF1c3RyYWxpYQoxNTY1LFFKR1ZPQkxBVElIVzQ1NyxRSkdWT0JMQVRJSFc0NTctdmY0dTdkZ3MsMjAxNS0wMS0xOFQwMzo0MzoxMy4wMDAwMDArMDAwMCwyMDE1LTAxLTE4VDAzOjU0OjQ5LjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMTg3LDEzLjQsMjAxNS0wMS0wMixvdGhlcl9jYW1wYWlnbixTd2VkZW4KMTU2NixRSkdWT0JMQVRJSFc0NTcsUUpHVk9CTEFUSUhXNDU3LXZmNHU3ZGdzLDIwMTUtMDEtMThUMDM6NDM6MTMuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOFQwMzo1NTozNy4wMDAwMDArMDAwMCxpYXAsZ2VtczIsOS45OSwxMy40LDIwMTUtMDEtMDIsb3RoZXJfY2FtcGFpZ24sU3dlZGVuCjE1ODAsTlBNSklZSEVUR0tXMjk3LE5QTUpJWUhFVEdLVzI5Ny10bmk3OHU5ZSwyMDE1LTAxLTE4VDA1OjI0OjE4LjAwMDAwMCswMDAwLDIwMTUtMDEtMThUMDU6MzI6MTIuMDAwMDAwKzAwMDAsYWQsYWRfcGxheWFibGUsMC4zNzYsMTQuMywyMDE1LTAxLTE4LGdvb2dsZSxQaGlsaXBwaW5lcwoxNTgxLE5QTUpJWUhFVEdLVzI5NyxOUE1KSVlIRVRHS1cyOTctdG5pNzh1OWUsMjAxNS0wMS0xOFQwNToyNDoxOC4wMDAwMDArMDAwMCwyMDE1LTAxLTE4VDA1OjMyOjE4LjAwMDAwMCswMDAwLGlhcCxvZmZlcjQsNS45OSwxNC4zLDIwMTUtMDEtMTgsZ29vZ2xlLFBoaWxpcHBpbmVzCjE1ODIsTlBNSklZSEVUR0tXMjk3LE5QTUpJWUhFVEdLVzI5Ny10bmk3OHU5ZSwyMDE1LTAxLTE4VDA1OjI0OjE4LjAwMDAwMCswMDAwLDIwMTUtMDEtMThUMDU6Mzg6MDYuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyLDE0LjMsMjAxNS0wMS0xOCxnb29nbGUsUGhpbGlwcGluZXMKMTU4MyxGR0tYUE5JUkpIQ1k2MjUsRkdLWFBOSVJKSENZNjI1LW9rcnZtdTlmLDIwMTUtMDEtMThUMDY6MDM6NTcuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOFQwNjowNjo1Ny4wMDAwMDArMDAwMCxpYXAsZ29sZDIsMS4xOSw4LjIsMjAxNS0wMS0xNyxjcm9zc3Byb21vLEhvbmcgS29uZwoxNTg2LFJZWkhBSkVYTUJJRjcyNCxSWVpIQUpFWE1CSUY3MjQtOGE5bHhvN20sMjAxNS0wMS0xOFQwNjoxODo1Mi4wMDAwMDArMDAwMCwyMDE1LTAxLTE4VDA2OjE5OjI4LjAwMDAwMCswMDAwLGlhcCxnZW1zNCw0MS45OSwxMS42LDIwMTUtMDEtMTUsZ29vZ2xlLFBvcnR1Z2FsCjE1ODcsUllaSEFKRVhNQklGNzI0LFJZWkhBSkVYTUJJRjcyNC04YTlseG83bSwyMDE1LTAxLTE4VDA2OjE4OjUyLjAwMDAwMCswMDAwLDIwMTUtMDEtMThUMDY6MjU6MjguMDAwMDAwKzAwMDAsYWQsYWRfcGxheWFibGUsMS40NCwxMS42LDIwMTUtMDEtMTUsZ29vZ2xlLFBvcnR1Z2FsCjE1ODgsUllaSEFKRVhNQklGNzI0LFJZWkhBSkVYTUJJRjcyNC04YTlseG83bSwyMDE1LTAxLTE4VDA2OjE4OjUyLjAwMDAwMCswMDAwLDIwMTUtMDEtMThUMDY6MjY6NDAuMDAwMDAwKzAwMDAsaWFwLGdvbGQzLDMuNDksMTEuNiwyMDE1LTAxLTE1LGdvb2dsZSxQb3J0dWdhbAoxNTkzLEVLSUhYQlJGR09DRDU3MSxFS0lIWEJSRkdPQ0Q1NzEtaG9sdWM5MWEsMjAxNS0wMS0xOFQwNzoxMTo0MC4wMDAwMDArMDAwMCwyMDE1LTAxLTE4VDA3OjE0OjU4LjAwMDAwMCswMDAwLGFkLGFkXzE1c2VjLDAuMzIsMTIuNiwyMDE1LTAxLTE3LGFwcGxlLFVuaXRlZCBLaW5nZG9tCjE1OTQsRUtJSFhCUkZHT0NENTcxLEVLSUhYQlJGR09DRDU3MS1ob2x1YzkxYSwyMDE1LTAxLTE4VDA3OjExOjQwLjAwMDAwMCswMDAwLDIwMTUtMDEtMThUMDc6MTg6NTguMDAwMDAwKzAwMDAsaWFwLG9mZmVyMywxNC45OSwxMi42LDIwMTUtMDEtMTcsYXBwbGUsVW5pdGVkIEtpbmdkb20KMTYyOSxOUE1KSVlIRVRHS1cyOTcsTlBNSklZSEVUR0tXMjk3LXpqbjVoOGtkLDIwMTUtMDEtMThUMTE6MjQ6NTYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOFQxMTozNzowOC4wMDAwMDArMDAwMCxhZCxhZF9zdXJ2ZXksMC4zLDEzLjQsMjAxNS0wMS0xOCxnb29nbGUsUGhpbGlwcGluZXMKMTYzMCxOUE1KSVlIRVRHS1cyOTcsTlBNSklZSEVUR0tXMjk3LXpqbjVoOGtkLDIwMTUtMDEtMThUMTE6MjQ6NTYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOFQxMTozNzo1MC4wMDAwMDArMDAwMCxpYXAsb2ZmZXIzLDQuNDksMTMuNCwyMDE1LTAxLTE4LGdvb2dsZSxQaGlsaXBwaW5lcwoxNjQxLFpNSkxQR0NSSUtOQTQ3MSxaTUpMUEdDUklLTkE0NzEtbnpqdWJmZ3IsMjAxNS0wMS0xOFQxMzo1NToxMC4wMDAwMDArMDAwMCwyMDE1LTAxLTE4VDEzOjU5OjI4LjAwMDAwMCswMDAwLGFkLGFkXzE1c2VjLDAuMDg0LDYuMiwyMDE1LTAxLTEwLG9yZ2FuaWMsRWd5cHQKMTY1MixOQU9KUkRNQ1NFQkkyODEsTkFPSlJETUNTRUJJMjgxLWpzNnBreTdvLDIwMTUtMDEtMThUMTQ6NDY6MzYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOFQxNDo1MDoxMi4wMDAwMDArMDAwMCxhZCxhZF8zMHNlYywwLjk3MiwxMi42LDIwMTUtMDEtMTEsb3JnYW5pYyxOb3J3YXkKMTY1MyxOQU9KUkRNQ1NFQkkyODEsTkFPSlJETUNTRUJJMjgxLWpzNnBreTdvLDIwMTUtMDEtMThUMTQ6NDY6MzYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOFQxNDo1MDozNi4wMDAwMDArMDAwMCxpYXAsb2ZmZXIxLDUuNDksMTIuNiwyMDE1LTAxLTExLG9yZ2FuaWMsTm9yd2F5CjE2NTQsSUNCQVVaS0dTUVBGMTQ1LElDQkFVWktHU1FQRjE0NS04MWpteGZyNSwyMDE1LTAxLTE4VDE1OjAzOjU5LjAwMDAwMCswMDAwLDIwMTUtMDEtMThUMTU6MDY6MjkuMDAwMDAwKzAwMDAsYWQsYWRfMTVzZWMsMC4zMDcsOC42LDIwMTUtMDEtMDYsZ29vZ2xlLFNvdXRoIEFmcmljYQoxNjYzLFpHRVZRSlNLRklCWDM5OCxaR0VWUUpTS0ZJQlgzOTgtNmV6d240bG0sMjAxNS0wMS0xOFQxNTozODozNS4wMDAwMDArMDAwMCwyMDE1LTAxLTE4VDE1OjQyOjU5LjAwMDAwMCswMDAwLGFkLGFkX3N1cnZleSwwLjM5Miw1LjcsMjAxNS0wMS0xNyxvcmdhbmljLFNvdXRoIEtvcmVhCjE2NzUsSERTQU1QVE9MQldDNDM4LEhEU0FNUFRPTEJXQzQzOC1jcXNsbWJvMiwyMDE1LTAxLTE4VDE4OjU3OjQ4LjAwMDAwMCswMDAwLDIwMTUtMDEtMThUMTg6NTg6MjQuMDAwMDAwKzAwMDAsaWFwLGdlbXMzLDI3LjQ5LDcuOCwyMDE1LTAxLTE0LG9yZ2FuaWMsU3dpdHplcmxhbmQKMTY3NixIRFNBTVBUT0xCV0M0MzgsSERTQU1QVE9MQldDNDM4LWNxc2xtYm8yLDIwMTUtMDEtMThUMTg6NTc6NDguMDAwMDAwKzAwMDAsMjAxNS0wMS0xOFQxOTowMjoxMi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMTIsNy44LDIwMTUtMDEtMTQsb3JnYW5pYyxTd2l0emVybGFuZAoxNjgyLEJGTkxVUklTSlhUSDY0NyxCRk5MVVJJU0pYVEg2NDctZ2o0aTlocHEsMjAxNS0wMS0xOFQyMDo1NjozMi4wMDAwMDArMDAwMCwyMDE1LTAxLTE4VDIxOjAyOjUwLjAwMDAwMCswMDAwLGFkLGFkXzMwc2VjLDAuMTgsMTQuMywyMDE1LTAxLTEwLG9yZ2FuaWMsSW5kaWEKMTY4MyxCRk5MVVJJU0pYVEg2NDcsQkZOTFVSSVNKWFRINjQ3LWdqNGk5aHBxLDIwMTUtMDEtMThUMjA6NTY6MzIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOFQyMTowNDowMi4wMDAwMDArMDAwMCxpYXAsZ29sZDUsMTEuNTksMTQuMywyMDE1LTAxLTEwLG9yZ2FuaWMsSW5kaWEKMTcyNCxKWUVCQ0xOVVpUWFE0NTcsSllFQkNMTlVaVFhRNDU3LWJkNTFpc2dhLDIwMTUtMDEtMTlUMDI6MzU6MjcuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOVQwMjo0MjoxNS4wMDAwMDArMDAwMCxhZCxhZF8yMHNlYywwLjM5LDguNSwyMDE1LTAxLTA0LG90aGVyX2NhbXBhaWduLEVneXB0CjE3MjUsRUtJSFhCUkZHT0NENTcxLEVLSUhYQlJGR09DRDU3MS1hand0dXpobiwyMDE1LTAxLTE5VDAzOjAxOjM5LjAwMDAwMCswMDAwLDIwMTUtMDEtMTlUMDM6MDQ6MjEuMDAwMDAwKzAwMDAsYWQsYWRfMjBzZWMsMS4wOCw2LjgsMjAxNS0wMS0xNyxhcHBsZSxVbml0ZWQgS2luZ2RvbQoxNzM0LFdaR0lIUlRTS0NWRDE2NSxXWkdJSFJUU0tDVkQxNjUtYXM1dHBueTksMjAxNS0wMS0xOVQwNDoxMTo1Ny4wMDAwMDArMDAwMCwyMDE1LTAxLTE5VDA0OjE4OjI3LjAwMDAwMCswMDAwLGFkLGFkXzE1c2VjLDAuNiw3LjIsMjAxNS0wMS0xNyxvcmdhbmljLFVuaXRlZCBTdGF0ZXMKMTczNSxXWkdJSFJUU0tDVkQxNjUsV1pHSUhSVFNLQ1ZEMTY1LWFzNXRwbnk5LDIwMTUtMDEtMTlUMDQ6MTE6NTcuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOVQwNDoxODozMy4wMDAwMDArMDAwMCxpYXAsZ29sZDEsMC42OSw3LjIsMjAxNS0wMS0xNyxvcmdhbmljLFVuaXRlZCBTdGF0ZXMKMTczNixXWkdJSFJUU0tDVkQxNjUsV1pHSUhSVFNLQ1ZEMTY1LWFzNXRwbnk5LDIwMTUtMDEtMTlUMDQ6MTE6NTcuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOVQwNDoxOTowOS4wMDAwMDArMDAwMCxpYXAsb2ZmZXIzLDEwLjQ5LDcuMiwyMDE1LTAxLTE3LG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwoxNzM3LE1UQ0lXS09WQVNZUDkyNSxNVENJV0tPVkFTWVA5MjUtZXFiY3Z5Z3QsMjAxNS0wMS0xOVQwNDozODo1NC4wMDAwMDArMDAwMCwyMDE1LTAxLTE5VDA0OjM5OjEyLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMiw5LjQsMjAxNS0wMS0xNCxvcmdhbmljLEdlcm1hbnkKMTc0MCxGR0tYUE5JUkpIQ1k2MjUsRkdLWFBOSVJKSENZNjI1LTJkMThvNGlqLDIwMTUtMDEtMTlUMDU6MDA6NTYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOVQwNTowNDozOC4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjE0NywxMS4zLDIwMTUtMDEtMTcsY3Jvc3Nwcm9tbyxIb25nIEtvbmcKMTc0MSxGR0tYUE5JUkpIQ1k2MjUsRkdLWFBOSVJKSENZNjI1LTJkMThvNGlqLDIwMTUtMDEtMTlUMDU6MDA6NTYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOVQwNTowNzozOC4wMDAwMDArMDAwMCxpYXAsb2ZmZXIyLDUuOTksMTEuMywyMDE1LTAxLTE3LGNyb3NzcHJvbW8sSG9uZyBLb25nCjE3NDIsRkdLWFBOSVJKSENZNjI1LEZHS1hQTklSSkhDWTYyNS0yZDE4bzRpaiwyMDE1LTAxLTE5VDA1OjAwOjU2LjAwMDAwMCswMDAwLDIwMTUtMDEtMTlUMDU6MTA6MzIuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA0MiwxMS4zLDIwMTUtMDEtMTcsY3Jvc3Nwcm9tbyxIb25nIEtvbmcKMTc1NyxHQVlJQkxVQ09FREo3MzIsR0FZSUJMVUNPRURKNzMyLWxlY280MWd6LDIwMTUtMDEtMTlUMDY6MTQ6MzIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOVQwNjoyMDozOC4wMDAwMDArMDAwMCxhZCxhZF8zMHNlYywxLjI2LDEwLjksMjAxNS0wMS0wMyxvcmdhbmljLFVuaXRlZCBTdGF0ZXMKMTc1OCxHQVlJQkxVQ09FREo3MzIsR0FZSUJMVUNPRURKNzMyLWxlY280MWd6LDIwMTUtMDEtMTlUMDY6MTQ6MzIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOVQwNjoyNToxNC4wMDAwMDArMDAwMCxhZCxhZF9zdXJ2ZXksMS4yOCwxMC45LDIwMTUtMDEtMDMsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjE3NjksQkZOTFVSSVNKWFRINjQ3LEJGTkxVUklTSlhUSDY0Ny10Y2Y1eXNhdiwyMDE1LTAxLTE5VDA4OjA1OjIwLjAwMDAwMCswMDAwLDIwMTUtMDEtMTlUMDg6MDg6NTYuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4wMTYsNS45LDIwMTUtMDEtMTAsb3JnYW5pYyxJbmRpYQoxNzg1LEZHS1hQTklSSkhDWTYyNSxGR0tYUE5JUkpIQ1k2MjUtcTU5cG93bmwsMjAxNS0wMS0xOVQxMDo1Nzo0My4wMDAwMDArMDAwMCwyMDE1LTAxLTE5VDExOjAyOjMxLjAwMDAwMCswMDAwLGFkLGFkX3N1cnZleSwwLjQ4MywxNC40LDIwMTUtMDEtMTcsY3Jvc3Nwcm9tbyxIb25nIEtvbmcKMTc4NixGR0tYUE5JUkpIQ1k2MjUsRkdLWFBOSVJKSENZNjI1LXE1OXBvd25sLDIwMTUtMDEtMTlUMTA6NTc6NDMuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOVQxMTowNzoxOS4wMDAwMDArMDAwMCxpYXAsb2ZmZXIxLDIuOTksMTQuNCwyMDE1LTAxLTE3LGNyb3NzcHJvbW8sSG9uZyBLb25nCjE3ODcsRkdLWFBOSVJKSENZNjI1LEZHS1hQTklSSkhDWTYyNS1xNTlwb3dubCwyMDE1LTAxLTE5VDEwOjU3OjQzLjAwMDAwMCswMDAwLDIwMTUtMDEtMTlUMTE6MTE6NTUuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA1NiwxNC40LDIwMTUtMDEtMTcsY3Jvc3Nwcm9tbyxIb25nIEtvbmcKMTc5MSxGWFdETktJVU1KWVI0NzEsRlhXRE5LSVVNSllSNDcxLWdxN2QzMnRlLDIwMTUtMDEtMTlUMTE6NDA6NTMuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOVQxMTo1MTo0Ny4wMDAwMDArMDAwMCxhZCxhZF8xNXNlYywwLjM5LDExLjQsMjAxNS0wMS0xMCxvcmdhbmljLFVuaXRlZCBTdGF0ZXMKMTc5MixKVkJaQ1BLWEhGTVU0OTEsSlZCWkNQS1hIRk1VNDkxLXVmNmtocmExLDIwMTUtMDEtMTlUMTI6MzQ6MjguMDAwMDAwKzAwMDAsMjAxNS0wMS0xOVQxMjozNzoxNi4wMDAwMDArMDAwMCxhZCxhZF8xNXNlYywwLjE1LDE1LjAsMjAxNS0wMS0wNyxvcmdhbmljLFVuaXRlZCBTdGF0ZXMKMTc5MyxKVkJaQ1BLWEhGTVU0OTEsSlZCWkNQS1hIRk1VNDkxLXVmNmtocmExLDIwMTUtMDEtMTlUMTI6MzQ6MjguMDAwMDAwKzAwMDAsMjAxNS0wMS0xOVQxMjo0NzozNC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMSwxNS4wLDIwMTUtMDEtMDcsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjE3OTQsSlZCWkNQS1hIRk1VNDkxLEpWQlpDUEtYSEZNVTQ5MS11ZjZraHJhMSwyMDE1LTAxLTE5VDEyOjM0OjI4LjAwMDAwMCswMDAwLDIwMTUtMDEtMTlUMTI6NDg6NTIuMDAwMDAwKzAwMDAsaWFwLGdlbXM1LDkwLjk5LDE1LjAsMjAxNS0wMS0wNyxvcmdhbmljLFVuaXRlZCBTdGF0ZXMKMTgwMSxHSkNYTlRXRUJJUFEzNjksR0pDWE5UV0VCSVBRMzY5LWp5NGY1c2NiLDIwMTUtMDEtMTlUMTQ6MDI6MTQuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOVQxNDowNjozOC4wMDAwMDArMDAwMCxhZCxhZF9zdXJ2ZXksMC41OCwxNS4wLDIwMTUtMDEtMTQsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjE4MDIsR0pDWE5UV0VCSVBRMzY5LEdKQ1hOVFdFQklQUTM2OS1qeTRmNXNjYiwyMDE1LTAxLTE5VDE0OjAyOjE0LjAwMDAwMCswMDAwLDIwMTUtMDEtMTlUMTQ6MDg6MjAuMDAwMDAwKzAwMDAsaWFwLGdlbXM1LDkwLjk5LDE1LjAsMjAxNS0wMS0xNCxvcmdhbmljLFVuaXRlZCBTdGF0ZXMKMTgwMyxHSkNYTlRXRUJJUFEzNjksR0pDWE5UV0VCSVBRMzY5LWp5NGY1c2NiLDIwMTUtMDEtMTlUMTQ6MDI6MTQuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOVQxNDoxMTo1Ni4wMDAwMDArMDAwMCxhZCxhZF9zdXJ2ZXksMS4yNCwxNS4wLDIwMTUtMDEtMTQsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjE4MDksUURVWkpJRVRDQUdXNjU0LFFEVVpKSUVUQ0FHVzY1NC1kMXFuazU3eCwyMDE1LTAxLTE5VDE2OjI4OjI0LjAwMDAwMCswMDAwLDIwMTUtMDEtMTlUMTY6MzI6NDIuMDAwMDAwKzAwMDAsYWQsYWRfMTVzZWMsMC43MDgsOS42LDIwMTUtMDEtMDcsZmFjZWJvb2ssU3dpdHplcmxhbmQKMTgyNixSTU9TV0hKR0VMQ0k2NzUsUk1PU1dISkdFTENJNjc1LXdmNHJ6eWp2LDIwMTUtMDEtMTlUMTk6MTc6NDYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOVQxOToyMDowNC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDksNS43LDIwMTUtMDEtMTAsb3RoZXJfY2FtcGFpZ24sRnJhbmNlCjE4MzgsRUtJSFhCUkZHT0NENTcxLEVLSUhYQlJGR09DRDU3MS03bml4cWJ0OSwyMDE1LTAxLTE5VDIwOjA4OjU4LjAwMDAwMCswMDAwLDIwMTUtMDEtMTlUMjA6MTI6MTAuMDAwMDAwKzAwMDAsaWFwLG9mZmVyMSw0Ljk5LDExLjYsMjAxNS0wMS0xNyxhcHBsZSxVbml0ZWQgS2luZ2RvbQoxODM5LEVLSUhYQlJGR09DRDU3MSxFS0lIWEJSRkdPQ0Q1NzEtN25peHFidDksMjAxNS0wMS0xOVQyMDowODo1OC4wMDAwMDArMDAwMCwyMDE1LTAxLTE5VDIwOjE0OjM0LjAwMDAwMCswMDAwLGFkLGFkXzIwc2VjLDAuOCwxMS42LDIwMTUtMDEtMTcsYXBwbGUsVW5pdGVkIEtpbmdkb20KMTg0MCxFS0lIWEJSRkdPQ0Q1NzEsRUtJSFhCUkZHT0NENTcxLTduaXhxYnQ5LDIwMTUtMDEtMTlUMjA6MDg6NTguMDAwMDAwKzAwMDAsMjAxNS0wMS0xOVQyMDoxOTo1Mi4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjE0LDExLjYsMjAxNS0wMS0xNyxhcHBsZSxVbml0ZWQgS2luZ2RvbQoxODQxLEhEU0FNUFRPTEJXQzQzOCxIRFNBTVBUT0xCV0M0MzgteHVreml2M2IsMjAxNS0wMS0xOVQyMDoxODozNS4wMDAwMDArMDAwMCwyMDE1LTAxLTE5VDIwOjE5OjQxLjAwMDAwMCswMDAwLGlhcCxvZmZlcjUsMzEuODksMTQuMSwyMDE1LTAxLTE0LG9yZ2FuaWMsU3dpdHplcmxhbmQKMTg0MixIRFNBTVBUT0xCV0M0MzgsSERTQU1QVE9MQldDNDM4LXh1a3ppdjNiLDIwMTUtMDEtMTlUMjA6MTg6MzUuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOVQyMDoyMToyMy4wMDAwMDArMDAwMCxhZCxhZF8yMHNlYywwLjQ0NCwxNC4xLDIwMTUtMDEtMTQsb3JnYW5pYyxTd2l0emVybGFuZAoxODQzLEhEU0FNUFRPTEJXQzQzOCxIRFNBTVBUT0xCV0M0MzgteHVreml2M2IsMjAxNS0wMS0xOVQyMDoxODozNS4wMDAwMDArMDAwMCwyMDE1LTAxLTE5VDIwOjI4OjExLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4xMiwxNC4xLDIwMTUtMDEtMTQsb3JnYW5pYyxTd2l0emVybGFuZAoxODUyLEdKQ1hOVFdFQklQUTM2OSxHSkNYTlRXRUJJUFEzNjktYm1zOWcycHcsMjAxNS0wMS0yMFQwMDozODowNC4wMDAwMDArMDAwMCwyMDE1LTAxLTIwVDAwOjM4OjM0LjAwMDAwMCswMDAwLGlhcCxnZW1zNSw5MC45OSwxMy45LDIwMTUtMDEtMTQsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjE4NTMsR0pDWE5UV0VCSVBRMzY5LEdKQ1hOVFdFQklQUTM2OS1ibXM5ZzJwdywyMDE1LTAxLTIwVDAwOjM4OjA0LjAwMDAwMCswMDAwLDIwMTUtMDEtMjBUMDA6NDc6MTYuMDAwMDAwKzAwMDAsaWFwLGdlbXMzLDE3LjQ5LDEzLjksMjAxNS0wMS0xNCxvcmdhbmljLFVuaXRlZCBTdGF0ZXMKMTg1NCxHSkNYTlRXRUJJUFEzNjksR0pDWE5UV0VCSVBRMzY5LWJtczlnMnB3LDIwMTUtMDEtMjBUMDA6Mzg6MDQuMDAwMDAwKzAwMDAsMjAxNS0wMS0yMFQwMDo1MDo1Mi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMSwxMy45LDIwMTUtMDEtMTQsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjE4NjAsT0FCSldESUdRUkNVNDE4LE9BQkpXRElHUVJDVTQxOC1jdGdtcGl1biwyMDE1LTAxLTIwVDAzOjE2OjI0LjAwMDAwMCswMDAwLDIwMTUtMDEtMjBUMDM6MjE6NDguMDAwMDAwKzAwMDAsYWQsYWRfc3VydmV5LDAuNiwxNC44LDIwMTUtMDEtMjAsZmFjZWJvb2ssRnJhbmNlCjE4NjEsT0FCSldESUdRUkNVNDE4LE9BQkpXRElHUVJDVTQxOC1jdGdtcGl1biwyMDE1LTAxLTIwVDAzOjE2OjI0LjAwMDAwMCswMDAwLDIwMTUtMDEtMjBUMDM6Mjc6NTQuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4xMiwxNC44LDIwMTUtMDEtMjAsZmFjZWJvb2ssRnJhbmNlCjE4NzUsRExURlZRV1lJWFJKNTg5LERMVEZWUVdZSVhSSjU4OS1sM2g4cWNvNSwyMDE1LTAxLTIwVDA2OjA5OjA4LjAwMDAwMCswMDAwLDIwMTUtMDEtMjBUMDY6MTQ6NDQuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4xNTQsNy43LDIwMTUtMDEtMTMsb3JnYW5pYyxTb3V0aCBBZnJpY2EKMTg4NSxFS0lIWEJSRkdPQ0Q1NzEsRUtJSFhCUkZHT0NENTcxLXByMW1qZWhjLDIwMTUtMDEtMjBUMDY6MjQ6NTAuMDAwMDAwKzAwMDAsMjAxNS0wMS0yMFQwNjozMjoyNi4wMDAwMDArMDAwMCxhZCxhZF8yMHNlYywwLjY0OSwxMy40LDIwMTUtMDEtMTcsYXBwbGUsVW5pdGVkIEtpbmdkb20KMTg5MCxRV1pPQ0lFVUxWSEo1ODQsUVdaT0NJRVVMVkhKNTg0LWM0eW52YjE3LDIwMTUtMDEtMjBUMDY6NDc6MDQuMDAwMDAwKzAwMDAsMjAxNS0wMS0yMFQwNjo0OTo1Mi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDIsMTMuMSwyMDE1LTAxLTIwLGdvb2dsZSxFZ3lwdAoxODkxLFFXWk9DSUVVTFZISjU4NCxRV1pPQ0lFVUxWSEo1ODQtYzR5bnZiMTcsMjAxNS0wMS0yMFQwNjo0NzowNC4wMDAwMDArMDAwMCwyMDE1LTAxLTIwVDA2OjUxOjUyLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNTUsMTMuMSwyMDE1LTAxLTIwLGdvb2dsZSxFZ3lwdAoxODkyLFFXWk9DSUVVTFZISjU4NCxRV1pPQ0lFVUxWSEo1ODQtYzR5bnZiMTcsMjAxNS0wMS0yMFQwNjo0NzowNC4wMDAwMDArMDAwMCwyMDE1LTAxLTIwVDA2OjUzOjIyLjAwMDAwMCswMDAwLGlhcCxvZmZlcjIsNC45OSwxMy4xLDIwMTUtMDEtMjAsZ29vZ2xlLEVneXB0CjE4OTUsQUlPSEtQRkNYWVNCNDc1LEFJT0hLUEZDWFlTQjQ3NS1vcmY5enE3aywyMDE1LTAxLTIwVDA3OjM5OjI2LjAwMDAwMCswMDAwLDIwMTUtMDEtMjBUMDc6NDg6MjAuMDAwMDAwKzAwMDAsYWQsYWRfMTVzZWMsMC41OCw5LjUsMjAxNS0wMS0xOCxvcmdhbmljLEF1c3RyYWxpYQoxODk2LFJNT1NXSEpHRUxDSTY3NSxSTU9TV0hKR0VMQ0k2NzUtaWJqb2V5YXgsMjAxNS0wMS0yMFQwOTowNDoxNS4wMDAwMDArMDAwMCwyMDE1LTAxLTIwVDA5OjA3OjI3LjAwMDAwMCswMDAwLGlhcCxvZmZlcjUsMjYuMDksOS4yLDIwMTUtMDEtMTAsb3RoZXJfY2FtcGFpZ24sRnJhbmNlCjE4OTcsUk1PU1dISkdFTENJNjc1LFJNT1NXSEpHRUxDSTY3NS1pYmpvZXlheCwyMDE1LTAxLTIwVDA5OjA0OjE1LjAwMDAwMCswMDAwLDIwMTUtMDEtMjBUMDk6MDc6NDUuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4xMyw5LjIsMjAxNS0wMS0xMCxvdGhlcl9jYW1wYWlnbixGcmFuY2UKMTg5OCxSTU9TV0hKR0VMQ0k2NzUsUk1PU1dISkdFTENJNjc1LWliam9leWF4LDIwMTUtMDEtMjBUMDk6MDQ6MTUuMDAwMDAwKzAwMDAsMjAxNS0wMS0yMFQwOTowOToyNy4wMDAwMDArMDAwMCxpYXAsb2ZmZXIyLDguOTksOS4yLDIwMTUtMDEtMTAsb3RoZXJfY2FtcGFpZ24sRnJhbmNlCjE5MTMsTVRDSVdLT1ZBU1lQOTI1LE1UQ0lXS09WQVNZUDkyNS0xcTN4dmZtcCwyMDE1LTAxLTIwVDEyOjM0OjQzLjAwMDAwMCswMDAwLDIwMTUtMDEtMjBUMTI6MzU6MzcuMDAwMDAwKzAwMDAsaWFwLG9mZmVyNSwyNi4wOSwzLjksMjAxNS0wMS0xNCxvcmdhbmljLEdlcm1hbnkKMTkxNCxNVENJV0tPVkFTWVA5MjUsTVRDSVdLT1ZBU1lQOTI1LTFxM3h2Zm1wLDIwMTUtMDEtMjBUMTI6MzQ6NDMuMDAwMDAwKzAwMDAsMjAxNS0wMS0yMFQxMjozNzoyNS4wMDAwMDArMDAwMCxpYXAsZ29sZDIsMS43OSwzLjksMjAxNS0wMS0xNCxvcmdhbmljLEdlcm1hbnkKMTkxOSxCRk5MVVJJU0pYVEg2NDcsQkZOTFVSSVNKWFRINjQ3LWxlbjZ2dWpkLDIwMTUtMDEtMjBUMTQ6MDk6NTEuMDAwMDAwKzAwMDAsMjAxNS0wMS0yMFQxNDoxMDowMy4wMDAwMDArMDAwMCxpYXAsZ29sZDcsNDcuOTksNC41LDIwMTUtMDEtMTAsb3JnYW5pYyxJbmRpYQoxOTIwLEJGTkxVUklTSlhUSDY0NyxCRk5MVVJJU0pYVEg2NDctbGVuNnZ1amQsMjAxNS0wMS0yMFQxNDowOTo1MS4wMDAwMDArMDAwMCwyMDE1LTAxLTIwVDE0OjE0OjIxLjAwMDAwMCswMDAwLGlhcCxnb2xkNiwyMy45OSw0LjUsMjAxNS0wMS0xMCxvcmdhbmljLEluZGlhCjE5NTQsUllaSEFKRVhNQklGNzI0LFJZWkhBSkVYTUJJRjcyNC1yajR2eGJpdSwyMDE1LTAxLTIwVDE4OjI0OjE0LjAwMDAwMCswMDAwLDIwMTUtMDEtMjBUMTg6MjQ6MzguMDAwMDAwKzAwMDAsaWFwLGdvbGQ2LDQxLjk5LDkuMiwyMDE1LTAxLTE1LGdvb2dsZSxQb3J0dWdhbAoxOTU1LFJZWkhBSkVYTUJJRjcyNCxSWVpIQUpFWE1CSUY3MjQtcmo0dnhiaXUsMjAxNS0wMS0yMFQxODoyNDoxNC4wMDAwMDArMDAwMCwyMDE1LTAxLTIwVDE4OjI3OjQ0LjAwMDAwMCswMDAwLGlhcCxvZmZlcjMsMTAuNDksOS4yLDIwMTUtMDEtMTUsZ29vZ2xlLFBvcnR1Z2FsCjE5NTYsUllaSEFKRVhNQklGNzI0LFJZWkhBSkVYTUJJRjcyNC1yajR2eGJpdSwyMDE1LTAxLTIwVDE4OjI0OjE0LjAwMDAwMCswMDAwLDIwMTUtMDEtMjBUMTg6MzA6MTQuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAzNiw5LjIsMjAxNS0wMS0xNSxnb29nbGUsUG9ydHVnYWwKMTk3MCxXWkdJSFJUU0tDVkQxNjUsV1pHSUhSVFNLQ1ZEMTY1LXR3a2cybzE4LDIwMTUtMDEtMjBUMjI6NTQ6MDkuMDAwMDAwKzAwMDAsMjAxNS0wMS0yMFQyMjo1Nzo0NS4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjE2LDcuOCwyMDE1LTAxLTE3LG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwoxOTkyLEpWQlpDUEtYSEZNVTQ5MSxKVkJaQ1BLWEhGTVU0OTEtd3ZpNmhzMnQsMjAxNS0wMS0yMVQwMTo0OTozNi4wMDAwMDArMDAwMCwyMDE1LTAxLTIxVDAxOjUzOjM2LjAwMDAwMCswMDAwLGlhcCxnb2xkNiw0MS45OSw3LjEsMjAxNS0wMS0wNyxvcmdhbmljLFVuaXRlZCBTdGF0ZXMKMTk5MyxKVkJaQ1BLWEhGTVU0OTEsSlZCWkNQS1hIRk1VNDkxLXd2aTZoczJ0LDIwMTUtMDEtMjFUMDE6NDk6MzYuMDAwMDAwKzAwMDAsMjAxNS0wMS0yMVQwMTo1NTo0Mi4wMDAwMDArMDAwMCxpYXAsZ2VtczMsMTcuNDksNy4xLDIwMTUtMDEtMDcsb3JnYW5pYyxVbml0ZWQgU3RhdGVzCjE5OTgsUk1PU1dISkdFTENJNjc1LFJNT1NXSEpHRUxDSTY3NS12Ymhjc210ciwyMDE1LTAxLTIxVDAyOjM5OjQ4LjAwMDAwMCswMDAwLDIwMTUtMDEtMjFUMDI6NDA6MDAuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAzLDguNCwyMDE1LTAxLTEwLG90aGVyX2NhbXBhaWduLEZyYW5jZQoxOTk5LFJNT1NXSEpHRUxDSTY3NSxSTU9TV0hKR0VMQ0k2NzUtdmJoY3NtdHIsMjAxNS0wMS0yMVQwMjozOTo0OC4wMDAwMDArMDAwMCwyMDE1LTAxLTIxVDAyOjQ3OjEyLjAwMDAwMCswMDAwLGlhcCxvZmZlcjUsMjYuMDksOC40LDIwMTUtMDEtMTAsb3RoZXJfY2FtcGFpZ24sRnJhbmNlCg==" download="extract_0003.csv"><button style="background-color: #67C2DC; color: #FFFFFF; border: none; padding: 5px; font-weight: bold; cursor: pointer; border-radius: 4px;">CSV</button></a></td>
  </tr>
</tbody>
</table>
</div>
<h2 id="wrapping-up-from-passive-validation-to-active-data-quality-management">Wrapping Up: from Passive Validation to Active Data Quality Management
</h2>
<p>With <a href="https://posit-dev.github.io/pointblank/reference/Actions.html" target="_blank" rel="noopener"><code>Actions</code></a>
 and
<a href="https://posit-dev.github.io/pointblank/reference/FinalActions.html" target="_blank" rel="noopener"><code>FinalActions</code></a>
, Pointblank is
now more of a complete data quality management system. Instead of just detecting problems, you can
now:</p>
<ol>
<li>respond immediately to validation failures</li>
<li>customize responses based on severity level</li>
<li>generate comprehensive reports after validation completes</li>
<li>integrate with other systems through custom action functions</li>
<li>automate workflows based on validation results</li>
</ol>
<p>These capabilities transform data validation from a passive reporting activity into an active
component of your data pipeline, helping ensure that data quality issues are detected, reported, and
addressed efficiently.</p>
<p>As we continue to enhance Pointblank, we&rsquo;d love to hear how you&rsquo;re using
<a href="https://posit-dev.github.io/pointblank/reference/Actions.html" target="_blank" rel="noopener"><code>Actions</code></a>
 and
<a href="https://posit-dev.github.io/pointblank/reference/FinalActions.html" target="_blank" rel="noopener"><code>FinalActions</code></a>
 in your
workflows. Share your experiences or suggestions with us on
<a href="https://discord.gg/YH7CybCNCQ" target="_blank" rel="noopener">Discord</a>
 or file an issue on
<a href="https://github.com/posit-dev/pointblank/issues" target="_blank" rel="noopener">GitHub</a>
.</p>
<h2 id="learn-more">Learn More
</h2>
<p>Explore our documentation to learn more about Pointblank&rsquo;s action capabilities:</p>
<ul>
<li><a href="https://posit-dev.github.io/pointblank/reference/Actions.html" target="_blank" rel="noopener">Actions documentation</a>
</li>
<li><a href="https://posit-dev.github.io/pointblank/reference/FinalActions.html" target="_blank" rel="noopener">FinalActions documentation</a>
</li>
<li><a href="https://posit-dev.github.io/pointblank/user-guide/actions.html" target="_blank" rel="noopener">User Guide on Triggering Actions</a>
</li>
</ul>
]]></description>
    </item>
    <item>
      <title>Introducing Pointblank</title>
      <link>https://posit-open-source.netlify.app/blog/pointblank/intro-pointblank/</link>
      <pubDate>Fri, 04 Apr 2025 00:00:00 +0000</pubDate>
      <guid>https://posit-open-source.netlify.app/blog/pointblank/intro-pointblank/</guid>
      <dc:creator>Rich Iannone</dc:creator><description><![CDATA[<script src="https://cdn.jsdelivr.net/npm/requirejs@2.3.6/require.min.js" integrity="sha384-c9c+LnTbwQ3aujuU7ULEPVvgLs+Fn6fJUvIGTsuu1ZcCf11fiEubah0ttpca4ntM sha384-6V1/AdqZRWk1KAlWbKBlGhN7VG4iE/yAZcO6NZPMF8od0vukrvr0tg4qY6NSrItx" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.min.js" integrity="sha384-ZvpUoO/+PpLXR1lu4jmpXWu80pZlYUAfxl5NsBMWOEPSjUn/6Z/hRTt8+pR6L4N2" crossorigin="anonymous" data-relocate-top="true"></script>
<script type="application/javascript">define('jquery', [],function() {return window.jQuery;})</script>
<p>If you have tabular data (and who doesn&rsquo;t?) this is the package for you! I&rsquo;ve long been interested
in data quality and so I&rsquo;ve spent a lot of time building tooling that makes it possible to perform
data quality checks. And there&rsquo;s so many reasons to care about data quality. If I were to put down
just one good reason for why data quality is worth your time it is because having good data quality
strongly determines the quality of decisions.</p>
<p>Having the ability to distinguish bad data from good data is the first step in solving DQ issues,
and the sustained practice of doing data validation will guard against intrusions of poor-quality
data. Pointblank has been designed to really help here. Though it&rsquo;s a fairly new package it is
currently quite capable. And it&rsquo;s available in PyPI, so you can install it by using:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">pip install pointblank
</span></span></code></pre></td></tr></table>
</div>
</div><div class="callout callout-note" role="note" aria-label="Note">
<div class="callout-header">
<span class="callout-title">Note</span>
</div>
<div class="callout-body">
<p>To run the examples in this post, you&rsquo;ll need to have a DataFrame library installed. Pointblank
works seamlessly with both Polars and Pandas but you&rsquo;ll need to install at least one of them on your
own. We also have a DuckDB example that&rsquo;s running via Ibis (so, you&rsquo;ll have to install Ibis with
the DuckDB backend for that to work).</p>
</div>
</div>
<h2 id="how-pointblank-transforms-your-data-validation-workflow">How Pointblank Transforms Your Data Validation Workflow
</h2>
<p>What sets Pointblank apart is its intuitive, expressive approach to data validation. Rather than
writing dozens of ad-hoc checks scattered throughout your codebase, Pointblank lets you define a
comprehensive validation plan with just a few lines of code. The fluent API makes your validation
intentions crystal clear, whether you&rsquo;re ensuring numeric values fall within expected ranges, text
fields match specific patterns, or relationships between columns remain consistent.</p>
<p>But say you find problems. What are you gonna do about it? Well, Pointblank wants to help at not
just finding problems but helping you understand them. When validation failures occur, the detailed
reporting capabilities (in the form of beautiful, sharable tables) show you exactly where issues
are. Right down to the specific rows and columns. This transforms data validation from a binary
pass/fail exercise into a super-insightful diagnostic tool.</p>
<p><div class="not-prose"><figure>
    <img class="h-auto max-w-full rounded-lg"
      src="https://posit-open-source.netlify.app/blog/pointblank/intro-pointblank/step_report.png"
      alt="" 
      loading="lazy"
    >
  </figure></div>
</p>
<p>Here&rsquo;s the the best part: Pointblank is designed to work with your existing data stack. Whether
you&rsquo;re using Polars, Pandas, DuckDB, or other database systems, Pointblank tries hard to integrate
without forcing you to change your workflow. We also have international spoken language support for
reporting, meaning that validation reports can be localized to your team&rsquo;s preferred language. This
making data quality accessible to everyone in your organization (like a team sport!).</p>
<p><div class="not-prose"><figure>
    <img class="h-auto max-w-full rounded-lg"
      src="https://posit-open-source.netlify.app/blog/pointblank/intro-pointblank/pointblank-localized.png"
      alt="" 
      loading="lazy"
    >
  </figure></div>
</p>
<p>Alright! Let&rsquo;s look at a few demonstrations of Pointblank&rsquo;s capabilities for data validation.</p>
<h2 id="the-data-validation-workflow">The Data Validation Workflow
</h2>
<p>Let&rsquo;s get right to performing a basic check of a Polars DataFrame. We&rsquo;ll make use of the included
<code>small_table</code> dataset.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">pointblank</span> <span class="k">as</span> <span class="nn">pb</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">small_table</span> <span class="o">=</span> <span class="n">pb</span><span class="o">.</span><span class="n">load_dataset</span><span class="p">(</span><span class="n">dataset</span><span class="o">=</span><span class="s2">&#34;small_table&#34;</span><span class="p">,</span> <span class="n">tbl_type</span><span class="o">=</span><span class="s2">&#34;polars&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">validation_1</span> <span class="o">=</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">pb</span><span class="o">.</span><span class="n">Validate</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="n">data</span><span class="o">=</span><span class="n">small_table</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="n">tbl_name</span><span class="o">=</span><span class="s2">&#34;small_table&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="n">label</span><span class="o">=</span><span class="s2">&#34;Example Validation&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">col_vals_lt</span><span class="p">(</span><span class="n">columns</span><span class="o">=</span><span class="s2">&#34;a&#34;</span><span class="p">,</span> <span class="n">value</span><span class="o">=</span><span class="mi">10</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">col_vals_between</span><span class="p">(</span><span class="n">columns</span><span class="o">=</span><span class="s2">&#34;d&#34;</span><span class="p">,</span> <span class="n">left</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">right</span><span class="o">=</span><span class="mi">5000</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">col_vals_in_set</span><span class="p">(</span><span class="n">columns</span><span class="o">=</span><span class="s2">&#34;f&#34;</span><span class="p">,</span> <span class="nb">set</span><span class="o">=</span><span class="p">[</span><span class="s2">&#34;low&#34;</span><span class="p">,</span> <span class="s2">&#34;mid&#34;</span><span class="p">,</span> <span class="s2">&#34;high&#34;</span><span class="p">])</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">col_vals_regex</span><span class="p">(</span><span class="n">columns</span><span class="o">=</span><span class="s2">&#34;b&#34;</span><span class="p">,</span> <span class="n">pattern</span><span class="o">=</span><span class="sa">r</span><span class="s2">&#34;^[0-9]-[a-z]</span><span class="si">{3}</span><span class="s2">-[0-9]</span><span class="si">{3}</span><span class="s2">$&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">interrogate</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">validation_1</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div id="pb_tbl" style="padding-left:0px;padding-right:0px;padding-top:10px;padding-bottom:10px;overflow-x:auto;overflow-y:auto;width:auto;height:auto;">
<style>
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono&display=swap');
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans&display=swap');
#pb_tbl table {
          font-family: 'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Helvetica Neue', 'Fira Sans', 'Droid Sans', Arial, sans-serif;
          -webkit-font-smoothing: antialiased;
          -moz-osx-font-smoothing: grayscale;
        }
<p>#pb_tbl thead, tbody, tfoot, tr, td, th { border-style: none; }
tr { background-color: transparent; }
#pb_tbl p { margin: 0; padding: 0; }
#pb_tbl .gt_table { display: table; border-collapse: collapse; line-height: normal; margin-left: auto; margin-right: auto; color: #333333; font-size: 90%; font-weight: normal; font-style: normal; background-color: #FFFFFF; width: auto; border-top-style: solid; border-top-width: 2px; border-top-color: #A8A8A8; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #A8A8A8; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; }
#pb_tbl .gt_caption { padding-top: 4px; padding-bottom: 4px; }
#pb_tbl .gt_title { color: #333333; font-size: 125%; font-weight: initial; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; border-bottom-color: #FFFFFF; border-bottom-width: 0; }
#pb_tbl .gt_subtitle { color: #333333; font-size: 85%; font-weight: initial; padding-top: 3px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; border-top-color: #FFFFFF; border-top-width: 0; }
#pb_tbl .gt_heading { background-color: #FFFFFF; text-align: left; border-bottom-color: #FFFFFF; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; }
#pb_tbl .gt_bottom_border { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; }
#pb_tbl .gt_col_headings { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; }
#pb_tbl .gt_col_heading { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; overflow-x: hidden; }
#pb_tbl .gt_column_spanner_outer { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; padding-top: 0; padding-bottom: 0; padding-left: 4px; padding-right: 4px; }
#pb_tbl .gt_column_spanner_outer:first-child { padding-left: 0; }
#pb_tbl .gt_column_spanner_outer:last-child { padding-right: 0; }
#pb_tbl .gt_column_spanner { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; overflow-x: hidden; display: inline-block; width: 100%; }
#pb_tbl .gt_spanner_row { border-bottom-style: hidden; }
#pb_tbl .gt_group_heading { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; text-align: left; }
#pb_tbl .gt_empty_group_heading { padding: 0.5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: middle; }
#pb_tbl .gt_from_md&gt; :first-child { margin-top: 0; }
#pb_tbl .gt_from_md&gt; :last-child { margin-bottom: 0; }
#pb_tbl .gt_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; margin: 10px; border-top-style: solid; border-top-width: 1px; border-top-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; overflow-x: hidden; }
#pb_tbl .gt_stub { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; }
#pb_tbl .gt_stub_row_group { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; vertical-align: top; }
#pb_tbl .gt_row_group_first td { border-top-width: 2px; }
#pb_tbl .gt_row_group_first th { border-top-width: 2px; }
#pb_tbl .gt_striped { color: #333333; background-color: #F4F4F4; }
#pb_tbl .gt_table_body { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; }
#pb_tbl .gt_grand_summary_row { color: #333333; background-color: #FFFFFF; text-transform: inherit; padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; }
#pb_tbl .gt_first_grand_summary_row_bottom { border-top-style: double; border-top-width: 6px; border-top-color: #D3D3D3; }
#pb_tbl .gt_last_grand_summary_row_top { border-bottom-style: double; border-bottom-width: 6px; border-bottom-color: #D3D3D3; }
#pb_tbl .gt_sourcenotes { color: #333333; background-color: #FFFFFF; border-bottom-style: none; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; }
#pb_tbl .gt_sourcenote { font-size: 90%; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; text-align: left; }
#pb_tbl .gt_left { text-align: left; }
#pb_tbl .gt_center { text-align: center; }
#pb_tbl .gt_right { text-align: right; font-variant-numeric: tabular-nums; }
#pb_tbl .gt_font_normal { font-weight: normal; }
#pb_tbl .gt_font_bold { font-weight: bold; }
#pb_tbl .gt_font_italic { font-style: italic; }
#pb_tbl .gt_super { font-size: 65%; }
#pb_tbl .gt_footnote_marks { font-size: 75%; vertical-align: 0.4em; position: initial; }
#pb_tbl .gt_asterisk { font-size: 100%; vertical-align: 0; }</p>
<p></style></p>
<table style="table-layout: fixed;; width: 0px" class="gt_table" data-quarto-disable-processing="true" data-quarto-bootstrap="false">
<colgroup>
  <col style="width:4px;"/>
  <col style="width:35px;"/>
  <col style="width:190px;"/>
  <col style="width:120px;"/>
  <col style="width:120px;"/>
  <col style="width:50px;"/>
  <col style="width:50px;"/>
  <col style="width:60px;"/>
  <col style="width:60px;"/>
  <col style="width:60px;"/>
  <col style="width:30px;"/>
  <col style="width:30px;"/>
  <col style="width:30px;"/>
  <col style="width:65px;"/>
</colgroup>
<thead>
  <tr class="gt_heading">
    <td colspan="14" class="gt_heading gt_title gt_font_normal" style="color: #444444;font-size: 28px;text-align: left;font-weight: bold; text-align: left;">Pointblank Validation</td>
  </tr>
  <tr class="gt_heading">
    <td colspan="14" class="gt_heading gt_subtitle gt_font_normal gt_bottom_border" style="text-align: left;"><div><span style='text-decoration-style: solid; text-decoration-color: #ADD8E6; text-decoration-line: underline; text-underline-position: under; color: #333333; font-variant-numeric: tabular-nums; padding-left: 4px; margin-right: 5px; padding-right: 2px;'>Example Validation</span><div style="padding-top: 10px; padding-bottom: 5px;"><span style='background-color: #0075FF; color: #FFFFFF; padding: 0.5em 0.5em; position: inherit; text-transform: uppercase; margin: 5px 0px 5px 0px; border: solid 1px #0075FF; font-weight: bold; padding: 2px 15px 2px 15px; font-size: 10px;'>Polars</span><span style='background-color: none; color: #222222; padding: 0.5em 0.5em; position: inherit; margin: 5px 10px 5px -4px; border: solid 1px #0075FF; font-weight: bold; padding: 2px 15px 2px 15px; font-size: 10px;'>small_table</span></div></div></td>
  </tr>
<tr class="gt_col_headings">
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-status_color"></th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-i"></th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-type_upd">STEP</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-columns_upd">COLUMNS</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-values_upd">VALUES</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-tbl">TBL</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-eval">EVAL</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-test_units">UNITS</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-pass">PASS</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-fail">FAIL</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-w_upd">W</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-e_upd">E</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-c_upd">C</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-extract_upd">EXT</th>
</tr>
</thead>
<tbody class="gt_table_body">
  <tr>
    <td style="height: 40px; background-color: #4CA64C; color: transparent;font-size: 0px;" class="gt_row gt_left">#4CA64C</td>
    <td style="height: 40px; color: #666666;font-size: 13px;font-weight: bold;" class="gt_row gt_right">1</td>
    <td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_left">
        <div style="margin: 0; padding: 0; display: inline-block; height: 30px; vertical-align: middle; width: 16%;">
            <!--?xml version="1.0" encoding="UTF-8"?--><?xml version="1.0" encoding="UTF-8"?>
<svg width="30px" height="30px" viewBox="0 0 67 67" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="background: #FFFFFF;">
    <title>col_vals_lt</title>
    <g id="Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="col_vals_lt" transform="translate(1.500000, 1.500000)" fill-rule="nonzero">
            <path d="M55,0 C57.4852813,0 59.7352813,1.00735931 61.363961,2.63603897 C62.9926407,4.26471863 64,6.51471863 64,9 L64,9 L64,64 L9,64 C6.51471862,64 4.26471862,62.9926407 2.63603897,61.363961 C1.00735931,59.7352814 0,57.4852814 0,55 L0,55 L0,9 C0,6.51471863 1.00735931,4.26471863 2.63603897,2.63603897 C4.26471862,1.00735931 6.51471862,0 9,0 L9,0 L55,0 Z" id="rectangle" stroke="#000000" stroke-width="2" fill="#FFFFFF"></path>
            <path d="M51,10 L13,10 C11.347656,10 10,11.347656 10,13 L10,51 C10,52.652344 11.347656,54 13,54 L51,54 C52.652344,54 54,52.652344 54,51 L54,13 C54,11.347656 52.652344,10 51,10 Z M38.707031,45.292969 L37.292969,46.707031 L22.585938,32 L37.292969,17.292969 L38.707031,18.707031 L25.414063,32 L38.707031,45.292969 Z" id="less_than" fill="#000000"></path>
        </g>
    </g>
</svg>
        </div>
        <div style="font-family: 'IBM Plex Mono', monospace, courier; color: black; font-size: 11px; display: inline-block; vertical-align: middle;">
            <div>col_vals_lt()</div>
        </div>
<pre><code>    &lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;a&lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;10&lt;/td&gt;
&lt;td style=&quot;height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;&quot; class=&quot;gt_row gt_center&quot;&gt;&lt;svg width=&quot;25px&quot; height=&quot;25px&quot; viewBox=&quot;0 0 25 25&quot; version=&quot;1.1&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot; style=&quot;vertical-align: middle;&quot;&gt;
&lt;g id=&quot;unchanged&quot; stroke=&quot;none&quot; stroke-width=&quot;1&quot; fill=&quot;none&quot; fill-rule=&quot;evenodd&quot;&gt;
    &lt;g id=&quot;unchanged&quot; transform=&quot;translate(0.500000, 0.570147)&quot;&gt;
        &lt;rect id=&quot;Rectangle&quot; x=&quot;0.125132506&quot; y=&quot;0&quot; width=&quot;23.749735&quot; height=&quot;23.7894737&quot;&gt;&lt;/rect&gt;
        &lt;path d=&quot;M5.80375046,8.18194736 C3.77191832,8.18194736 2.11875046,9.83495328 2.11875046,11.8669474 C2.11875046,13.8989414 3.77191832,15.5519474 5.80375046,15.5519474 C7.8355826,15.5519474 9.48875046,13.8989414 9.48875046,11.8669474 C9.48875046,9.83495328 7.83552863,8.18194736 5.80375046,8.18194736 Z M5.80375046,14.814915 C4.17821997,14.814915 2.85578285,13.4924778 2.85578285,11.8669474 C2.85578285,10.2414169 4.17821997,8.91897975 5.80375046,8.91897975 C7.42928095,8.91897975 8.75171807,10.2414169 8.75171807,11.8669474 C8.75171807,13.4924778 7.42928095,14.814915 5.80375046,14.814915 Z&quot; id=&quot;Shape&quot; fill=&quot;#000000&quot; fill-rule=&quot;nonzero&quot;&gt;&lt;/path&gt;
        &lt;path d=&quot;M13.9638189,8.699335 C13.9364621,8.70430925 13.9091059,8.71176968 13.8842359,8.71923074 C13.7822704,8.73663967 13.6877654,8.77643115 13.6056956,8.83860518 L10.2433156,11.3852598 C10.0766886,11.5046343 9.97720993,11.6986181 9.97720993,11.9025491 C9.97720993,12.1064807 10.0766886,12.3004639 10.2433156,12.4198383 L13.6056956,14.966493 C13.891697,15.1803725 14.2970729,15.1231721 14.5109517,14.8371707 C14.7248313,14.5511692 14.6676309,14.145794 14.3816294,13.9319145 L12.5313257,12.5392127 L21.8812495,12.5392127 L21.8812495,11.2658854 L12.5313257,11.2658854 L14.3816294,9.87318364 C14.6377872,9.71650453 14.7497006,9.40066014 14.6477351,9.11714553 C14.5482564,8.83363156 14.262255,8.65954352 13.9638189,8.699335 Z&quot; id=&quot;arrow&quot; fill=&quot;#000000&quot; transform=&quot;translate(15.929230, 11.894737) rotate(-180.000000) translate(-15.929230, -11.894737) &quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
&lt;/g&gt;
</code></pre>
<p></svg></td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color:#4CA64C;">✓</span></td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_right">13</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">13<br />1.00</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">0<br />0.00</td>
<td style="height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;" class="gt_row gt_center">—</td>
<td style="height: 40px; background-color: #FCFCFC;" class="gt_row gt_center">—</td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center">—</td>
<td style="height: 40px;" class="gt_row gt_center">—</td></p>
  </tr>
  <tr>
    <td style="height: 40px; background-color: #4CA64C66; color: transparent;font-size: 0px;" class="gt_row gt_left">#4CA64C66</td>
    <td style="height: 40px; color: #666666;font-size: 13px;font-weight: bold;" class="gt_row gt_right">2</td>
    <td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_left">
        <div style="margin: 0; padding: 0; display: inline-block; height: 30px; vertical-align: middle; width: 16%;">
            <!--?xml version="1.0" encoding="UTF-8"?--><?xml version="1.0" encoding="UTF-8"?>
<svg width="30px" height="30px" viewBox="0 0 67 67" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <title>col_vals_between</title>
    <g id="Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="col_vals_between" transform="translate(0.000000, 0.206897)">
            <path d="M56.712234,1 C59.1975153,1 61.4475153,2.00735931 63.076195,3.63603897 C64.7048747,5.26471863 65.712234,7.51471863 65.712234,10 L65.712234,10 L65.712234,65 L10.712234,65 C8.22695259,65 5.97695259,63.9926407 4.34827294,62.363961 C2.71959328,60.7352814 1.71223397,58.4852814 1.71223397,56 L1.71223397,56 L1.71223397,10 C1.71223397,7.51471863 2.71959328,5.26471863 4.34827294,3.63603897 C5.97695259,2.00735931 8.22695259,1 10.712234,1 L10.712234,1 Z" id="rectangle" stroke="#000000" stroke-width="2" fill="#FFFFFF"></path>
            <path d="M11.993484,21.96875 C10.962234,22.082031 10.188797,22.964844 10.212234,24 L10.212234,42 C10.200515,42.722656 10.579422,43.390625 11.204422,43.753906 C11.825515,44.121094 12.598953,44.121094 13.220047,43.753906 C13.845047,43.390625 14.223953,42.722656 14.212234,42 L14.212234,24 C14.220047,23.457031 14.009109,22.9375 13.626297,22.554688 C13.243484,22.171875 12.723953,21.960938 12.180984,21.96875 C12.118484,21.964844 12.055984,21.964844 11.993484,21.96875 Z M55.993484,21.96875 C54.962234,22.082031 54.188797,22.964844 54.212234,24 L54.212234,42 C54.200515,42.722656 54.579422,43.390625 55.204422,43.753906 C55.825515,44.121094 56.598953,44.121094 57.220047,43.753906 C57.845047,43.390625 58.223953,42.722656 58.212234,42 L58.212234,24 C58.220047,23.457031 58.009109,22.9375 57.626297,22.554688 C57.243484,22.171875 56.723953,21.960938 56.180984,21.96875 C56.118484,21.964844 56.055984,21.964844 55.993484,21.96875 Z M16.212234,22 C15.661453,22 15.212234,22.449219 15.212234,23 C15.212234,23.550781 15.661453,24 16.212234,24 C16.763015,24 17.212234,23.550781 17.212234,23 C17.212234,22.449219 16.763015,22 16.212234,22 Z M20.212234,22 C19.661453,22 19.212234,22.449219 19.212234,23 C19.212234,23.550781 19.661453,24 20.212234,24 C20.763015,24 21.212234,23.550781 21.212234,23 C21.212234,22.449219 20.763015,22 20.212234,22 Z M24.212234,22 C23.661453,22 23.212234,22.449219 23.212234,23 C23.212234,23.550781 23.661453,24 24.212234,24 C24.763015,24 25.212234,23.550781 25.212234,23 C25.212234,22.449219 24.763015,22 24.212234,22 Z M28.212234,22 C27.661453,22 27.212234,22.449219 27.212234,23 C27.212234,23.550781 27.661453,24 28.212234,24 C28.763015,24 29.212234,23.550781 29.212234,23 C29.212234,22.449219 28.763015,22 28.212234,22 Z M32.212234,22 C31.661453,22 31.212234,22.449219 31.212234,23 C31.212234,23.550781 31.661453,24 32.212234,24 C32.763015,24 33.212234,23.550781 33.212234,23 C33.212234,22.449219 32.763015,22 32.212234,22 Z M36.212234,22 C35.661453,22 35.212234,22.449219 35.212234,23 C35.212234,23.550781 35.661453,24 36.212234,24 C36.763015,24 37.212234,23.550781 37.212234,23 C37.212234,22.449219 36.763015,22 36.212234,22 Z M40.212234,22 C39.661453,22 39.212234,22.449219 39.212234,23 C39.212234,23.550781 39.661453,24 40.212234,24 C40.763015,24 41.212234,23.550781 41.212234,23 C41.212234,22.449219 40.763015,22 40.212234,22 Z M44.212234,22 C43.661453,22 43.212234,22.449219 43.212234,23 C43.212234,23.550781 43.661453,24 44.212234,24 C44.763015,24 45.212234,23.550781 45.212234,23 C45.212234,22.449219 44.763015,22 44.212234,22 Z M48.212234,22 C47.661453,22 47.212234,22.449219 47.212234,23 C47.212234,23.550781 47.661453,24 48.212234,24 C48.763015,24 49.212234,23.550781 49.212234,23 C49.212234,22.449219 48.763015,22 48.212234,22 Z M52.212234,22 C51.661453,22 51.212234,22.449219 51.212234,23 C51.212234,23.550781 51.661453,24 52.212234,24 C52.763015,24 53.212234,23.550781 53.212234,23 C53.212234,22.449219 52.763015,22 52.212234,22 Z M21.462234,27.96875 C21.419265,27.976563 21.376297,27.988281 21.337234,28 C21.177078,28.027344 21.02864,28.089844 20.899734,28.1875 L15.618484,32.1875 C15.356765,32.375 15.200515,32.679688 15.200515,33 C15.200515,33.320313 15.356765,33.625 15.618484,33.8125 L20.899734,37.8125 C21.348953,38.148438 21.985672,38.058594 22.321609,37.609375 C22.657547,37.160156 22.567703,36.523438 22.118484,36.1875 L19.212234,34 L49.212234,34 L46.305984,36.1875 C45.856765,36.523438 45.766922,37.160156 46.102859,37.609375 C46.438797,38.058594 47.075515,38.148438 47.524734,37.8125 L52.805984,33.8125 C53.067703,33.625 53.223953,33.320313 53.223953,33 C53.223953,32.679688 53.067703,32.375 52.805984,32.1875 L47.524734,28.1875 C47.30989,28.027344 47.040359,27.960938 46.774734,28 C46.743484,28 46.712234,28 46.680984,28 C46.282547,28.074219 45.96614,28.382813 45.884109,28.78125 C45.802078,29.179688 45.970047,29.585938 46.305984,29.8125 L49.212234,32 L19.212234,32 L22.118484,29.8125 C22.520828,29.566406 22.696609,29.070313 22.536453,28.625 C22.380203,28.179688 21.930984,27.90625 21.462234,27.96875 Z M16.212234,42 C15.661453,42 15.212234,42.449219 15.212234,43 C15.212234,43.550781 15.661453,44 16.212234,44 C16.763015,44 17.212234,43.550781 17.212234,43 C17.212234,42.449219 16.763015,42 16.212234,42 Z M20.212234,42 C19.661453,42 19.212234,42.449219 19.212234,43 C19.212234,43.550781 19.661453,44 20.212234,44 C20.763015,44 21.212234,43.550781 21.212234,43 C21.212234,42.449219 20.763015,42 20.212234,42 Z M24.212234,42 C23.661453,42 23.212234,42.449219 23.212234,43 C23.212234,43.550781 23.661453,44 24.212234,44 C24.763015,44 25.212234,43.550781 25.212234,43 C25.212234,42.449219 24.763015,42 24.212234,42 Z M28.212234,42 C27.661453,42 27.212234,42.449219 27.212234,43 C27.212234,43.550781 27.661453,44 28.212234,44 C28.763015,44 29.212234,43.550781 29.212234,43 C29.212234,42.449219 28.763015,42 28.212234,42 Z M32.212234,42 C31.661453,42 31.212234,42.449219 31.212234,43 C31.212234,43.550781 31.661453,44 32.212234,44 C32.763015,44 33.212234,43.550781 33.212234,43 C33.212234,42.449219 32.763015,42 32.212234,42 Z M36.212234,42 C35.661453,42 35.212234,42.449219 35.212234,43 C35.212234,43.550781 35.661453,44 36.212234,44 C36.763015,44 37.212234,43.550781 37.212234,43 C37.212234,42.449219 36.763015,42 36.212234,42 Z M40.212234,42 C39.661453,42 39.212234,42.449219 39.212234,43 C39.212234,43.550781 39.661453,44 40.212234,44 C40.763015,44 41.212234,43.550781 41.212234,43 C41.212234,42.449219 40.763015,42 40.212234,42 Z M44.212234,42 C43.661453,42 43.212234,42.449219 43.212234,43 C43.212234,43.550781 43.661453,44 44.212234,44 C44.763015,44 45.212234,43.550781 45.212234,43 C45.212234,42.449219 44.763015,42 44.212234,42 Z M48.212234,42 C47.661453,42 47.212234,42.449219 47.212234,43 C47.212234,43.550781 47.661453,44 48.212234,44 C48.763015,44 49.212234,43.550781 49.212234,43 C49.212234,42.449219 48.763015,42 48.212234,42 Z M52.212234,42 C51.661453,42 51.212234,42.449219 51.212234,43 C51.212234,43.550781 51.661453,44 52.212234,44 C52.763015,44 53.212234,43.550781 53.212234,43 C53.212234,42.449219 52.763015,42 52.212234,42 Z" id="inside_range" fill="#000000" fill-rule="nonzero"></path>
        </g>
    </g>
</svg>
        </div>
        <div style="font-family: 'IBM Plex Mono', monospace, courier; color: black; font-size: 10px; display: inline-block; vertical-align: middle;">
            <div>col_vals_between()</div>
        </div>
<pre><code>    &lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;d&lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;[0, 5000]&lt;/td&gt;
&lt;td style=&quot;height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;&quot; class=&quot;gt_row gt_center&quot;&gt;&lt;svg width=&quot;25px&quot; height=&quot;25px&quot; viewBox=&quot;0 0 25 25&quot; version=&quot;1.1&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot; style=&quot;vertical-align: middle;&quot;&gt;
&lt;g id=&quot;unchanged&quot; stroke=&quot;none&quot; stroke-width=&quot;1&quot; fill=&quot;none&quot; fill-rule=&quot;evenodd&quot;&gt;
    &lt;g id=&quot;unchanged&quot; transform=&quot;translate(0.500000, 0.570147)&quot;&gt;
        &lt;rect id=&quot;Rectangle&quot; x=&quot;0.125132506&quot; y=&quot;0&quot; width=&quot;23.749735&quot; height=&quot;23.7894737&quot;&gt;&lt;/rect&gt;
        &lt;path d=&quot;M5.80375046,8.18194736 C3.77191832,8.18194736 2.11875046,9.83495328 2.11875046,11.8669474 C2.11875046,13.8989414 3.77191832,15.5519474 5.80375046,15.5519474 C7.8355826,15.5519474 9.48875046,13.8989414 9.48875046,11.8669474 C9.48875046,9.83495328 7.83552863,8.18194736 5.80375046,8.18194736 Z M5.80375046,14.814915 C4.17821997,14.814915 2.85578285,13.4924778 2.85578285,11.8669474 C2.85578285,10.2414169 4.17821997,8.91897975 5.80375046,8.91897975 C7.42928095,8.91897975 8.75171807,10.2414169 8.75171807,11.8669474 C8.75171807,13.4924778 7.42928095,14.814915 5.80375046,14.814915 Z&quot; id=&quot;Shape&quot; fill=&quot;#000000&quot; fill-rule=&quot;nonzero&quot;&gt;&lt;/path&gt;
        &lt;path d=&quot;M13.9638189,8.699335 C13.9364621,8.70430925 13.9091059,8.71176968 13.8842359,8.71923074 C13.7822704,8.73663967 13.6877654,8.77643115 13.6056956,8.83860518 L10.2433156,11.3852598 C10.0766886,11.5046343 9.97720993,11.6986181 9.97720993,11.9025491 C9.97720993,12.1064807 10.0766886,12.3004639 10.2433156,12.4198383 L13.6056956,14.966493 C13.891697,15.1803725 14.2970729,15.1231721 14.5109517,14.8371707 C14.7248313,14.5511692 14.6676309,14.145794 14.3816294,13.9319145 L12.5313257,12.5392127 L21.8812495,12.5392127 L21.8812495,11.2658854 L12.5313257,11.2658854 L14.3816294,9.87318364 C14.6377872,9.71650453 14.7497006,9.40066014 14.6477351,9.11714553 C14.5482564,8.83363156 14.262255,8.65954352 13.9638189,8.699335 Z&quot; id=&quot;arrow&quot; fill=&quot;#000000&quot; transform=&quot;translate(15.929230, 11.894737) rotate(-180.000000) translate(-15.929230, -11.894737) &quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
&lt;/g&gt;
</code></pre>
<p></svg></td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color:#4CA64C;">✓</span></td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_right">13</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">12<br />0.92</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">1<br />0.08</td>
<td style="height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;" class="gt_row gt_center">—</td>
<td style="height: 40px; background-color: #FCFCFC;" class="gt_row gt_center">—</td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center">—</td>
<td style="height: 40px;" class="gt_row gt_center"><a href="data:text/csv;base64,X3Jvd19udW1fLGRhdGVfdGltZSxkYXRlLGEsYixjLGQsZSxmCjIsMjAxNi0wMS0wNFQwMDozMjowMC4wMDAwMDAsMjAxNi0wMS0wNCwzLDUtZWdoLTE2Myw4LDk5OTkuOTksdHJ1ZSxsb3cK" download="extract_0002.csv"><button style="background-color: #67C2DC; color: #FFFFFF; border: none; padding: 5px; font-weight: bold; cursor: pointer; border-radius: 4px;">CSV</button></a></td></p>
  </tr>
  <tr>
    <td style="height: 40px; background-color: #4CA64C; color: transparent;font-size: 0px;" class="gt_row gt_left">#4CA64C</td>
    <td style="height: 40px; color: #666666;font-size: 13px;font-weight: bold;" class="gt_row gt_right">3</td>
    <td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_left">
        <div style="margin: 0; padding: 0; display: inline-block; height: 30px; vertical-align: middle; width: 16%;">
            <!--?xml version="1.0" encoding="UTF-8"?--><?xml version="1.0" encoding="UTF-8"?>
<svg width="30px" height="30px" viewBox="0 0 67 67" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <title>col_vals_in_set</title>
    <g id="Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="col_vals_in_set" transform="translate(0.000000, 0.172414)">
            <path d="M56.712234,1 C59.1975153,1 61.4475153,2.00735931 63.076195,3.63603897 C64.7048747,5.26471863 65.712234,7.51471863 65.712234,10 L65.712234,10 L65.712234,65 L10.712234,65 C8.22695259,65 5.97695259,63.9926407 4.34827294,62.363961 C2.71959328,60.7352814 1.71223397,58.4852814 1.71223397,56 L1.71223397,56 L1.71223397,10 C1.71223397,7.51471863 2.71959328,5.26471863 4.34827294,3.63603897 C5.97695259,2.00735931 8.22695259,1 10.712234,1 L10.712234,1 Z" id="rectangle" stroke="#000000" stroke-width="2" fill="#FFFFFF"></path>
            <path d="M44.127969,41.1538382 L31.0814568,41.1538382 C29.9510748,41.1536429 28.8827052,40.9256134 27.9079888,40.5136953 C26.4467442,39.8960136 25.19849,38.8599685 24.3189894,37.5577099 C23.8792391,36.906727 23.5314818,36.1899233 23.2936866,35.4252675 C23.2130217,35.16589 23.1460289,34.9005554 23.0913409,34.6307286 L44.1278714,34.6307286 C45.028466,34.6306309 45.7586488,33.9004481 45.7586488,32.9998535 C45.7586488,32.0992589 45.028466,31.3690761 44.1278714,31.3690761 L23.0905596,31.3690761 C23.1990567,30.8337194 23.3597028,30.3180894 23.5675173,29.8264831 C24.185199,28.3652386 25.2212442,27.1169844 26.5236004,26.2374838 C27.1745833,25.7977334 27.891387,25.4499762 28.6560428,25.2122786 C29.4208939,24.9744833 30.2334994,24.8459665 31.0813591,24.8459665 L44.1277737,24.8459665 C45.0283683,24.8459665 45.7586488,24.1157837 45.7586488,23.2151891 C45.7586488,22.3145945 45.0283683,21.5844117 44.1277737,21.5844117 L31.0813591,21.5844117 C29.5096643,21.5844117 28.0039858,21.9038483 26.6373711,22.4820765 C24.5866678,23.3498583 22.8469049,24.7950871 21.6163267,26.616296 C20.3856508,28.4362354 19.665136,30.6413347 19.6658191,33.0000488 C19.6658191,34.5717436 19.9852563,36.0774222 20.5635822,37.4440369 C21.4312663,39.4947402 22.8765927,41.2345031 24.697704,42.4650813 C26.5176434,43.6957572 28.7227427,44.4155883 31.0814568,44.4155883 L44.1278714,44.4155883 C45.028466,44.4155883 45.7586488,43.6854055 45.7586488,42.7848109 C45.7586488,41.8842163 45.0285636,41.1538382 44.127969,41.1538382 Z" id="set_of" fill="#000000" fill-rule="nonzero"></path>
        </g>
    </g>
</svg>
        </div>
        <div style="font-family: 'IBM Plex Mono', monospace, courier; color: black; font-size: 11px; display: inline-block; vertical-align: middle;">
            <div>col_vals_in_set()</div>
        </div>
<pre><code>    &lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;f&lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;low, mid, high&lt;/td&gt;
&lt;td style=&quot;height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;&quot; class=&quot;gt_row gt_center&quot;&gt;&lt;svg width=&quot;25px&quot; height=&quot;25px&quot; viewBox=&quot;0 0 25 25&quot; version=&quot;1.1&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot; style=&quot;vertical-align: middle;&quot;&gt;
&lt;g id=&quot;unchanged&quot; stroke=&quot;none&quot; stroke-width=&quot;1&quot; fill=&quot;none&quot; fill-rule=&quot;evenodd&quot;&gt;
    &lt;g id=&quot;unchanged&quot; transform=&quot;translate(0.500000, 0.570147)&quot;&gt;
        &lt;rect id=&quot;Rectangle&quot; x=&quot;0.125132506&quot; y=&quot;0&quot; width=&quot;23.749735&quot; height=&quot;23.7894737&quot;&gt;&lt;/rect&gt;
        &lt;path d=&quot;M5.80375046,8.18194736 C3.77191832,8.18194736 2.11875046,9.83495328 2.11875046,11.8669474 C2.11875046,13.8989414 3.77191832,15.5519474 5.80375046,15.5519474 C7.8355826,15.5519474 9.48875046,13.8989414 9.48875046,11.8669474 C9.48875046,9.83495328 7.83552863,8.18194736 5.80375046,8.18194736 Z M5.80375046,14.814915 C4.17821997,14.814915 2.85578285,13.4924778 2.85578285,11.8669474 C2.85578285,10.2414169 4.17821997,8.91897975 5.80375046,8.91897975 C7.42928095,8.91897975 8.75171807,10.2414169 8.75171807,11.8669474 C8.75171807,13.4924778 7.42928095,14.814915 5.80375046,14.814915 Z&quot; id=&quot;Shape&quot; fill=&quot;#000000&quot; fill-rule=&quot;nonzero&quot;&gt;&lt;/path&gt;
        &lt;path d=&quot;M13.9638189,8.699335 C13.9364621,8.70430925 13.9091059,8.71176968 13.8842359,8.71923074 C13.7822704,8.73663967 13.6877654,8.77643115 13.6056956,8.83860518 L10.2433156,11.3852598 C10.0766886,11.5046343 9.97720993,11.6986181 9.97720993,11.9025491 C9.97720993,12.1064807 10.0766886,12.3004639 10.2433156,12.4198383 L13.6056956,14.966493 C13.891697,15.1803725 14.2970729,15.1231721 14.5109517,14.8371707 C14.7248313,14.5511692 14.6676309,14.145794 14.3816294,13.9319145 L12.5313257,12.5392127 L21.8812495,12.5392127 L21.8812495,11.2658854 L12.5313257,11.2658854 L14.3816294,9.87318364 C14.6377872,9.71650453 14.7497006,9.40066014 14.6477351,9.11714553 C14.5482564,8.83363156 14.262255,8.65954352 13.9638189,8.699335 Z&quot; id=&quot;arrow&quot; fill=&quot;#000000&quot; transform=&quot;translate(15.929230, 11.894737) rotate(-180.000000) translate(-15.929230, -11.894737) &quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
&lt;/g&gt;
</code></pre>
<p></svg></td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color:#4CA64C;">✓</span></td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_right">13</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">13<br />1.00</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">0<br />0.00</td>
<td style="height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;" class="gt_row gt_center">—</td>
<td style="height: 40px; background-color: #FCFCFC;" class="gt_row gt_center">—</td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center">—</td>
<td style="height: 40px;" class="gt_row gt_center">—</td></p>
  </tr>
  <tr>
    <td style="height: 40px; background-color: #4CA64C; color: transparent;font-size: 0px;" class="gt_row gt_left">#4CA64C</td>
    <td style="height: 40px; color: #666666;font-size: 13px;font-weight: bold;" class="gt_row gt_right">4</td>
    <td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_left">
        <div style="margin: 0; padding: 0; display: inline-block; height: 30px; vertical-align: middle; width: 16%;">
            <!--?xml version="1.0" encoding="UTF-8"?--><?xml version="1.0" encoding="UTF-8"?>
<svg width="30px" height="30px" viewBox="0 0 67 67" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <title>col_vals_regex</title>
    <g id="Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="col_vals_regex" transform="translate(0.000000, 0.034483)">
            <path d="M56.712234,1 C59.1975153,1 61.4475153,2.00735931 63.076195,3.63603897 C64.7048747,5.26471863 65.712234,7.51471863 65.712234,10 L65.712234,10 L65.712234,65 L10.712234,65 C8.22695259,65 5.97695259,63.9926407 4.34827294,62.363961 C2.71959328,60.7352814 1.71223397,58.4852814 1.71223397,56 L1.71223397,56 L1.71223397,10 C1.71223397,7.51471863 2.71959328,5.26471863 4.34827294,3.63603897 C5.97695259,2.00735931 8.22695259,1 10.712234,1 L10.712234,1 Z" id="rectangle" stroke="#000000" stroke-width="2" fill="#FFFFFF"></path>
            <g id="regex_symbols" transform="translate(18.000000, 12.000000)" fill="#000000" fill-rule="nonzero">
                <path d="M4.17434508,33.013582 C1.94895328,33.013582 0.138006923,34.8245284 0.138006923,37.0499202 C0.138006923,39.275312 1.94895328,41.0862583 4.17434508,41.0862583 C6.39973688,41.0862583 8.21068324,39.275312 8.21068324,37.0499202 C8.21068324,34.8245284 6.39973688,33.013582 4.17434508,33.013582 Z" id="full_stop"></path>
                <path d="M23.9479718,23.3175402 L21.5628264,23.3175402 C21.2344032,23.3175402 20.9665401,23.0520067 20.9665401,22.7212538 L20.9665401,15.1022979 L14.3445004,18.8873192 C14.0626621,19.050366 13.7016292,18.952538 13.5362533,18.6706991 L12.3436806,16.6442575 C12.262157,16.506832 12.2388642,16.3437852 12.2807909,16.1900549 C12.3203879,16.0363251 12.4205455,15.9058874 12.557971,15.8266929 L19.1800101,11.9880994 L12.557971,8.15183511 C12.4205455,8.07264112 12.3203879,7.93987439 12.2807909,7.78614401 C12.2388642,7.63241423 12.262157,7.46936689 12.3413509,7.33194137 L13.5339237,5.30549975 C13.6993001,5.02366143 14.0626621,4.92816199 14.3445004,5.09120934 L20.9665401,8.87390091 L20.9665401,1.25494501 C20.9665401,0.926521818 21.2344032,0.658658658 21.5628264,0.658658658 L23.9479718,0.658658658 C24.2787247,0.658658658 24.5442582,0.926521818 24.5442582,1.25494501 L24.5442582,8.87390091 L31.1662979,5.09120934 C31.4481362,4.92816199 31.8091691,5.02366143 31.9745455,5.30549975 L33.1671182,7.33194137 C33.2486413,7.46936689 33.2719341,7.63241423 33.2300074,7.78614401 C33.1904104,7.93987439 33.0902528,8.07264112 32.9528278,8.15183511 L26.3307882,11.9880994 L32.9528278,15.8243638 C33.0879237,15.9058874 33.1880813,16.0363251 33.2300074,16.1900549 C33.269605,16.3437852 33.2486413,16.506832 33.1671182,16.6442575 L31.9745455,18.6706991 C31.8091691,18.952538 31.4481362,19.050366 31.1662979,18.8849895 L24.5442582,15.1022979 L24.5442582,22.7212538 C24.5442582,23.0520067 24.2787247,23.3175402 23.9479718,23.3175402 Z" id="asterisk"></path>
            </g>
        </g>
    </g>
</svg>
        </div>
        <div style="font-family: 'IBM Plex Mono', monospace, courier; color: black; font-size: 11px; display: inline-block; vertical-align: middle;">
            <div>col_vals_regex()</div>
        </div>
<pre><code>    &lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;b&lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;^[0-9]-[a-z]{3}-[0-9]{3}$&lt;/td&gt;
&lt;td style=&quot;height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;&quot; class=&quot;gt_row gt_center&quot;&gt;&lt;svg width=&quot;25px&quot; height=&quot;25px&quot; viewBox=&quot;0 0 25 25&quot; version=&quot;1.1&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot; style=&quot;vertical-align: middle;&quot;&gt;
&lt;g id=&quot;unchanged&quot; stroke=&quot;none&quot; stroke-width=&quot;1&quot; fill=&quot;none&quot; fill-rule=&quot;evenodd&quot;&gt;
    &lt;g id=&quot;unchanged&quot; transform=&quot;translate(0.500000, 0.570147)&quot;&gt;
        &lt;rect id=&quot;Rectangle&quot; x=&quot;0.125132506&quot; y=&quot;0&quot; width=&quot;23.749735&quot; height=&quot;23.7894737&quot;&gt;&lt;/rect&gt;
        &lt;path d=&quot;M5.80375046,8.18194736 C3.77191832,8.18194736 2.11875046,9.83495328 2.11875046,11.8669474 C2.11875046,13.8989414 3.77191832,15.5519474 5.80375046,15.5519474 C7.8355826,15.5519474 9.48875046,13.8989414 9.48875046,11.8669474 C9.48875046,9.83495328 7.83552863,8.18194736 5.80375046,8.18194736 Z M5.80375046,14.814915 C4.17821997,14.814915 2.85578285,13.4924778 2.85578285,11.8669474 C2.85578285,10.2414169 4.17821997,8.91897975 5.80375046,8.91897975 C7.42928095,8.91897975 8.75171807,10.2414169 8.75171807,11.8669474 C8.75171807,13.4924778 7.42928095,14.814915 5.80375046,14.814915 Z&quot; id=&quot;Shape&quot; fill=&quot;#000000&quot; fill-rule=&quot;nonzero&quot;&gt;&lt;/path&gt;
        &lt;path d=&quot;M13.9638189,8.699335 C13.9364621,8.70430925 13.9091059,8.71176968 13.8842359,8.71923074 C13.7822704,8.73663967 13.6877654,8.77643115 13.6056956,8.83860518 L10.2433156,11.3852598 C10.0766886,11.5046343 9.97720993,11.6986181 9.97720993,11.9025491 C9.97720993,12.1064807 10.0766886,12.3004639 10.2433156,12.4198383 L13.6056956,14.966493 C13.891697,15.1803725 14.2970729,15.1231721 14.5109517,14.8371707 C14.7248313,14.5511692 14.6676309,14.145794 14.3816294,13.9319145 L12.5313257,12.5392127 L21.8812495,12.5392127 L21.8812495,11.2658854 L12.5313257,11.2658854 L14.3816294,9.87318364 C14.6377872,9.71650453 14.7497006,9.40066014 14.6477351,9.11714553 C14.5482564,8.83363156 14.262255,8.65954352 13.9638189,8.699335 Z&quot; id=&quot;arrow&quot; fill=&quot;#000000&quot; transform=&quot;translate(15.929230, 11.894737) rotate(-180.000000) translate(-15.929230, -11.894737) &quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
&lt;/g&gt;
</code></pre>
<p></svg></td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color:#4CA64C;">✓</span></td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_right">13</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">13<br />1.00</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">0<br />0.00</td>
<td style="height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;" class="gt_row gt_center">—</td>
<td style="height: 40px; background-color: #FCFCFC;" class="gt_row gt_center">—</td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center">—</td>
<td style="height: 40px;" class="gt_row gt_center">—</td></p>
  </tr>
</tbody>
  <tfoot class="gt_sourcenotes">
  <tr>
    <td class="gt_sourcenote" colspan="14" style="text-align: left;"><div style='margin-top: 5px; margin-bottom: 5px;'><span style='background-color: #FFF; color: #444; padding: 0.5em 0.5em; position: inherit; text-transform: uppercase; margin-left: 10px; margin-right: 5px; border: solid 1px #999999; font-variant-numeric: tabular-nums; border-radius: 0; padding: 2px 10px 2px 10px;'>2026-04-02 19:07:32 UTC</span><span style='background-color: #FFF; color: #444; padding: 0.5em 0.5em; position: inherit; margin-right: 5px; border: solid 1px #999999; font-variant-numeric: tabular-nums; border-radius: 0; padding: 2px 10px 2px 10px;'>< 1 s</span><span style='background-color: #FFF; color: #444; padding: 0.5em 0.5em; position: inherit; text-transform: uppercase; margin: 5px 1px 5px -1px; border: solid 1px #999999; font-variant-numeric: tabular-nums; border-radius: 0; padding: 2px 10px 2px 10px;'>2026-04-02 19:07:32 UTC</span></div></td>
  </tr>
</tfoot>
</table>
</div>
<p>There&rsquo;s a lot to take in here so let&rsquo;s break down the code first! Note these three key pieces:</p>
<ul>
<li>the <code>Validate(data=...)</code> argument takes a DataFrame (or database table) that you want to validate</li>
<li>the methods starting with <code>col_*</code> specify validation steps that run on specific columns</li>
<li>the <code>interrogate()</code> method executes the validation plan on the table (it&rsquo;s the finishing step)</li>
</ul>
<p>This common pattern is used in a validation workflow, where
<a href="https://posit-dev.github.io/pointblank/reference/Validate.html" target="_blank" rel="noopener"><code>Validate</code></a>
 and
<a href="https://posit-dev.github.io/pointblank/reference/Validate.interrogate.html" target="_blank" rel="noopener"><code>interrogate()</code></a>

bookend a validation plan generated through calling validation methods.</p>
<p>Now, onto the result: it&rsquo;s a table! Naturally, we&rsquo;re using the awesome Great Tables package here in
Pointblank to really give you the goods on how the validation went down. Each row in this reporting
table represents a single validation step (one for each invocation of a <code>col_vals_*()</code> validation
method). Generally speaking, the left side of the validation report tables outlines the key
validation rules, and the right side provides the results of each validation step.</p>
<p>We tried to keep it simple in principle, but a lot of useful information can be packed into this
validation table. Here&rsquo;s a diagram that describes a few of the important parts of the validation
report table:</p>
<img src="https://posit-open-source.netlify.app/blog/pointblank/intro-pointblank/validation-table-diagram.png" style="width:100.0%" />
<p>All of those numbers under the <code>UNITS</code>, <code>PASS</code>, and <code>FAIL</code> columns have to do with test units, a
measure of central importance in Pointblank. Each validation step will execute a type of validation
test on the target table. For example, a
<a href="https://posit-dev.github.io/pointblank/reference/Validate.col_vals_lt.html" target="_blank" rel="noopener"><code>col_vals_lt()</code></a>

validation step can test that each value in a column is less than a specified number. The key
finding that&rsquo;s reported as a result of this test is the number of test units that pass or fail. This
little diagram explains what those numbers mean:</p>
<img src="https://posit-open-source.netlify.app/blog/pointblank/intro-pointblank/validation-test-units.png" data-text-align="center" />
<p>Failing test units can be tied to threshold levels, which can provide a better indication of whether
failures should raise some basic awareness or spur you into action. Here&rsquo;s a validation workflow
that sets three failure threshold levels that signal the severity of data quality problems:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">pointblank</span> <span class="k">as</span> <span class="nn">pb</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">polars</span> <span class="k">as</span> <span class="nn">pl</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">validation_2</span> <span class="o">=</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">pb</span><span class="o">.</span><span class="n">Validate</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="n">data</span><span class="o">=</span><span class="n">pb</span><span class="o">.</span><span class="n">load_dataset</span><span class="p">(</span><span class="n">dataset</span><span class="o">=</span><span class="s2">&#34;game_revenue&#34;</span><span class="p">,</span> <span class="n">tbl_type</span><span class="o">=</span><span class="s2">&#34;polars&#34;</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">        <span class="n">tbl_name</span><span class="o">=</span><span class="s2">&#34;game_revenue&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="n">label</span><span class="o">=</span><span class="s2">&#34;Data validation with threshold levels set.&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="n">thresholds</span><span class="o">=</span><span class="n">pb</span><span class="o">.</span><span class="n">Thresholds</span><span class="p">(</span><span class="n">warning</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">error</span><span class="o">=</span><span class="mi">20</span><span class="p">,</span> <span class="n">critical</span><span class="o">=</span><span class="mf">0.10</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">    <span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">col_vals_regex</span><span class="p">(</span><span class="n">columns</span><span class="o">=</span><span class="s2">&#34;player_id&#34;</span><span class="p">,</span> <span class="n">pattern</span><span class="o">=</span><span class="sa">r</span><span class="s2">&#34;^[A-Z]</span><span class="si">{12}</span><span class="s2">[0-9]</span><span class="si">{3}</span><span class="s2">$&#34;</span><span class="p">)</span>        <span class="c1"># STEP 1</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">col_vals_gt</span><span class="p">(</span><span class="n">columns</span><span class="o">=</span><span class="s2">&#34;session_duration&#34;</span><span class="p">,</span> <span class="n">value</span><span class="o">=</span><span class="mi">5</span><span class="p">)</span>                           <span class="c1"># STEP 2</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">col_vals_ge</span><span class="p">(</span><span class="n">columns</span><span class="o">=</span><span class="s2">&#34;item_revenue&#34;</span><span class="p">,</span> <span class="n">value</span><span class="o">=</span><span class="mf">0.02</span><span class="p">)</span>                            <span class="c1"># STEP 3</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">col_vals_in_set</span><span class="p">(</span><span class="n">columns</span><span class="o">=</span><span class="s2">&#34;item_type&#34;</span><span class="p">,</span> <span class="nb">set</span><span class="o">=</span><span class="p">[</span><span class="s2">&#34;iap&#34;</span><span class="p">,</span> <span class="s2">&#34;ad&#34;</span><span class="p">])</span>                    <span class="c1"># STEP 4</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">col_vals_in_set</span><span class="p">(</span>                                                           <span class="c1"># STEP 5</span>
</span></span><span class="line"><span class="cl">        <span class="n">columns</span><span class="o">=</span><span class="s2">&#34;acquisition&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nb">set</span><span class="o">=</span><span class="p">[</span><span class="s2">&#34;google&#34;</span><span class="p">,</span> <span class="s2">&#34;facebook&#34;</span><span class="p">,</span> <span class="s2">&#34;organic&#34;</span><span class="p">,</span> <span class="s2">&#34;crosspromo&#34;</span><span class="p">,</span> <span class="s2">&#34;other_campaign&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">    <span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">col_vals_not_in_set</span><span class="p">(</span><span class="n">columns</span><span class="o">=</span><span class="s2">&#34;country&#34;</span><span class="p">,</span> <span class="nb">set</span><span class="o">=</span><span class="p">[</span><span class="s2">&#34;Mongolia&#34;</span><span class="p">,</span> <span class="s2">&#34;Germany&#34;</span><span class="p">])</span>        <span class="c1"># STEP 6</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">col_vals_between</span><span class="p">(</span>                                                          <span class="c1"># STEP 7</span>
</span></span><span class="line"><span class="cl">        <span class="n">columns</span><span class="o">=</span><span class="s2">&#34;session_duration&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="n">left</span><span class="o">=</span><span class="mi">10</span><span class="p">,</span> <span class="n">right</span><span class="o">=</span><span class="mi">50</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="n">pre</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">df</span><span class="p">:</span> <span class="n">df</span><span class="o">.</span><span class="n">select</span><span class="p">(</span><span class="n">pl</span><span class="o">.</span><span class="n">median</span><span class="p">(</span><span class="s2">&#34;session_duration&#34;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">    <span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">rows_distinct</span><span class="p">(</span><span class="n">columns_subset</span><span class="o">=</span><span class="p">[</span><span class="s2">&#34;player_id&#34;</span><span class="p">,</span> <span class="s2">&#34;session_id&#34;</span><span class="p">,</span> <span class="s2">&#34;time&#34;</span><span class="p">])</span>          <span class="c1"># STEP 8</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">row_count_match</span><span class="p">(</span><span class="n">count</span><span class="o">=</span><span class="mi">2000</span><span class="p">)</span>                                                <span class="c1"># STEP 9</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">col_exists</span><span class="p">(</span><span class="n">columns</span><span class="o">=</span><span class="s2">&#34;start_day&#34;</span><span class="p">)</span>                                            <span class="c1"># STEP 10</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">interrogate</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">validation_2</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div id="pb_tbl" style="padding-left:0px;padding-right:0px;padding-top:10px;padding-bottom:10px;overflow-x:auto;overflow-y:auto;width:auto;height:auto;">
<style>
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono&display=swap');
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans&display=swap');
#pb_tbl table {
          font-family: 'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Helvetica Neue', 'Fira Sans', 'Droid Sans', Arial, sans-serif;
          -webkit-font-smoothing: antialiased;
          -moz-osx-font-smoothing: grayscale;
        }
<p>#pb_tbl thead, tbody, tfoot, tr, td, th { border-style: none; }
tr { background-color: transparent; }
#pb_tbl p { margin: 0; padding: 0; }
#pb_tbl .gt_table { display: table; border-collapse: collapse; line-height: normal; margin-left: auto; margin-right: auto; color: #333333; font-size: 90%; font-weight: normal; font-style: normal; background-color: #FFFFFF; width: auto; border-top-style: solid; border-top-width: 2px; border-top-color: #A8A8A8; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #A8A8A8; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; }
#pb_tbl .gt_caption { padding-top: 4px; padding-bottom: 4px; }
#pb_tbl .gt_title { color: #333333; font-size: 125%; font-weight: initial; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; border-bottom-color: #FFFFFF; border-bottom-width: 0; }
#pb_tbl .gt_subtitle { color: #333333; font-size: 85%; font-weight: initial; padding-top: 3px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; border-top-color: #FFFFFF; border-top-width: 0; }
#pb_tbl .gt_heading { background-color: #FFFFFF; text-align: left; border-bottom-color: #FFFFFF; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; }
#pb_tbl .gt_bottom_border { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; }
#pb_tbl .gt_col_headings { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; }
#pb_tbl .gt_col_heading { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; overflow-x: hidden; }
#pb_tbl .gt_column_spanner_outer { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; padding-top: 0; padding-bottom: 0; padding-left: 4px; padding-right: 4px; }
#pb_tbl .gt_column_spanner_outer:first-child { padding-left: 0; }
#pb_tbl .gt_column_spanner_outer:last-child { padding-right: 0; }
#pb_tbl .gt_column_spanner { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; overflow-x: hidden; display: inline-block; width: 100%; }
#pb_tbl .gt_spanner_row { border-bottom-style: hidden; }
#pb_tbl .gt_group_heading { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; text-align: left; }
#pb_tbl .gt_empty_group_heading { padding: 0.5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: middle; }
#pb_tbl .gt_from_md&gt; :first-child { margin-top: 0; }
#pb_tbl .gt_from_md&gt; :last-child { margin-bottom: 0; }
#pb_tbl .gt_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; margin: 10px; border-top-style: solid; border-top-width: 1px; border-top-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; overflow-x: hidden; }
#pb_tbl .gt_stub { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; }
#pb_tbl .gt_stub_row_group { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; vertical-align: top; }
#pb_tbl .gt_row_group_first td { border-top-width: 2px; }
#pb_tbl .gt_row_group_first th { border-top-width: 2px; }
#pb_tbl .gt_striped { color: #333333; background-color: #F4F4F4; }
#pb_tbl .gt_table_body { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; }
#pb_tbl .gt_grand_summary_row { color: #333333; background-color: #FFFFFF; text-transform: inherit; padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; }
#pb_tbl .gt_first_grand_summary_row_bottom { border-top-style: double; border-top-width: 6px; border-top-color: #D3D3D3; }
#pb_tbl .gt_last_grand_summary_row_top { border-bottom-style: double; border-bottom-width: 6px; border-bottom-color: #D3D3D3; }
#pb_tbl .gt_sourcenotes { color: #333333; background-color: #FFFFFF; border-bottom-style: none; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; }
#pb_tbl .gt_sourcenote { font-size: 90%; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; text-align: left; }
#pb_tbl .gt_left { text-align: left; }
#pb_tbl .gt_center { text-align: center; }
#pb_tbl .gt_right { text-align: right; font-variant-numeric: tabular-nums; }
#pb_tbl .gt_font_normal { font-weight: normal; }
#pb_tbl .gt_font_bold { font-weight: bold; }
#pb_tbl .gt_font_italic { font-style: italic; }
#pb_tbl .gt_super { font-size: 65%; }
#pb_tbl .gt_footnote_marks { font-size: 75%; vertical-align: 0.4em; position: initial; }
#pb_tbl .gt_asterisk { font-size: 100%; vertical-align: 0; }</p>
<p></style></p>
<table style="table-layout: fixed;; width: 0px" class="gt_table" data-quarto-disable-processing="true" data-quarto-bootstrap="false">
<colgroup>
  <col style="width:4px;"/>
  <col style="width:35px;"/>
  <col style="width:190px;"/>
  <col style="width:120px;"/>
  <col style="width:120px;"/>
  <col style="width:50px;"/>
  <col style="width:50px;"/>
  <col style="width:60px;"/>
  <col style="width:60px;"/>
  <col style="width:60px;"/>
  <col style="width:30px;"/>
  <col style="width:30px;"/>
  <col style="width:30px;"/>
  <col style="width:65px;"/>
</colgroup>
<thead>
  <tr class="gt_heading">
    <td colspan="14" class="gt_heading gt_title gt_font_normal" style="color: #444444;font-size: 28px;text-align: left;font-weight: bold; text-align: left;">Pointblank Validation</td>
  </tr>
  <tr class="gt_heading">
    <td colspan="14" class="gt_heading gt_subtitle gt_font_normal gt_bottom_border" style="text-align: left;"><div><span style='text-decoration-style: solid; text-decoration-color: #ADD8E6; text-decoration-line: underline; text-underline-position: under; color: #333333; font-variant-numeric: tabular-nums; padding-left: 4px; margin-right: 5px; padding-right: 2px;'>Data validation with threshold levels set.</span><div style="padding-top: 10px; padding-bottom: 5px;"><span style='background-color: #0075FF; color: #FFFFFF; padding: 0.5em 0.5em; position: inherit; text-transform: uppercase; margin: 5px 0px 5px 0px; border: solid 1px #0075FF; font-weight: bold; padding: 2px 15px 2px 15px; font-size: 10px;'>Polars</span><span style='background-color: none; color: #222222; padding: 0.5em 0.5em; position: inherit; margin: 5px 10px 5px -4px; border: solid 1px #0075FF; font-weight: bold; padding: 2px 15px 2px 15px; font-size: 10px;'>game_revenue</span><span><span style="background-color: #AAAAAA; color: white; padding: 0.5em 0.5em; position: inherit; text-transform: uppercase; margin: 5px 0px 5px 5px; border: solid 1px #AAAAAA; font-weight: bold; padding: 2px 15px 2px 15px; font-size: smaller;">WARNING</span><span style="background-color: none; color: #333333; padding: 0.5em 0.5em; position: inherit; margin: 5px 0px 5px -4px; font-weight: bold; border: solid 1px #AAAAAA; padding: 2px 15px 2px 15px; font-size: smaller; margin-right: 5px;">1</span><span style="background-color: #EBBC14; color: white; padding: 0.5em 0.5em; position: inherit; text-transform: uppercase; margin: 5px 0px 5px 1px; border: solid 1px #EBBC14; font-weight: bold; padding: 2px 15px 2px 15px; font-size: smaller;">ERROR</span><span style="background-color: none; color: #333333; padding: 0.5em 0.5em; position: inherit; margin: 5px 0px 5px -4px; font-weight: bold; border: solid 1px #EBBC14; padding: 2px 15px 2px 15px; font-size: smaller; margin-right: 5px;">20</span><span style="background-color: #FF3300; color: white; padding: 0.5em 0.5em; position: inherit; text-transform: uppercase; margin: 5px 0px 5px 1px; border: solid 1px #FF3300; font-weight: bold; padding: 2px 15px 2px 15px; font-size: smaller;">CRITICAL</span><span style="background-color: none; color: #333333; padding: 0.5em 0.5em; position: inherit; margin: 5px 0px 5px -4px; font-weight: bold; border: solid 1px #FF3300; padding: 2px 15px 2px 15px; font-size: smaller;">0.1</span></span></div></div></td>
  </tr>
<tr class="gt_col_headings">
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-status_color"></th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-i"></th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-type_upd">STEP</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-columns_upd">COLUMNS</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-values_upd">VALUES</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-tbl">TBL</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-eval">EVAL</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-test_units">UNITS</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-pass">PASS</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-fail">FAIL</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-w_upd">W</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-e_upd">E</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-c_upd">C</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-extract_upd">EXT</th>
</tr>
</thead>
<tbody class="gt_table_body">
  <tr>
    <td style="height: 40px; background-color: #4CA64C; color: transparent;font-size: 0px;" class="gt_row gt_left">#4CA64C</td>
    <td style="height: 40px; color: #666666;font-size: 13px;font-weight: bold;" class="gt_row gt_right">1</td>
    <td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_left">
        <div style="margin: 0; padding: 0; display: inline-block; height: 30px; vertical-align: middle; width: 16%;">
            <!--?xml version="1.0" encoding="UTF-8"?--><?xml version="1.0" encoding="UTF-8"?>
<svg width="30px" height="30px" viewBox="0 0 67 67" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <title>col_vals_regex</title>
    <g id="Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="col_vals_regex" transform="translate(0.000000, 0.034483)">
            <path d="M56.712234,1 C59.1975153,1 61.4475153,2.00735931 63.076195,3.63603897 C64.7048747,5.26471863 65.712234,7.51471863 65.712234,10 L65.712234,10 L65.712234,65 L10.712234,65 C8.22695259,65 5.97695259,63.9926407 4.34827294,62.363961 C2.71959328,60.7352814 1.71223397,58.4852814 1.71223397,56 L1.71223397,56 L1.71223397,10 C1.71223397,7.51471863 2.71959328,5.26471863 4.34827294,3.63603897 C5.97695259,2.00735931 8.22695259,1 10.712234,1 L10.712234,1 Z" id="rectangle" stroke="#000000" stroke-width="2" fill="#FFFFFF"></path>
            <g id="regex_symbols" transform="translate(18.000000, 12.000000)" fill="#000000" fill-rule="nonzero">
                <path d="M4.17434508,33.013582 C1.94895328,33.013582 0.138006923,34.8245284 0.138006923,37.0499202 C0.138006923,39.275312 1.94895328,41.0862583 4.17434508,41.0862583 C6.39973688,41.0862583 8.21068324,39.275312 8.21068324,37.0499202 C8.21068324,34.8245284 6.39973688,33.013582 4.17434508,33.013582 Z" id="full_stop"></path>
                <path d="M23.9479718,23.3175402 L21.5628264,23.3175402 C21.2344032,23.3175402 20.9665401,23.0520067 20.9665401,22.7212538 L20.9665401,15.1022979 L14.3445004,18.8873192 C14.0626621,19.050366 13.7016292,18.952538 13.5362533,18.6706991 L12.3436806,16.6442575 C12.262157,16.506832 12.2388642,16.3437852 12.2807909,16.1900549 C12.3203879,16.0363251 12.4205455,15.9058874 12.557971,15.8266929 L19.1800101,11.9880994 L12.557971,8.15183511 C12.4205455,8.07264112 12.3203879,7.93987439 12.2807909,7.78614401 C12.2388642,7.63241423 12.262157,7.46936689 12.3413509,7.33194137 L13.5339237,5.30549975 C13.6993001,5.02366143 14.0626621,4.92816199 14.3445004,5.09120934 L20.9665401,8.87390091 L20.9665401,1.25494501 C20.9665401,0.926521818 21.2344032,0.658658658 21.5628264,0.658658658 L23.9479718,0.658658658 C24.2787247,0.658658658 24.5442582,0.926521818 24.5442582,1.25494501 L24.5442582,8.87390091 L31.1662979,5.09120934 C31.4481362,4.92816199 31.8091691,5.02366143 31.9745455,5.30549975 L33.1671182,7.33194137 C33.2486413,7.46936689 33.2719341,7.63241423 33.2300074,7.78614401 C33.1904104,7.93987439 33.0902528,8.07264112 32.9528278,8.15183511 L26.3307882,11.9880994 L32.9528278,15.8243638 C33.0879237,15.9058874 33.1880813,16.0363251 33.2300074,16.1900549 C33.269605,16.3437852 33.2486413,16.506832 33.1671182,16.6442575 L31.9745455,18.6706991 C31.8091691,18.952538 31.4481362,19.050366 31.1662979,18.8849895 L24.5442582,15.1022979 L24.5442582,22.7212538 C24.5442582,23.0520067 24.2787247,23.3175402 23.9479718,23.3175402 Z" id="asterisk"></path>
            </g>
        </g>
    </g>
</svg>
        </div>
        <div style="font-family: 'IBM Plex Mono', monospace, courier; color: black; font-size: 11px; display: inline-block; vertical-align: middle;">
            <div>col_vals_regex()</div>
        </div>
<pre><code>    &lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;player_id&lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;^[A-Z]{12}[0-9]{3}$&lt;/td&gt;
&lt;td style=&quot;height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;&quot; class=&quot;gt_row gt_center&quot;&gt;&lt;svg width=&quot;25px&quot; height=&quot;25px&quot; viewBox=&quot;0 0 25 25&quot; version=&quot;1.1&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot; style=&quot;vertical-align: middle;&quot;&gt;
&lt;g id=&quot;unchanged&quot; stroke=&quot;none&quot; stroke-width=&quot;1&quot; fill=&quot;none&quot; fill-rule=&quot;evenodd&quot;&gt;
    &lt;g id=&quot;unchanged&quot; transform=&quot;translate(0.500000, 0.570147)&quot;&gt;
        &lt;rect id=&quot;Rectangle&quot; x=&quot;0.125132506&quot; y=&quot;0&quot; width=&quot;23.749735&quot; height=&quot;23.7894737&quot;&gt;&lt;/rect&gt;
        &lt;path d=&quot;M5.80375046,8.18194736 C3.77191832,8.18194736 2.11875046,9.83495328 2.11875046,11.8669474 C2.11875046,13.8989414 3.77191832,15.5519474 5.80375046,15.5519474 C7.8355826,15.5519474 9.48875046,13.8989414 9.48875046,11.8669474 C9.48875046,9.83495328 7.83552863,8.18194736 5.80375046,8.18194736 Z M5.80375046,14.814915 C4.17821997,14.814915 2.85578285,13.4924778 2.85578285,11.8669474 C2.85578285,10.2414169 4.17821997,8.91897975 5.80375046,8.91897975 C7.42928095,8.91897975 8.75171807,10.2414169 8.75171807,11.8669474 C8.75171807,13.4924778 7.42928095,14.814915 5.80375046,14.814915 Z&quot; id=&quot;Shape&quot; fill=&quot;#000000&quot; fill-rule=&quot;nonzero&quot;&gt;&lt;/path&gt;
        &lt;path d=&quot;M13.9638189,8.699335 C13.9364621,8.70430925 13.9091059,8.71176968 13.8842359,8.71923074 C13.7822704,8.73663967 13.6877654,8.77643115 13.6056956,8.83860518 L10.2433156,11.3852598 C10.0766886,11.5046343 9.97720993,11.6986181 9.97720993,11.9025491 C9.97720993,12.1064807 10.0766886,12.3004639 10.2433156,12.4198383 L13.6056956,14.966493 C13.891697,15.1803725 14.2970729,15.1231721 14.5109517,14.8371707 C14.7248313,14.5511692 14.6676309,14.145794 14.3816294,13.9319145 L12.5313257,12.5392127 L21.8812495,12.5392127 L21.8812495,11.2658854 L12.5313257,11.2658854 L14.3816294,9.87318364 C14.6377872,9.71650453 14.7497006,9.40066014 14.6477351,9.11714553 C14.5482564,8.83363156 14.262255,8.65954352 13.9638189,8.699335 Z&quot; id=&quot;arrow&quot; fill=&quot;#000000&quot; transform=&quot;translate(15.929230, 11.894737) rotate(-180.000000) translate(-15.929230, -11.894737) &quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
&lt;/g&gt;
</code></pre>
<p></svg></td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color:#4CA64C;">✓</span></td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_right">2000</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">2000<br />1.00</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">0<br />0.00</td>
<td style="height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color: #AAAAAA;">○</span></td>
<td style="height: 40px; background-color: #FCFCFC;" class="gt_row gt_center"><span style="color: #EBBC14;">○</span></td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color: #FF3300;">○</span></td>
<td style="height: 40px;" class="gt_row gt_center">—</td></p>
  </tr>
  <tr>
    <td style="height: 40px; background-color: #AAAAAA; color: transparent;font-size: 0px;" class="gt_row gt_left">#AAAAAA</td>
    <td style="height: 40px; color: #666666;font-size: 13px;font-weight: bold;" class="gt_row gt_right">2</td>
    <td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_left">
        <div style="margin: 0; padding: 0; display: inline-block; height: 30px; vertical-align: middle; width: 16%;">
            <!--?xml version="1.0" encoding="UTF-8"?--><?xml version="1.0" encoding="UTF-8"?>
<svg width="30px" height="30px" viewBox="0 0 67 67" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="background: #FFFFFF;">
    <title>col_vals_gt</title>
    <g id="Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="col_vals_gt" transform="translate(1.500000, 1.500000)" fill-rule="nonzero">
            <path d="M55,0 C57.4852813,0 59.7352813,1.00735931 61.363961,2.63603897 C62.9926407,4.26471863 64,6.51471863 64,9 L64,9 L64,64 L9,64 C6.51471862,64 4.26471862,62.9926407 2.63603897,61.363961 C1.00735931,59.7352814 0,57.4852814 0,55 L0,55 L0,9 C0,6.51471863 1.00735931,4.26471863 2.63603897,2.63603897 C4.26471862,1.00735931 6.51471862,0 9,0 L9,0 L55,0 Z" id="rectangle" stroke="#000000" stroke-width="2" fill="#FFFFFF"></path>
            <path d="M48.7619048,10 L15.2380953,10 C12.3466667,10 10,12.3466667 10,15.2380952 L10,48.7619048 C10,51.6533333 12.3466667,54 15.2380953,54 L48.7619048,54 C51.6533333,54 54,51.6533333 54,48.7619048 L54,15.2380952 C54,12.3466667 51.6533333,10 48.7619048,10 Z M25.2638095,44.3828571 L24.0695238,42.6647619 L39.5847619,32 L24.0695238,21.3352381 L25.2638095,19.6171429 L43.2828572,32 L25.2638095,44.3828571 Z" id="greater_than" fill="#000000"></path>
        </g>
    </g>
</svg>
        </div>
        <div style="font-family: 'IBM Plex Mono', monospace, courier; color: black; font-size: 11px; display: inline-block; vertical-align: middle;">
            <div>col_vals_gt()</div>
        </div>
<pre><code>    &lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;session_duration&lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;5&lt;/td&gt;
&lt;td style=&quot;height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;&quot; class=&quot;gt_row gt_center&quot;&gt;&lt;svg width=&quot;25px&quot; height=&quot;25px&quot; viewBox=&quot;0 0 25 25&quot; version=&quot;1.1&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot; style=&quot;vertical-align: middle;&quot;&gt;
&lt;g id=&quot;unchanged&quot; stroke=&quot;none&quot; stroke-width=&quot;1&quot; fill=&quot;none&quot; fill-rule=&quot;evenodd&quot;&gt;
    &lt;g id=&quot;unchanged&quot; transform=&quot;translate(0.500000, 0.570147)&quot;&gt;
        &lt;rect id=&quot;Rectangle&quot; x=&quot;0.125132506&quot; y=&quot;0&quot; width=&quot;23.749735&quot; height=&quot;23.7894737&quot;&gt;&lt;/rect&gt;
        &lt;path d=&quot;M5.80375046,8.18194736 C3.77191832,8.18194736 2.11875046,9.83495328 2.11875046,11.8669474 C2.11875046,13.8989414 3.77191832,15.5519474 5.80375046,15.5519474 C7.8355826,15.5519474 9.48875046,13.8989414 9.48875046,11.8669474 C9.48875046,9.83495328 7.83552863,8.18194736 5.80375046,8.18194736 Z M5.80375046,14.814915 C4.17821997,14.814915 2.85578285,13.4924778 2.85578285,11.8669474 C2.85578285,10.2414169 4.17821997,8.91897975 5.80375046,8.91897975 C7.42928095,8.91897975 8.75171807,10.2414169 8.75171807,11.8669474 C8.75171807,13.4924778 7.42928095,14.814915 5.80375046,14.814915 Z&quot; id=&quot;Shape&quot; fill=&quot;#000000&quot; fill-rule=&quot;nonzero&quot;&gt;&lt;/path&gt;
        &lt;path d=&quot;M13.9638189,8.699335 C13.9364621,8.70430925 13.9091059,8.71176968 13.8842359,8.71923074 C13.7822704,8.73663967 13.6877654,8.77643115 13.6056956,8.83860518 L10.2433156,11.3852598 C10.0766886,11.5046343 9.97720993,11.6986181 9.97720993,11.9025491 C9.97720993,12.1064807 10.0766886,12.3004639 10.2433156,12.4198383 L13.6056956,14.966493 C13.891697,15.1803725 14.2970729,15.1231721 14.5109517,14.8371707 C14.7248313,14.5511692 14.6676309,14.145794 14.3816294,13.9319145 L12.5313257,12.5392127 L21.8812495,12.5392127 L21.8812495,11.2658854 L12.5313257,11.2658854 L14.3816294,9.87318364 C14.6377872,9.71650453 14.7497006,9.40066014 14.6477351,9.11714553 C14.5482564,8.83363156 14.262255,8.65954352 13.9638189,8.699335 Z&quot; id=&quot;arrow&quot; fill=&quot;#000000&quot; transform=&quot;translate(15.929230, 11.894737) rotate(-180.000000) translate(-15.929230, -11.894737) &quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
&lt;/g&gt;
</code></pre>
<p></svg></td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color:#4CA64C;">✓</span></td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_right">2000</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">1982<br />0.99</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">18<br />0.01</td>
<td style="height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color: #AAAAAA;">●</span></td>
<td style="height: 40px; background-color: #FCFCFC;" class="gt_row gt_center"><span style="color: #EBBC14;">○</span></td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color: #FF3300;">○</span></td>
<td style="height: 40px;" class="gt_row gt_center"><a href="data:text/csv;base64,X3Jvd19udW1fLHBsYXllcl9pZCxzZXNzaW9uX2lkLHNlc3Npb25fc3RhcnQsdGltZSxpdGVtX3R5cGUsaXRlbV9uYW1lLGl0ZW1fcmV2ZW51ZSxzZXNzaW9uX2R1cmF0aW9uLHN0YXJ0X2RheSxhY3F1aXNpdGlvbixjb3VudHJ5CjU0OSxRTkxWUkRFT1hGWUo4OTIsUU5MVlJERU9YRllKODkyLWx6NWZtcjZrLDIwMTUtMDEtMTBUMTY6NDQ6MTcuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMFQxNjo0NToyOS4wMDAwMDArMDAwMCxpYXAsZ29sZDMsMy40OSwzLjcsMjAxNS0wMS0wOSxjcm9zc3Byb21vLEF1c3RyYWxpYQo2MjAsUk1PU1dISkdFTENJNjc1LFJNT1NXSEpHRUxDSTY3NS10NHk4YmpjdSwyMDE1LTAxLTExVDA3OjI0OjI0LjAwMDAwMCswMDAwLDIwMTUtMDEtMTFUMDc6MjU6MTguMDAwMDAwKzAwMDAsaWFwLG9mZmVyNCwxNy45OTEsNS4wLDIwMTUtMDEtMTAsb3RoZXJfY2FtcGFpZ24sRnJhbmNlCjYyMSxSTU9TV0hKR0VMQ0k2NzUsUk1PU1dISkdFTENJNjc1LXQ0eThiamN1LDIwMTUtMDEtMTFUMDc6MjQ6MjQuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMVQwNzoyNjoyNC4wMDAwMDArMDAwMCxpYXAsb2ZmZXI1LDI2LjA5LDUuMCwyMDE1LTAxLTEwLG90aGVyX2NhbXBhaWduLEZyYW5jZQo2MjIsUk1PU1dISkdFTENJNjc1LFJNT1NXSEpHRUxDSTY3NS10NHk4YmpjdSwyMDE1LTAxLTExVDA3OjI0OjI0LjAwMDAwMCswMDAwLDIwMTUtMDEtMTFUMDc6Mjg6MzYuMDAwMDAwKzAwMDAsYWQsYWRfMTVzZWMsMC41Myw1LjAsMjAxNS0wMS0xMCxvdGhlcl9jYW1wYWlnbixGcmFuY2UKNjYzLEdGTFlKSEFQTVpXRDYzMSxHRkxZSkhBUE1aV0Q2MzEtaTJ2MWJsN2EsMjAxNS0wMS0xMVQxNjoxMzoyNC4wMDAwMDArMDAwMCwyMDE1LTAxLTExVDE2OjE0OjU0LjAwMDAwMCswMDAwLGlhcCxnZW1zMiwzLjk5LDMuNiwyMDE1LTAxLTA5LG9yZ2FuaWMsSW5kaWEKNzcyLEJGTkxVUklTSlhUSDY0NyxCRk5MVVJJU0pYVEg2NDctNm81aHgyN3osMjAxNS0wMS0xMlQxNzozNzozOS4wMDAwMDArMDAwMCwyMDE1LTAxLTEyVDE3OjM5OjI3LjAwMDAwMCswMDAwLGlhcCxvZmZlcjUsMTEuNTksNC4xLDIwMTUtMDEtMTAsb3JnYW5pYyxJbmRpYQo3NzMsQkZOTFVSSVNKWFRINjQ3LEJGTkxVUklTSlhUSDY0Ny02bzVoeDI3eiwyMDE1LTAxLTEyVDE3OjM3OjM5LjAwMDAwMCswMDAwLDIwMTUtMDEtMTJUMTc6NDE6NDUuMDAwMDAwKzAwMDAsaWFwLGdlbXMzLDkuOTksNC4xLDIwMTUtMDEtMTAsb3JnYW5pYyxJbmRpYQo5MDgsS0lMV1pZSFJTSkVHMzE2LEtJTFdaWUhSU0pFRzMxNi11a2U3ZGhxaiwyMDE1LTAxLTEzVDIyOjE2OjI5LjAwMDAwMCswMDAwLDIwMTUtMDEtMTNUMjI6MTc6MzUuMDAwMDAwKzAwMDAsaWFwLG9mZmVyMiwxMC45OSwzLjIsMjAxNS0wMS0wNCxvcmdhbmljLERlbm1hcmsKMTAzNyxKVUJEVkZIQ05RV1QxOTgsSlVCRFZGSENOUVdUMTk4LTloNHhzMnBiLDIwMTUtMDEtMTRUMTY6MDg6MjUuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNFQxNjowODo0My4wMDAwMDArMDAwMCxpYXAsb2ZmZXI1LDguNjksMy4zLDIwMTUtMDEtMTQsb3JnYW5pYyxQaGlsaXBwaW5lcwoxMDM4LEpVQkRWRkhDTlFXVDE5OCxKVUJEVkZIQ05RV1QxOTgtOWg0eHMycGIsMjAxNS0wMS0xNFQxNjowODoyNS4wMDAwMDArMDAwMCwyMDE1LTAxLTE0VDE2OjExOjAxLjAwMDAwMCswMDAwLGlhcCxvZmZlcjQsNS45OSwzLjMsMjAxNS0wMS0xNCxvcmdhbmljLFBoaWxpcHBpbmVzCjEzMTgsS0daQ09KSFBGVFFWNzUzLEtHWkNPSkhQRlRRVjc1My02azl4aXVnciwyMDE1LTAxLTE2VDE0OjU1OjMyLjAwMDAwMCswMDAwLDIwMTUtMDEtMTZUMTU6MDA6MzIuMDAwMDAwKzAwMDAsYWQsYWRfcGxheWFibGUsMS4wNyw1LjAsMjAxNS0wMS0xMSxvcmdhbmljLFVuaXRlZCBTdGF0ZXMKMTQ1NSxHSkNYTlRXRUJJUFEzNjksR0pDWE5UV0VCSVBRMzY5LTQ2Y2Rqenk3LDIwMTUtMDEtMTdUMTE6MjU6MjUuMDAwMDAwKzAwMDAsMjAxNS0wMS0xN1QxMToyODowMS4wMDAwMDArMDAwMCxpYXAsb2ZmZXI0LDEzLjk5LDQuNiwyMDE1LTAxLTE0LG9yZ2FuaWMsVW5pdGVkIFN0YXRlcwoxNTE2LE9NQ1ZVQUlLU0RUUjY1MSxPTUNWVUFJS1NEVFI2NTEteXNvOWUxYjIsMjAxNS0wMS0xN1QyMDo1ODozNC4wMDAwMDArMDAwMCwyMDE1LTAxLTE3VDIxOjAxOjM0LjAwMDAwMCswMDAwLGlhcCxvZmZlcjMsMTAuNDksNC4yLDIwMTUtMDEtMDcsb3RoZXJfY2FtcGFpZ24sVW5pdGVkIFN0YXRlcwoxNTE3LE9NQ1ZVQUlLU0RUUjY1MSxPTUNWVUFJS1NEVFI2NTEteXNvOWUxYjIsMjAxNS0wMS0xN1QyMDo1ODozNC4wMDAwMDArMDAwMCwyMDE1LTAxLTE3VDIxOjAyOjM0LjAwMDAwMCswMDAwLGlhcCxvZmZlcjUsMjAuMjksNC4yLDIwMTUtMDEtMDcsb3RoZXJfY2FtcGFpZ24sVW5pdGVkIFN0YXRlcwoxOTEzLE1UQ0lXS09WQVNZUDkyNSxNVENJV0tPVkFTWVA5MjUtMXEzeHZmbXAsMjAxNS0wMS0yMFQxMjozNDo0My4wMDAwMDArMDAwMCwyMDE1LTAxLTIwVDEyOjM1OjM3LjAwMDAwMCswMDAwLGlhcCxvZmZlcjUsMjYuMDksMy45LDIwMTUtMDEtMTQsb3JnYW5pYyxHZXJtYW55CjE5MTQsTVRDSVdLT1ZBU1lQOTI1LE1UQ0lXS09WQVNZUDkyNS0xcTN4dmZtcCwyMDE1LTAxLTIwVDEyOjM0OjQzLjAwMDAwMCswMDAwLDIwMTUtMDEtMjBUMTI6Mzc6MjUuMDAwMDAwKzAwMDAsaWFwLGdvbGQyLDEuNzksMy45LDIwMTUtMDEtMTQsb3JnYW5pYyxHZXJtYW55CjE5MTksQkZOTFVSSVNKWFRINjQ3LEJGTkxVUklTSlhUSDY0Ny1sZW42dnVqZCwyMDE1LTAxLTIwVDE0OjA5OjUxLjAwMDAwMCswMDAwLDIwMTUtMDEtMjBUMTQ6MTA6MDMuMDAwMDAwKzAwMDAsaWFwLGdvbGQ3LDQ3Ljk5LDQuNSwyMDE1LTAxLTEwLG9yZ2FuaWMsSW5kaWEKMTkyMCxCRk5MVVJJU0pYVEg2NDcsQkZOTFVSSVNKWFRINjQ3LWxlbjZ2dWpkLDIwMTUtMDEtMjBUMTQ6MDk6NTEuMDAwMDAwKzAwMDAsMjAxNS0wMS0yMFQxNDoxNDoyMS4wMDAwMDArMDAwMCxpYXAsZ29sZDYsMjMuOTksNC41LDIwMTUtMDEtMTAsb3JnYW5pYyxJbmRpYQo=" download="extract_0002.csv"><button style="background-color: #67C2DC; color: #FFFFFF; border: none; padding: 5px; font-weight: bold; cursor: pointer; border-radius: 4px;">CSV</button></a></td></p>
  </tr>
  <tr>
    <td style="height: 40px; background-color: #EBBC14; color: transparent;font-size: 0px;" class="gt_row gt_left">#EBBC14</td>
    <td style="height: 40px; color: #666666;font-size: 13px;font-weight: bold;" class="gt_row gt_right">3</td>
    <td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_left">
        <div style="margin: 0; padding: 0; display: inline-block; height: 30px; vertical-align: middle; width: 16%;">
            <!--?xml version="1.0" encoding="UTF-8"?--><?xml version="1.0" encoding="UTF-8"?>
<svg width="30px" height="30px" viewBox="0 0 67 67" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="background: #FFFFFF;">
    <title>col_vals_ge</title>
    <g id="Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="col_vals_ge" transform="translate(1.500000, 1.500000)" fill-rule="nonzero">
            <path d="M55,0 C57.4852813,0 59.7352813,1.00735931 61.363961,2.63603897 C62.9926407,4.26471863 64,6.51471863 64,9 L64,9 L64,64 L9,64 C6.51471862,64 4.26471862,62.9926407 2.63603897,61.363961 C1.00735931,59.7352814 0,57.4852814 0,55 L0,55 L0,9 C0,6.51471863 1.00735931,4.26471863 2.63603897,2.63603897 C4.26471862,1.00735931 6.51471862,0 9,0 L9,0 L55,0 Z" id="rectangle" stroke="#000000" stroke-width="2" fill="#FFFFFF"></path>
            <path d="M48.7619048,10 L15.2380953,10 C12.3466667,10 10,12.3466667 10,15.2380952 L10,48.7619048 C10,51.6533333 12.3466667,54 15.2380953,54 L48.7619048,54 C51.6533333,54 54,51.6533333 54,48.7619048 L54,15.2380952 C54,12.3466667 51.6533333,10 48.7619048,10 Z M43.5238095,46.6666667 L20.4761905,46.6666667 L20.4761905,44.5714286 L43.5238095,44.5714286 L43.5238095,46.6666667 Z M22.0161905,40.2552381 L21.0314286,38.4114286 L39.1761905,28.8571429 L21.0314286,19.3028571 L22.0161905,17.4590476 L43.6809524,28.8571429 L22.0161905,40.2552381 Z" id="greater_than_equal" fill="#000000"></path>
        </g>
    </g>
</svg>
        </div>
        <div style="font-family: 'IBM Plex Mono', monospace, courier; color: black; font-size: 11px; display: inline-block; vertical-align: middle;">
            <div>col_vals_ge()</div>
        </div>
<pre><code>    &lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;item_revenue&lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;0.02&lt;/td&gt;
&lt;td style=&quot;height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;&quot; class=&quot;gt_row gt_center&quot;&gt;&lt;svg width=&quot;25px&quot; height=&quot;25px&quot; viewBox=&quot;0 0 25 25&quot; version=&quot;1.1&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot; style=&quot;vertical-align: middle;&quot;&gt;
&lt;g id=&quot;unchanged&quot; stroke=&quot;none&quot; stroke-width=&quot;1&quot; fill=&quot;none&quot; fill-rule=&quot;evenodd&quot;&gt;
    &lt;g id=&quot;unchanged&quot; transform=&quot;translate(0.500000, 0.570147)&quot;&gt;
        &lt;rect id=&quot;Rectangle&quot; x=&quot;0.125132506&quot; y=&quot;0&quot; width=&quot;23.749735&quot; height=&quot;23.7894737&quot;&gt;&lt;/rect&gt;
        &lt;path d=&quot;M5.80375046,8.18194736 C3.77191832,8.18194736 2.11875046,9.83495328 2.11875046,11.8669474 C2.11875046,13.8989414 3.77191832,15.5519474 5.80375046,15.5519474 C7.8355826,15.5519474 9.48875046,13.8989414 9.48875046,11.8669474 C9.48875046,9.83495328 7.83552863,8.18194736 5.80375046,8.18194736 Z M5.80375046,14.814915 C4.17821997,14.814915 2.85578285,13.4924778 2.85578285,11.8669474 C2.85578285,10.2414169 4.17821997,8.91897975 5.80375046,8.91897975 C7.42928095,8.91897975 8.75171807,10.2414169 8.75171807,11.8669474 C8.75171807,13.4924778 7.42928095,14.814915 5.80375046,14.814915 Z&quot; id=&quot;Shape&quot; fill=&quot;#000000&quot; fill-rule=&quot;nonzero&quot;&gt;&lt;/path&gt;
        &lt;path d=&quot;M13.9638189,8.699335 C13.9364621,8.70430925 13.9091059,8.71176968 13.8842359,8.71923074 C13.7822704,8.73663967 13.6877654,8.77643115 13.6056956,8.83860518 L10.2433156,11.3852598 C10.0766886,11.5046343 9.97720993,11.6986181 9.97720993,11.9025491 C9.97720993,12.1064807 10.0766886,12.3004639 10.2433156,12.4198383 L13.6056956,14.966493 C13.891697,15.1803725 14.2970729,15.1231721 14.5109517,14.8371707 C14.7248313,14.5511692 14.6676309,14.145794 14.3816294,13.9319145 L12.5313257,12.5392127 L21.8812495,12.5392127 L21.8812495,11.2658854 L12.5313257,11.2658854 L14.3816294,9.87318364 C14.6377872,9.71650453 14.7497006,9.40066014 14.6477351,9.11714553 C14.5482564,8.83363156 14.262255,8.65954352 13.9638189,8.699335 Z&quot; id=&quot;arrow&quot; fill=&quot;#000000&quot; transform=&quot;translate(15.929230, 11.894737) rotate(-180.000000) translate(-15.929230, -11.894737) &quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
&lt;/g&gt;
</code></pre>
<p></svg></td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color:#4CA64C;">✓</span></td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_right">2000</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">1941<br />0.97</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">59<br />0.03</td>
<td style="height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color: #AAAAAA;">●</span></td>
<td style="height: 40px; background-color: #FCFCFC;" class="gt_row gt_center"><span style="color: #EBBC14;">●</span></td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color: #FF3300;">○</span></td>
<td style="height: 40px;" class="gt_row gt_center"><a href="data:text/csv;base64,X3Jvd19udW1fLHBsYXllcl9pZCxzZXNzaW9uX2lkLHNlc3Npb25fc3RhcnQsdGltZSxpdGVtX3R5cGUsaXRlbV9uYW1lLGl0ZW1fcmV2ZW51ZSxzZXNzaW9uX2R1cmF0aW9uLHN0YXJ0X2RheSxhY3F1aXNpdGlvbixjb3VudHJ5CjI1NSxQWkJOUktTTVVMSFgyMTMsUFpCTlJLU01VTEhYMjEzLWtvc3Y4aGxlLDIwMTUtMDEtMDdUMTM6NDk6MTkuMDAwMDAwKzAwMDAsMjAxNS0wMS0wN1QxNDowNTozMS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDA0LDIyLjIsMjAxNS0wMS0wNyxvcmdhbmljLEluZGlhCjI5MSxQWkJOUktTTVVMSFgyMTMsUFpCTlJLU01VTEhYMjEzLWp4bndhaDR2LDIwMTUtMDEtMDdUMTc6NTU6MjIuMDAwMDAwKzAwMDAsMjAxNS0wMS0wN1QxODoyNDoyOC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDE0LDMwLjksMjAxNS0wMS0wNyxvcmdhbmljLEluZGlhCjMwOCxLQkVRWkdGU1JQSEo0NzksS0JFUVpHRlNSUEhKNDc5LTZ4enluanZkLDIwMTUtMDEtMDdUMjI6Mzc6MzcuMDAwMDAwKzAwMDAsMjAxNS0wMS0wN1QyMjo1ODoxMy4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDA5LDI3LjQsMjAxNS0wMS0wNyxvcmdhbmljLFJ1c3NpYQozNDgsSUNCQVVaS0dTUVBGMTQ1LElDQkFVWktHU1FQRjE0NS1mbGFveWRqNSwyMDE1LTAxLTA4VDEyOjQ4OjEzLjAwMDAwMCswMDAwLDIwMTUtMDEtMDhUMTM6MDg6MjUuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAxNDk5LDI3LjksMjAxNS0wMS0wNixnb29nbGUsU291dGggQWZyaWNhCjM1MCxQWkJOUktTTVVMSFgyMTMsUFpCTlJLU01VTEhYMjEzLW0ybjZ0azFpLDIwMTUtMDEtMDhUMTQ6MTA6MTguMDAwMDAwKzAwMDAsMjAxNS0wMS0wOFQxNDoxNjozMC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDEsMzQuMiwyMDE1LTAxLTA3LG9yZ2FuaWMsSW5kaWEKMzUzLFBaQk5SS1NNVUxIWDIxMyxQWkJOUktTTVVMSFgyMTMtbTJuNnRrMWksMjAxNS0wMS0wOFQxNDoxMDoxOC4wMDAwMDArMDAwMCwyMDE1LTAxLTA4VDE0OjM4OjA2LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMDYsMzQuMiwyMDE1LTAxLTA3LG9yZ2FuaWMsSW5kaWEKMzY1LEtCRVFaR0ZTUlBISjQ3OSxLQkVRWkdGU1JQSEo0NzktZjJlNXJkYWIsMjAxNS0wMS0wOFQxNjoxMTowOC4wMDAwMDArMDAwMCwyMDE1LTAxLTA4VDE2OjM1OjAyLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMTgsMzMuMSwyMDE1LTAxLTA3LG9yZ2FuaWMsUnVzc2lhCjQzNyxHRkxZSkhBUE1aV0Q2MzEsR0ZMWUpIQVBNWldENjMxLXdkejM3dmN0LDIwMTUtMDEtMDlUMTU6NTA6MTguMDAwMDAwKzAwMDAsMjAxNS0wMS0wOVQxNjoxMjowNi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDE0LDMwLjksMjAxNS0wMS0wOSxvcmdhbmljLEluZGlhCjQ2MixMRFNVSENSQVlLTU8xNzksTERTVUhDUkFZS01PMTc5LTR4a282OWVpLDIwMTUtMDEtMDlUMjM6NTQ6MTcuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMFQwMDowMjoyMy4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDE4LDIwLjMsMjAxNS0wMS0wNyxvdGhlcl9jYW1wYWlnbixQb3J0dWdhbAo1MTcsR0ZMWUpIQVBNWldENjMxLEdGTFlKSEFQTVpXRDYzMS12cHdmajNjYSwyMDE1LTAxLTEwVDEyOjM0OjQ1LjAwMDAwMCswMDAwLDIwMTUtMDEtMTBUMTI6NDk6NTEuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAwNCwyMS40LDIwMTUtMDEtMDksb3JnYW5pYyxJbmRpYQo1MTgsR0ZMWUpIQVBNWldENjMxLEdGTFlKSEFQTVpXRDYzMS12cHdmajNjYSwyMDE1LTAxLTEwVDEyOjM0OjQ1LjAwMDAwMCswMDAwLDIwMTUtMDEtMTBUMTI6NTU6NTEuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4wMTYsMjEuNCwyMDE1LTAxLTA5LG9yZ2FuaWMsSW5kaWEKNTE5LFBaQk5SS1NNVUxIWDIxMyxQWkJOUktTTVVMSFgyMTMtdnRseTM1ZmMsMjAxNS0wMS0xMFQxNDowNjozNi4wMDAwMDArMDAwMCwyMDE1LTAxLTEwVDE0OjA5OjE4LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMDYsMjYuMywyMDE1LTAxLTA3LG9yZ2FuaWMsSW5kaWEKNTIwLFBaQk5SS1NNVUxIWDIxMyxQWkJOUktTTVVMSFgyMTMtdnRseTM1ZmMsMjAxNS0wMS0xMFQxNDowNjozNi4wMDAwMDArMDAwMCwyMDE1LTAxLTEwVDE0OjE0OjE4LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMTYsMjYuMywyMDE1LTAxLTA3LG9yZ2FuaWMsSW5kaWEKNTI0LFBaQk5SS1NNVUxIWDIxMyxQWkJOUktTTVVMSFgyMTMtdnRseTM1ZmMsMjAxNS0wMS0xMFQxNDowNjozNi4wMDAwMDArMDAwMCwyMDE1LTAxLTEwVDE0OjMxOjU0LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMDYsMjYuMywyMDE1LTAxLTA3LG9yZ2FuaWMsSW5kaWEKNTY1LFBaQk5SS1NNVUxIWDIxMyxQWkJOUktTTVVMSFgyMTMteTcyMWZ1dGEsMjAxNS0wMS0xMFQxOTo1NDoxMS4wMDAwMDArMDAwMCwyMDE1LTAxLTEwVDIwOjEyOjI5LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMDQsMzkuOCwyMDE1LTAxLTA3LG9yZ2FuaWMsSW5kaWEKNTcyLEJGTkxVUklTSlhUSDY0NyxCRk5MVVJJU0pYVEg2NDctM2JjbXRlcGcsMjAxNS0wMS0xMFQyMTowMDozMS4wMDAwMDArMDAwMCwyMDE1LTAxLTEwVDIxOjE2OjQzLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMDQsMzQuMCwyMDE1LTAxLTEwLG9yZ2FuaWMsSW5kaWEKNTczLEJGTkxVUklTSlhUSDY0NyxCRk5MVVJJU0pYVEg2NDctM2JjbXRlcGcsMjAxNS0wMS0xMFQyMTowMDozMS4wMDAwMDArMDAwMCwyMDE1LTAxLTEwVDIxOjE4OjQzLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMDQsMzQuMCwyMDE1LTAxLTEwLG9yZ2FuaWMsSW5kaWEKNTc0LEJGTkxVUklTSlhUSDY0NyxCRk5MVVJJU0pYVEg2NDctM2JjbXRlcGcsMjAxNS0wMS0xMFQyMTowMDozMS4wMDAwMDArMDAwMCwyMDE1LTAxLTEwVDIxOjIxOjQ5LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMTQsMzQuMCwyMDE1LTAxLTEwLG9yZ2FuaWMsSW5kaWEKNjQyLEJGTkxVUklTSlhUSDY0NyxCRk5MVVJJU0pYVEg2NDctZnVjcTFlbTgsMjAxNS0wMS0xMVQxMTowMjowOS4wMDAwMDArMDAwMCwyMDE1LTAxLTExVDExOjM0OjUxLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMDgsNDAuNywyMDE1LTAxLTEwLG9yZ2FuaWMsSW5kaWEKNjg5LFBaQk5SS1NNVUxIWDIxMyxQWkJOUktTTVVMSFgyMTMtbjhlbDZwdXcsMjAxNS0wMS0xMVQyMjowODoyNC4wMDAwMDArMDAwMCwyMDE1LTAxLTExVDIyOjI0OjMwLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMDQsMjguNiwyMDE1LTAxLTA3LG9yZ2FuaWMsSW5kaWEKNjkwLFBaQk5SS1NNVUxIWDIxMyxQWkJOUktTTVVMSFgyMTMtbjhlbDZwdXcsMjAxNS0wMS0xMVQyMjowODoyNC4wMDAwMDArMDAwMCwyMDE1LTAxLTExVDIyOjI4OjAwLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMTYsMjguNiwyMDE1LTAxLTA3LG9yZ2FuaWMsSW5kaWEKNzExLEFVV0ZEUlpNWFZKSDkyOCxBVVdGRFJaTVhWSkg5MjgtbXhyYjhsZDMsMjAxNS0wMS0xMlQwNDozMDoxMi4wMDAwMDArMDAwMCwyMDE1LTAxLTEyVDA0OjMxOjQ4LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMTIsMTkuNCwyMDE1LTAxLTExLGdvb2dsZSxJbmRpYQo3MzcsUExRRVNCTkdVREtKMTU0LFBMUUVTQk5HVURLSjE1NC1wNTMyaXZ5MSwyMDE1LTAxLTEyVDA4OjQ4OjA2LjAwMDAwMCswMDAwLDIwMTUtMDEtMTJUMDg6NTM6MDYuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAxMiwzNi4wLDIwMTUtMDEtMTIsZmFjZWJvb2ssSmFwYW4KNzY4LEFVV0ZEUlpNWFZKSDkyOCxBVVdGRFJaTVhWSkg5MjgtdzlmaGszcHosMjAxNS0wMS0xMlQxNzoyNzo0NS4wMDAwMDArMDAwMCwyMDE1LTAxLTEyVDE3OjMwOjE1LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMDgsMTEuNSwyMDE1LTAxLTExLGdvb2dsZSxJbmRpYQo4MDcsVkxRSFlKQ0tCT0lONzI5LFZMUUhZSkNLQk9JTjcyOS10ZTJhNzRsaSwyMDE1LTAxLTEzVDAwOjE3OjAwLjAwMDAwMCswMDAwLDIwMTUtMDEtMTNUMDA6MzY6NDguMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAxOCwyNS40LDIwMTUtMDEtMTAsb3JnYW5pYyxKYXBhbgo4NTMsQkZOTFVSSVNKWFRINjQ3LEJGTkxVUklTSlhUSDY0Ny1oeDI5a3Q0OCwyMDE1LTAxLTEzVDA4OjU5OjI5LjAwMDAwMCswMDAwLDIwMTUtMDEtMTNUMDk6MTQ6MTEuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAxOCwyNC40LDIwMTUtMDEtMTAsb3JnYW5pYyxJbmRpYQo4NTQsQkZOTFVSSVNKWFRINjQ3LEJGTkxVUklTSlhUSDY0Ny1oeDI5a3Q0OCwyMDE1LTAxLTEzVDA4OjU5OjI5LjAwMDAwMCswMDAwLDIwMTUtMDEtMTNUMDk6MTQ6MTcuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAwNCwyNC40LDIwMTUtMDEtMTAsb3JnYW5pYyxJbmRpYQo5MTcsUFpCTlJLU01VTEhYMjEzLFBaQk5SS1NNVUxIWDIxMy1ibHdkM3g3cSwyMDE1LTAxLTEzVDIzOjIzOjI3LjAwMDAwMCswMDAwLDIwMTUtMDEtMTNUMjM6NDA6MzMuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAxOCwyNC42LDIwMTUtMDEtMDcsb3JnYW5pYyxJbmRpYQo5MTgsUFpCTlJLU01VTEhYMjEzLFBaQk5SS1NNVUxIWDIxMy1ibHdkM3g3cSwyMDE1LTAxLTEzVDIzOjIzOjI3LjAwMDAwMCswMDAwLDIwMTUtMDEtMTNUMjM6NDE6MjcuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAxOCwyNC42LDIwMTUtMDEtMDcsb3JnYW5pYyxJbmRpYQo5NDksWlBUSUhOU1ZGWUFRMTQ2LFpQVElITlNWRllBUTE0Ni0xYjZpaDd2ZywyMDE1LTAxLTE0VDAyOjQ4OjU2LjAwMDAwMCswMDAwLDIwMTUtMDEtMTRUMDM6MjE6MTQuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAxMiwzNC45LDIwMTUtMDEtMDQsZmFjZWJvb2ssTWV4aWNvCjk1NyxYSUFIQk5LRUNHUk81OTgsWElBSEJOS0VDR1JPNTk4LWpsaGRuczhpLDIwMTUtMDEtMTRUMDQ6MzI6MTUuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNFQwNDozNDozMy4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDE1LDE0LjEsMjAxNS0wMS0xNCxnb29nbGUsRWd5cHQKOTYxLEVGTE5QR1RSWlZBQzc2NSxFRkxOUEdUUlpWQUM3NjUtdHM0OW0zcTcsMjAxNS0wMS0xNFQwNDozMzoyOC4wMDAwMDArMDAwMCwyMDE1LTAxLTE0VDA0OjUxOjE2LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMTUsMjAuNywyMDE1LTAxLTE0LG90aGVyX2NhbXBhaWduLFJ1c3NpYQo5NjIsRUZMTlBHVFJaVkFDNzY1LEVGTE5QR1RSWlZBQzc2NS10czQ5bTNxNywyMDE1LTAxLTE0VDA0OjMzOjI4LjAwMDAwMCswMDAwLDIwMTUtMDEtMTRUMDQ6NTE6NDAuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAxNSwyMC43LDIwMTUtMDEtMTQsb3RoZXJfY2FtcGFpZ24sUnVzc2lhCjEwMzQsWElBSEJOS0VDR1JPNTk4LFhJQUhCTktFQ0dSTzU5OC11bjFmYno5NSwyMDE1LTAxLTE0VDE2OjA2OjM3LjAwMDAwMCswMDAwLDIwMTUtMDEtMTRUMTY6MjY6NDMuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAxLDI3LjIsMjAxNS0wMS0xNCxnb29nbGUsRWd5cHQKMTA1MixQWkJOUktTTVVMSFgyMTMsUFpCTlJLU01VTEhYMjEzLWZ4b2liam5sLDIwMTUtMDEtMTRUMTg6MzM6NTYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNFQxODozODo0NC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDEsMTMuMywyMDE1LTAxLTA3LG9yZ2FuaWMsSW5kaWEKMTA1MyxQWkJOUktTTVVMSFgyMTMsUFpCTlJLU01VTEhYMjEzLWZ4b2liam5sLDIwMTUtMDEtMTRUMTg6MzM6NTYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNFQxODo0NToyNi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDA2LDEzLjMsMjAxNS0wMS0wNyxvcmdhbmljLEluZGlhCjExMDEsWk1KTFBHQ1JJS05BNDcxLFpNSkxQR0NSSUtOQTQ3MS1zamtmbWM0eSwyMDE1LTAxLTE1VDAzOjM5OjM4LjAwMDAwMCswMDAwLDIwMTUtMDEtMTVUMDM6NTI6MTQuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAxLDE3LjUsMjAxNS0wMS0xMCxvcmdhbmljLEVneXB0CjExMzAsVkxRSFlKQ0tCT0lONzI5LFZMUUhZSkNLQk9JTjcyOS02c2Z5d3Y3bSwyMDE1LTAxLTE1VDA4OjE4OjIwLjAwMDAwMCswMDAwLDIwMTUtMDEtMTVUMDg6MjE6MDIuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAxMiwzNC4wLDIwMTUtMDEtMTAsb3JnYW5pYyxKYXBhbgoxMTU5LFhJQUhCTktFQ0dSTzU5OCxYSUFIQk5LRUNHUk81OTgtYWcxOWp0OGYsMjAxNS0wMS0xNVQxMTozNDo0Mi4wMDAwMDArMDAwMCwyMDE1LTAxLTE1VDExOjM4OjQ4LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMSwxNS45LDIwMTUtMDEtMTQsZ29vZ2xlLEVneXB0CjExNzQsT0FOQ0lWWVhKTVJMNTk3LE9BTkNJVllYSk1STDU5Ny1icmk5dXBoMSwyMDE1LTAxLTE1VDEzOjI0OjI3LjAwMDAwMCswMDAwLDIwMTUtMDEtMTVUMTM6MjQ6NTEuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAwNCwxNy43LDIwMTUtMDEtMTUsb3RoZXJfY2FtcGFpZ24sSW5kaWEKMTE5OSxWTFFIWUpDS0JPSU43MjksVkxRSFlKQ0tCT0lONzI5LTlldmpvd2N0LDIwMTUtMDEtMTVUMjE6NTU6MjEuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNVQyMjowODo1Ny4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDE4LDM3LjIsMjAxNS0wMS0xMCxvcmdhbmljLEphcGFuCjEyMzAsQkZOTFVSSVNKWFRINjQ3LEJGTkxVUklTSlhUSDY0Ny1mZGFzd3lxZywyMDE1LTAxLTE2VDAzOjQ3OjE0LjAwMDAwMCswMDAwLDIwMTUtMDEtMTZUMDM6NTU6MDIuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAxOCwxMi4xLDIwMTUtMDEtMTAsb3JnYW5pYyxJbmRpYQoxMzI1LFBaQk5SS1NNVUxIWDIxMyxQWkJOUktTTVVMSFgyMTMtbzZ4eXV2aDgsMjAxNS0wMS0xNlQxNjoyOToxMC4wMDAwMDArMDAwMCwyMDE1LTAxLTE2VDE2OjM0OjM0LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMTYsMTguNSwyMDE1LTAxLTA3LG9yZ2FuaWMsSW5kaWEKMTQxMSxNWVFHSktPVUlXSEY2MTksTVlRR0pLT1VJV0hGNjE5LXRsd2NzeTc2LDIwMTUtMDEtMTdUMDY6MjM6NTguMDAwMDAwKzAwMDAsMjAxNS0wMS0xN1QwNjoyOTowNC4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjAxNCwxMi4zLDIwMTUtMDEtMTYsb3JnYW5pYyxJbmRpYQoxNDM0LEJGTkxVUklTSlhUSDY0NyxCRk5MVVJJU0pYVEg2NDctcWp1Z3BmMm4sMjAxNS0wMS0xN1QwOTo1ODoxOC4wMDAwMDArMDAwMCwyMDE1LTAxLTE3VDA5OjU5OjA2LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMTgsMjkuOCwyMDE1LTAxLTEwLG9yZ2FuaWMsSW5kaWEKMTQzNSxCRk5MVVJJU0pYVEg2NDcsQkZOTFVSSVNKWFRINjQ3LXFqdWdwZjJuLDIwMTUtMDEtMTdUMDk6NTg6MTguMDAwMDAwKzAwMDAsMjAxNS0wMS0xN1QxMDowNTowMC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDE4LDI5LjgsMjAxNS0wMS0xMCxvcmdhbmljLEluZGlhCjE0MzgsQkZOTFVSSVNKWFRINjQ3LEJGTkxVUklTSlhUSDY0Ny1xanVncGYybiwyMDE1LTAxLTE3VDA5OjU4OjE4LjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMTA6MjU6MDYuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAwNiwyOS44LDIwMTUtMDEtMTAsb3JnYW5pYyxJbmRpYQoxNDQ1LFhJQUhCTktFQ0dSTzU5OCxYSUFIQk5LRUNHUk81OTgtcW84cm16aWosMjAxNS0wMS0xN1QxMDo0MzoyOC4wMDAwMDArMDAwMCwyMDE1LTAxLTE3VDExOjAxOjA0LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMTUsMjguOCwyMDE1LTAxLTE0LGdvb2dsZSxFZ3lwdAoxNTI5LFBaQk5SS1NNVUxIWDIxMyxQWkJOUktTTVVMSFgyMTMtcmhjYW16dGYsMjAxNS0wMS0xN1QyMzowNToxNi4wMDAwMDArMDAwMCwyMDE1LTAxLTE3VDIzOjA5OjIyLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMTgsMTYuMSwyMDE1LTAxLTA3LG9yZ2FuaWMsSW5kaWEKMTUzMCxQWkJOUktTTVVMSFgyMTMsUFpCTlJLU01VTEhYMjEzLXJoY2FtenRmLDIwMTUtMDEtMTdUMjM6MDU6MTYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xN1QyMzoxMTozNC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDA4LDE2LjEsMjAxNS0wMS0wNyxvcmdhbmljLEluZGlhCjE1MzMsUFpCTlJLU01VTEhYMjEzLFBaQk5SS1NNVUxIWDIxMy1yaGNhbXp0ZiwyMDE1LTAxLTE3VDIzOjA1OjE2LjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMjM6MTk6NTIuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4wMTYsMTYuMSwyMDE1LTAxLTA3LG9yZ2FuaWMsSW5kaWEKMTcwNSxXRVBLWU5SWERGVVQ1NzIsV0VQS1lOUlhERlVUNTcyLWozYXZ1bDc1LDIwMTUtMDEtMTlUMDA6Mzc6MjcuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOVQwMDo0MTowMy4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDEyLDI5LjksMjAxNS0wMS0xMyxjcm9zc3Byb21vLENoaW5hCjE3MDYsV0VQS1lOUlhERlVUNTcyLFdFUEtZTlJYREZVVDU3Mi1qM2F2dWw3NSwyMDE1LTAxLTE5VDAwOjM3OjI3LjAwMDAwMCswMDAwLDIwMTUtMDEtMTlUMDA6NDI6NDUuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAxMiwyOS45LDIwMTUtMDEtMTMsY3Jvc3Nwcm9tbyxDaGluYQoxNzEyLFhJQUhCTktFQ0dSTzU5OCxYSUFIQk5LRUNHUk81OTgteWlsc3hmNXAsMjAxNS0wMS0xOVQwMDo1MjozMi4wMDAwMDArMDAwMCwyMDE1LTAxLTE5VDAxOjA0OjA4LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMTUsMzAuNCwyMDE1LTAxLTE0LGdvb2dsZSxFZ3lwdAoxNzEzLFhJQUhCTktFQ0dSTzU5OCxYSUFIQk5LRUNHUk81OTgteWlsc3hmNXAsMjAxNS0wMS0xOVQwMDo1MjozMi4wMDAwMDArMDAwMCwyMDE1LTAxLTE5VDAxOjA1OjA4LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMTUsMzAuNCwyMDE1LTAxLTE0LGdvb2dsZSxFZ3lwdAoxNzY5LEJGTkxVUklTSlhUSDY0NyxCRk5MVVJJU0pYVEg2NDctdGNmNXlzYXYsMjAxNS0wMS0xOVQwODowNToyMC4wMDAwMDArMDAwMCwyMDE1LTAxLTE5VDA4OjA4OjU2LjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDE2LDUuOSwyMDE1LTAxLTEwLG9yZ2FuaWMsSW5kaWEKMTc3OSxOUE1KSVlIRVRHS1cyOTcsTlBNSklZSEVUR0tXMjk3LXJ5MWo2c3p3LDIwMTUtMDEtMTlUMTA6MDE6MDguMDAwMDAwKzAwMDAsMjAxNS0wMS0xOVQxMDoxMzowOC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDE2LDI4LjQsMjAxNS0wMS0xOCxnb29nbGUsUGhpbGlwcGluZXMKMTkzMCxaR0VWUUpTS0ZJQlgzOTgsWkdFVlFKU0tGSUJYMzk4LXNvd2o2aDMxLDIwMTUtMDEtMjBUMTY6MDE6MTIuMDAwMDAwKzAwMDAsMjAxNS0wMS0yMFQxNjozNTo0OC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDE1LDQxLjAsMjAxNS0wMS0xNyxvcmdhbmljLFNvdXRoIEtvcmVhCjE5NDAsWlBUSUhOU1ZGWUFRMTQ2LFpQVElITlNWRllBUTE0Ni13Nm90ejE4cywyMDE1LTAxLTIwVDE2OjM5OjMyLjAwMDAwMCswMDAwLDIwMTUtMDEtMjBUMTY6NTg6MDIuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAxMiwzMy4xLDIwMTUtMDEtMDQsZmFjZWJvb2ssTWV4aWNvCg==" download="extract_0003.csv"><button style="background-color: #67C2DC; color: #FFFFFF; border: none; padding: 5px; font-weight: bold; cursor: pointer; border-radius: 4px;">CSV</button></a></td></p>
  </tr>
  <tr>
    <td style="height: 40px; background-color: #4CA64C; color: transparent;font-size: 0px;" class="gt_row gt_left">#4CA64C</td>
    <td style="height: 40px; color: #666666;font-size: 13px;font-weight: bold;" class="gt_row gt_right">4</td>
    <td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_left">
        <div style="margin: 0; padding: 0; display: inline-block; height: 30px; vertical-align: middle; width: 16%;">
            <!--?xml version="1.0" encoding="UTF-8"?--><?xml version="1.0" encoding="UTF-8"?>
<svg width="30px" height="30px" viewBox="0 0 67 67" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <title>col_vals_in_set</title>
    <g id="Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="col_vals_in_set" transform="translate(0.000000, 0.172414)">
            <path d="M56.712234,1 C59.1975153,1 61.4475153,2.00735931 63.076195,3.63603897 C64.7048747,5.26471863 65.712234,7.51471863 65.712234,10 L65.712234,10 L65.712234,65 L10.712234,65 C8.22695259,65 5.97695259,63.9926407 4.34827294,62.363961 C2.71959328,60.7352814 1.71223397,58.4852814 1.71223397,56 L1.71223397,56 L1.71223397,10 C1.71223397,7.51471863 2.71959328,5.26471863 4.34827294,3.63603897 C5.97695259,2.00735931 8.22695259,1 10.712234,1 L10.712234,1 Z" id="rectangle" stroke="#000000" stroke-width="2" fill="#FFFFFF"></path>
            <path d="M44.127969,41.1538382 L31.0814568,41.1538382 C29.9510748,41.1536429 28.8827052,40.9256134 27.9079888,40.5136953 C26.4467442,39.8960136 25.19849,38.8599685 24.3189894,37.5577099 C23.8792391,36.906727 23.5314818,36.1899233 23.2936866,35.4252675 C23.2130217,35.16589 23.1460289,34.9005554 23.0913409,34.6307286 L44.1278714,34.6307286 C45.028466,34.6306309 45.7586488,33.9004481 45.7586488,32.9998535 C45.7586488,32.0992589 45.028466,31.3690761 44.1278714,31.3690761 L23.0905596,31.3690761 C23.1990567,30.8337194 23.3597028,30.3180894 23.5675173,29.8264831 C24.185199,28.3652386 25.2212442,27.1169844 26.5236004,26.2374838 C27.1745833,25.7977334 27.891387,25.4499762 28.6560428,25.2122786 C29.4208939,24.9744833 30.2334994,24.8459665 31.0813591,24.8459665 L44.1277737,24.8459665 C45.0283683,24.8459665 45.7586488,24.1157837 45.7586488,23.2151891 C45.7586488,22.3145945 45.0283683,21.5844117 44.1277737,21.5844117 L31.0813591,21.5844117 C29.5096643,21.5844117 28.0039858,21.9038483 26.6373711,22.4820765 C24.5866678,23.3498583 22.8469049,24.7950871 21.6163267,26.616296 C20.3856508,28.4362354 19.665136,30.6413347 19.6658191,33.0000488 C19.6658191,34.5717436 19.9852563,36.0774222 20.5635822,37.4440369 C21.4312663,39.4947402 22.8765927,41.2345031 24.697704,42.4650813 C26.5176434,43.6957572 28.7227427,44.4155883 31.0814568,44.4155883 L44.1278714,44.4155883 C45.028466,44.4155883 45.7586488,43.6854055 45.7586488,42.7848109 C45.7586488,41.8842163 45.0285636,41.1538382 44.127969,41.1538382 Z" id="set_of" fill="#000000" fill-rule="nonzero"></path>
        </g>
    </g>
</svg>
        </div>
        <div style="font-family: 'IBM Plex Mono', monospace, courier; color: black; font-size: 11px; display: inline-block; vertical-align: middle;">
            <div>col_vals_in_set()</div>
        </div>
<pre><code>    &lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;item_type&lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;iap, ad&lt;/td&gt;
&lt;td style=&quot;height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;&quot; class=&quot;gt_row gt_center&quot;&gt;&lt;svg width=&quot;25px&quot; height=&quot;25px&quot; viewBox=&quot;0 0 25 25&quot; version=&quot;1.1&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot; style=&quot;vertical-align: middle;&quot;&gt;
&lt;g id=&quot;unchanged&quot; stroke=&quot;none&quot; stroke-width=&quot;1&quot; fill=&quot;none&quot; fill-rule=&quot;evenodd&quot;&gt;
    &lt;g id=&quot;unchanged&quot; transform=&quot;translate(0.500000, 0.570147)&quot;&gt;
        &lt;rect id=&quot;Rectangle&quot; x=&quot;0.125132506&quot; y=&quot;0&quot; width=&quot;23.749735&quot; height=&quot;23.7894737&quot;&gt;&lt;/rect&gt;
        &lt;path d=&quot;M5.80375046,8.18194736 C3.77191832,8.18194736 2.11875046,9.83495328 2.11875046,11.8669474 C2.11875046,13.8989414 3.77191832,15.5519474 5.80375046,15.5519474 C7.8355826,15.5519474 9.48875046,13.8989414 9.48875046,11.8669474 C9.48875046,9.83495328 7.83552863,8.18194736 5.80375046,8.18194736 Z M5.80375046,14.814915 C4.17821997,14.814915 2.85578285,13.4924778 2.85578285,11.8669474 C2.85578285,10.2414169 4.17821997,8.91897975 5.80375046,8.91897975 C7.42928095,8.91897975 8.75171807,10.2414169 8.75171807,11.8669474 C8.75171807,13.4924778 7.42928095,14.814915 5.80375046,14.814915 Z&quot; id=&quot;Shape&quot; fill=&quot;#000000&quot; fill-rule=&quot;nonzero&quot;&gt;&lt;/path&gt;
        &lt;path d=&quot;M13.9638189,8.699335 C13.9364621,8.70430925 13.9091059,8.71176968 13.8842359,8.71923074 C13.7822704,8.73663967 13.6877654,8.77643115 13.6056956,8.83860518 L10.2433156,11.3852598 C10.0766886,11.5046343 9.97720993,11.6986181 9.97720993,11.9025491 C9.97720993,12.1064807 10.0766886,12.3004639 10.2433156,12.4198383 L13.6056956,14.966493 C13.891697,15.1803725 14.2970729,15.1231721 14.5109517,14.8371707 C14.7248313,14.5511692 14.6676309,14.145794 14.3816294,13.9319145 L12.5313257,12.5392127 L21.8812495,12.5392127 L21.8812495,11.2658854 L12.5313257,11.2658854 L14.3816294,9.87318364 C14.6377872,9.71650453 14.7497006,9.40066014 14.6477351,9.11714553 C14.5482564,8.83363156 14.262255,8.65954352 13.9638189,8.699335 Z&quot; id=&quot;arrow&quot; fill=&quot;#000000&quot; transform=&quot;translate(15.929230, 11.894737) rotate(-180.000000) translate(-15.929230, -11.894737) &quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
&lt;/g&gt;
</code></pre>
<p></svg></td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color:#4CA64C;">✓</span></td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_right">2000</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">2000<br />1.00</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">0<br />0.00</td>
<td style="height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color: #AAAAAA;">○</span></td>
<td style="height: 40px; background-color: #FCFCFC;" class="gt_row gt_center"><span style="color: #EBBC14;">○</span></td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color: #FF3300;">○</span></td>
<td style="height: 40px;" class="gt_row gt_center">—</td></p>
  </tr>
  <tr>
    <td style="height: 40px; background-color: #EBBC14; color: transparent;font-size: 0px;" class="gt_row gt_left">#EBBC14</td>
    <td style="height: 40px; color: #666666;font-size: 13px;font-weight: bold;" class="gt_row gt_right">5</td>
    <td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_left">
        <div style="margin: 0; padding: 0; display: inline-block; height: 30px; vertical-align: middle; width: 16%;">
            <!--?xml version="1.0" encoding="UTF-8"?--><?xml version="1.0" encoding="UTF-8"?>
<svg width="30px" height="30px" viewBox="0 0 67 67" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <title>col_vals_in_set</title>
    <g id="Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="col_vals_in_set" transform="translate(0.000000, 0.172414)">
            <path d="M56.712234,1 C59.1975153,1 61.4475153,2.00735931 63.076195,3.63603897 C64.7048747,5.26471863 65.712234,7.51471863 65.712234,10 L65.712234,10 L65.712234,65 L10.712234,65 C8.22695259,65 5.97695259,63.9926407 4.34827294,62.363961 C2.71959328,60.7352814 1.71223397,58.4852814 1.71223397,56 L1.71223397,56 L1.71223397,10 C1.71223397,7.51471863 2.71959328,5.26471863 4.34827294,3.63603897 C5.97695259,2.00735931 8.22695259,1 10.712234,1 L10.712234,1 Z" id="rectangle" stroke="#000000" stroke-width="2" fill="#FFFFFF"></path>
            <path d="M44.127969,41.1538382 L31.0814568,41.1538382 C29.9510748,41.1536429 28.8827052,40.9256134 27.9079888,40.5136953 C26.4467442,39.8960136 25.19849,38.8599685 24.3189894,37.5577099 C23.8792391,36.906727 23.5314818,36.1899233 23.2936866,35.4252675 C23.2130217,35.16589 23.1460289,34.9005554 23.0913409,34.6307286 L44.1278714,34.6307286 C45.028466,34.6306309 45.7586488,33.9004481 45.7586488,32.9998535 C45.7586488,32.0992589 45.028466,31.3690761 44.1278714,31.3690761 L23.0905596,31.3690761 C23.1990567,30.8337194 23.3597028,30.3180894 23.5675173,29.8264831 C24.185199,28.3652386 25.2212442,27.1169844 26.5236004,26.2374838 C27.1745833,25.7977334 27.891387,25.4499762 28.6560428,25.2122786 C29.4208939,24.9744833 30.2334994,24.8459665 31.0813591,24.8459665 L44.1277737,24.8459665 C45.0283683,24.8459665 45.7586488,24.1157837 45.7586488,23.2151891 C45.7586488,22.3145945 45.0283683,21.5844117 44.1277737,21.5844117 L31.0813591,21.5844117 C29.5096643,21.5844117 28.0039858,21.9038483 26.6373711,22.4820765 C24.5866678,23.3498583 22.8469049,24.7950871 21.6163267,26.616296 C20.3856508,28.4362354 19.665136,30.6413347 19.6658191,33.0000488 C19.6658191,34.5717436 19.9852563,36.0774222 20.5635822,37.4440369 C21.4312663,39.4947402 22.8765927,41.2345031 24.697704,42.4650813 C26.5176434,43.6957572 28.7227427,44.4155883 31.0814568,44.4155883 L44.1278714,44.4155883 C45.028466,44.4155883 45.7586488,43.6854055 45.7586488,42.7848109 C45.7586488,41.8842163 45.0285636,41.1538382 44.127969,41.1538382 Z" id="set_of" fill="#000000" fill-rule="nonzero"></path>
        </g>
    </g>
</svg>
        </div>
        <div style="font-family: 'IBM Plex Mono', monospace, courier; color: black; font-size: 11px; display: inline-block; vertical-align: middle;">
            <div>col_vals_in_set()</div>
        </div>
<pre><code>    &lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;acquisition&lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;google, facebook, organic, crosspromo, other_campaign&lt;/td&gt;
&lt;td style=&quot;height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;&quot; class=&quot;gt_row gt_center&quot;&gt;&lt;svg width=&quot;25px&quot; height=&quot;25px&quot; viewBox=&quot;0 0 25 25&quot; version=&quot;1.1&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot; style=&quot;vertical-align: middle;&quot;&gt;
&lt;g id=&quot;unchanged&quot; stroke=&quot;none&quot; stroke-width=&quot;1&quot; fill=&quot;none&quot; fill-rule=&quot;evenodd&quot;&gt;
    &lt;g id=&quot;unchanged&quot; transform=&quot;translate(0.500000, 0.570147)&quot;&gt;
        &lt;rect id=&quot;Rectangle&quot; x=&quot;0.125132506&quot; y=&quot;0&quot; width=&quot;23.749735&quot; height=&quot;23.7894737&quot;&gt;&lt;/rect&gt;
        &lt;path d=&quot;M5.80375046,8.18194736 C3.77191832,8.18194736 2.11875046,9.83495328 2.11875046,11.8669474 C2.11875046,13.8989414 3.77191832,15.5519474 5.80375046,15.5519474 C7.8355826,15.5519474 9.48875046,13.8989414 9.48875046,11.8669474 C9.48875046,9.83495328 7.83552863,8.18194736 5.80375046,8.18194736 Z M5.80375046,14.814915 C4.17821997,14.814915 2.85578285,13.4924778 2.85578285,11.8669474 C2.85578285,10.2414169 4.17821997,8.91897975 5.80375046,8.91897975 C7.42928095,8.91897975 8.75171807,10.2414169 8.75171807,11.8669474 C8.75171807,13.4924778 7.42928095,14.814915 5.80375046,14.814915 Z&quot; id=&quot;Shape&quot; fill=&quot;#000000&quot; fill-rule=&quot;nonzero&quot;&gt;&lt;/path&gt;
        &lt;path d=&quot;M13.9638189,8.699335 C13.9364621,8.70430925 13.9091059,8.71176968 13.8842359,8.71923074 C13.7822704,8.73663967 13.6877654,8.77643115 13.6056956,8.83860518 L10.2433156,11.3852598 C10.0766886,11.5046343 9.97720993,11.6986181 9.97720993,11.9025491 C9.97720993,12.1064807 10.0766886,12.3004639 10.2433156,12.4198383 L13.6056956,14.966493 C13.891697,15.1803725 14.2970729,15.1231721 14.5109517,14.8371707 C14.7248313,14.5511692 14.6676309,14.145794 14.3816294,13.9319145 L12.5313257,12.5392127 L21.8812495,12.5392127 L21.8812495,11.2658854 L12.5313257,11.2658854 L14.3816294,9.87318364 C14.6377872,9.71650453 14.7497006,9.40066014 14.6477351,9.11714553 C14.5482564,8.83363156 14.262255,8.65954352 13.9638189,8.699335 Z&quot; id=&quot;arrow&quot; fill=&quot;#000000&quot; transform=&quot;translate(15.929230, 11.894737) rotate(-180.000000) translate(-15.929230, -11.894737) &quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
&lt;/g&gt;
</code></pre>
<p></svg></td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color:#4CA64C;">✓</span></td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_right">2000</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">1975<br />0.99</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">25<br />0.01</td>
<td style="height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color: #AAAAAA;">●</span></td>
<td style="height: 40px; background-color: #FCFCFC;" class="gt_row gt_center"><span style="color: #EBBC14;">●</span></td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color: #FF3300;">○</span></td>
<td style="height: 40px;" class="gt_row gt_center"><a href="data:text/csv;base64,X3Jvd19udW1fLHBsYXllcl9pZCxzZXNzaW9uX2lkLHNlc3Npb25fc3RhcnQsdGltZSxpdGVtX3R5cGUsaXRlbV9uYW1lLGl0ZW1fcmV2ZW51ZSxzZXNzaW9uX2R1cmF0aW9uLHN0YXJ0X2RheSxhY3F1aXNpdGlvbixjb3VudHJ5CjEzODMsRUtJSFhCUkZHT0NENTcxLEVLSUhYQlJGR09DRDU3MS1tM3QxaW41NywyMDE1LTAxLTE3VDAyOjQxOjQ1LjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMDI6NDg6MDkuMDAwMDAwKzAwMDAsYWQsYWRfc3VydmV5LDEuNDgsMTguOSwyMDE1LTAxLTE3LGFwcGxlLFVuaXRlZCBLaW5nZG9tCjEzODQsRUtJSFhCUkZHT0NENTcxLEVLSUhYQlJGR09DRDU3MS1tM3QxaW41NywyMDE1LTAxLTE3VDAyOjQxOjQ1LjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMDI6NTA6MjEuMDAwMDAwKzAwMDAsYWQsYWRfMTVzZWMsMC41NywxOC45LDIwMTUtMDEtMTcsYXBwbGUsVW5pdGVkIEtpbmdkb20KMTM4NSxFS0lIWEJSRkdPQ0Q1NzEsRUtJSFhCUkZHT0NENTcxLW0zdDFpbjU3LDIwMTUtMDEtMTdUMDI6NDE6NDUuMDAwMDAwKzAwMDAsMjAxNS0wMS0xN1QwMjo1MTo0NS4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjE5LDE4LjksMjAxNS0wMS0xNyxhcHBsZSxVbml0ZWQgS2luZ2RvbQoxNDIwLEVLSUhYQlJGR09DRDU3MSxFS0lIWEJSRkdPQ0Q1NzEtbjVrZTJhbDcsMjAxNS0wMS0xN1QwODoxNjoxNi4wMDAwMDArMDAwMCwyMDE1LTAxLTE3VDA4OjE2OjU4LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wOCwzNy4yLDIwMTUtMDEtMTcsYXBwbGUsVW5pdGVkIEtpbmdkb20KMTQyMSxFS0lIWEJSRkdPQ0Q1NzEsRUtJSFhCUkZHT0NENTcxLW41a2UyYWw3LDIwMTUtMDEtMTdUMDg6MTY6MTYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xN1QwODozMzo0MC4wMDAwMDArMDAwMCxpYXAsZ29sZDMsNC45OSwzNy4yLDIwMTUtMDEtMTcsYXBwbGUsVW5pdGVkIEtpbmdkb20KMTQyMixFS0lIWEJSRkdPQ0Q1NzEsRUtJSFhCUkZHT0NENTcxLW41a2UyYWw3LDIwMTUtMDEtMTdUMDg6MTY6MTYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xN1QwODozODo1Mi4wMDAwMDArMDAwMCxhZCxhZF9wbGF5YWJsZSwxLjAxLDM3LjIsMjAxNS0wMS0xNyxhcHBsZSxVbml0ZWQgS2luZ2RvbQoxNDIzLEVLSUhYQlJGR09DRDU3MSxFS0lIWEJSRkdPQ0Q1NzEtbjVrZTJhbDcsMjAxNS0wMS0xN1QwODoxNjoxNi4wMDAwMDArMDAwMCwyMDE1LTAxLTE3VDA4OjQyOjE2LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4xMSwzNy4yLDIwMTUtMDEtMTcsYXBwbGUsVW5pdGVkIEtpbmdkb20KMTQyNCxFS0lIWEJSRkdPQ0Q1NzEsRUtJSFhCUkZHT0NENTcxLW41a2UyYWw3LDIwMTUtMDEtMTdUMDg6MTY6MTYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xN1QwODo0NDowNC4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjExLDM3LjIsMjAxNS0wMS0xNyxhcHBsZSxVbml0ZWQgS2luZ2RvbQoxNDc2LEVLSUhYQlJGR09DRDU3MSxFS0lIWEJSRkdPQ0Q1NzEtNmwxZDV4anEsMjAxNS0wMS0xN1QxMjo1OToyNC4wMDAwMDArMDAwMCwyMDE1LTAxLTE3VDEzOjAxOjI0LjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDksMzMuNSwyMDE1LTAxLTE3LGFwcGxlLFVuaXRlZCBLaW5nZG9tCjE0NzcsRUtJSFhCUkZHT0NENTcxLEVLSUhYQlJGR09DRDU3MS02bDFkNXhqcSwyMDE1LTAxLTE3VDEyOjU5OjI0LjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMTM6MDI6NDIuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA2LDMzLjUsMjAxNS0wMS0xNyxhcHBsZSxVbml0ZWQgS2luZ2RvbQoxNDc4LEVLSUhYQlJGR09DRDU3MSxFS0lIWEJSRkdPQ0Q1NzEtNmwxZDV4anEsMjAxNS0wMS0xN1QxMjo1OToyNC4wMDAwMDArMDAwMCwyMDE1LTAxLTE3VDEzOjE5OjEyLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4xLDMzLjUsMjAxNS0wMS0xNyxhcHBsZSxVbml0ZWQgS2luZ2RvbQoxNDc5LEVLSUhYQlJGR09DRDU3MSxFS0lIWEJSRkdPQ0Q1NzEtNmwxZDV4anEsMjAxNS0wMS0xN1QxMjo1OToyNC4wMDAwMDArMDAwMCwyMDE1LTAxLTE3VDEzOjI3OjQyLjAwMDAwMCswMDAwLGFkLGFkXzE1c2VjLDAuMzQ5NywzMy41LDIwMTUtMDEtMTcsYXBwbGUsVW5pdGVkIEtpbmdkb20KMTU5MyxFS0lIWEJSRkdPQ0Q1NzEsRUtJSFhCUkZHT0NENTcxLWhvbHVjOTFhLDIwMTUtMDEtMThUMDc6MTE6NDAuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOFQwNzoxNDo1OC4wMDAwMDArMDAwMCxhZCxhZF8xNXNlYywwLjMyLDEyLjYsMjAxNS0wMS0xNyxhcHBsZSxVbml0ZWQgS2luZ2RvbQoxNTk0LEVLSUhYQlJGR09DRDU3MSxFS0lIWEJSRkdPQ0Q1NzEtaG9sdWM5MWEsMjAxNS0wMS0xOFQwNzoxMTo0MC4wMDAwMDArMDAwMCwyMDE1LTAxLTE4VDA3OjE4OjU4LjAwMDAwMCswMDAwLGlhcCxvZmZlcjMsMTQuOTksMTIuNiwyMDE1LTAxLTE3LGFwcGxlLFVuaXRlZCBLaW5nZG9tCjE2NTcsRUtJSFhCUkZHT0NENTcxLEVLSUhYQlJGR09DRDU3MS1kdnFneG01NiwyMDE1LTAxLTE4VDE1OjI5OjIyLjAwMDAwMCswMDAwLDIwMTUtMDEtMThUMTU6MzM6MjguMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4xNywzNS45LDIwMTUtMDEtMTcsYXBwbGUsVW5pdGVkIEtpbmdkb20KMTY1OCxFS0lIWEJSRkdPQ0Q1NzEsRUtJSFhCUkZHT0NENTcxLWR2cWd4bTU2LDIwMTUtMDEtMThUMTU6Mjk6MjIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOFQxNTozNDoxNi4wMDAwMDArMDAwMCxpYXAsb2ZmZXIyLDkuOTksMzUuOSwyMDE1LTAxLTE3LGFwcGxlLFVuaXRlZCBLaW5nZG9tCjE2NTksRUtJSFhCUkZHT0NENTcxLEVLSUhYQlJGR09DRDU3MS1kdnFneG01NiwyMDE1LTAxLTE4VDE1OjI5OjIyLjAwMDAwMCswMDAwLDIwMTUtMDEtMThUMTU6MzY6MTYuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA1LDM1LjksMjAxNS0wMS0xNyxhcHBsZSxVbml0ZWQgS2luZ2RvbQoxNjYwLEVLSUhYQlJGR09DRDU3MSxFS0lIWEJSRkdPQ0Q1NzEtZHZxZ3htNTYsMjAxNS0wMS0xOFQxNToyOToyMi4wMDAwMDArMDAwMCwyMDE1LTAxLTE4VDE1OjQzOjI4LjAwMDAwMCswMDAwLGFkLGFkXzE1c2VjLDAuMTYsMzUuOSwyMDE1LTAxLTE3LGFwcGxlLFVuaXRlZCBLaW5nZG9tCjE2NjEsRUtJSFhCUkZHT0NENTcxLEVLSUhYQlJGR09DRDU3MS1kdnFneG01NiwyMDE1LTAxLTE4VDE1OjI5OjIyLjAwMDAwMCswMDAwLDIwMTUtMDEtMThUMTU6NTQ6NTIuMDAwMDAwKzAwMDAsYWQsYWRfc3VydmV5LDAuNjEsMzUuOSwyMDE1LTAxLTE3LGFwcGxlLFVuaXRlZCBLaW5nZG9tCjE2NjIsRUtJSFhCUkZHT0NENTcxLEVLSUhYQlJGR09DRDU3MS1kdnFneG01NiwyMDE1LTAxLTE4VDE1OjI5OjIyLjAwMDAwMCswMDAwLDIwMTUtMDEtMThUMTY6MDQ6MTYuMDAwMDAwKzAwMDAsYWQsYWRfc3VydmV5LDEuMCwzNS45LDIwMTUtMDEtMTcsYXBwbGUsVW5pdGVkIEtpbmdkb20KMTcyNSxFS0lIWEJSRkdPQ0Q1NzEsRUtJSFhCUkZHT0NENTcxLWFqd3R1emhuLDIwMTUtMDEtMTlUMDM6MDE6MzkuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOVQwMzowNDoyMS4wMDAwMDArMDAwMCxhZCxhZF8yMHNlYywxLjA4LDYuOCwyMDE1LTAxLTE3LGFwcGxlLFVuaXRlZCBLaW5nZG9tCjE4MzgsRUtJSFhCUkZHT0NENTcxLEVLSUhYQlJGR09DRDU3MS03bml4cWJ0OSwyMDE1LTAxLTE5VDIwOjA4OjU4LjAwMDAwMCswMDAwLDIwMTUtMDEtMTlUMjA6MTI6MTAuMDAwMDAwKzAwMDAsaWFwLG9mZmVyMSw0Ljk5LDExLjYsMjAxNS0wMS0xNyxhcHBsZSxVbml0ZWQgS2luZ2RvbQoxODM5LEVLSUhYQlJGR09DRDU3MSxFS0lIWEJSRkdPQ0Q1NzEtN25peHFidDksMjAxNS0wMS0xOVQyMDowODo1OC4wMDAwMDArMDAwMCwyMDE1LTAxLTE5VDIwOjE0OjM0LjAwMDAwMCswMDAwLGFkLGFkXzIwc2VjLDAuOCwxMS42LDIwMTUtMDEtMTcsYXBwbGUsVW5pdGVkIEtpbmdkb20KMTg0MCxFS0lIWEJSRkdPQ0Q1NzEsRUtJSFhCUkZHT0NENTcxLTduaXhxYnQ5LDIwMTUtMDEtMTlUMjA6MDg6NTguMDAwMDAwKzAwMDAsMjAxNS0wMS0xOVQyMDoxOTo1Mi4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjE0LDExLjYsMjAxNS0wMS0xNyxhcHBsZSxVbml0ZWQgS2luZ2RvbQoxODg1LEVLSUhYQlJGR09DRDU3MSxFS0lIWEJSRkdPQ0Q1NzEtcHIxbWplaGMsMjAxNS0wMS0yMFQwNjoyNDo1MC4wMDAwMDArMDAwMCwyMDE1LTAxLTIwVDA2OjMyOjI2LjAwMDAwMCswMDAwLGFkLGFkXzIwc2VjLDAuNjQ5LDEzLjQsMjAxNS0wMS0xNyxhcHBsZSxVbml0ZWQgS2luZ2RvbQo=" download="extract_0005.csv"><button style="background-color: #67C2DC; color: #FFFFFF; border: none; padding: 5px; font-weight: bold; cursor: pointer; border-radius: 4px;">CSV</button></a></td></p>
  </tr>
  <tr>
    <td style="height: 40px; background-color: #FF3300; color: transparent;font-size: 0px;" class="gt_row gt_left">#FF3300</td>
    <td style="height: 40px; color: #666666;font-size: 13px;font-weight: bold;" class="gt_row gt_right">6</td>
    <td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_left">
        <div style="margin: 0; padding: 0; display: inline-block; height: 30px; vertical-align: middle; width: 16%;">
            <!--?xml version="1.0" encoding="UTF-8"?--><?xml version="1.0" encoding="UTF-8"?>
<svg width="30px" height="30px" viewBox="0 0 67 67" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <title>col_vals_not_in_set</title>
    <g id="Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="col_vals_not_in_set" transform="translate(0.000000, 0.655172)">
            <path d="M56.712234,1 C59.1975153,1 61.4475153,2.00735931 63.076195,3.63603897 C64.7048747,5.26471863 65.712234,7.51471863 65.712234,10 L65.712234,10 L65.712234,65 L10.712234,65 C8.22695259,65 5.97695259,63.9926407 4.34827294,62.363961 C2.71959328,60.7352814 1.71223397,58.4852814 1.71223397,56 L1.71223397,56 L1.71223397,10 C1.71223397,7.51471863 2.71959328,5.26471863 4.34827294,3.63603897 C5.97695259,2.00735931 8.22695259,1 10.712234,1 L10.712234,1 Z" id="rectangle" stroke="#000000" stroke-width="2" fill="#FFFFFF"></path>
            <path d="M44.127969,41.1538382 L31.0814568,41.1538382 C29.9510748,41.1536429 28.8827052,40.9256134 27.9079888,40.5136953 C26.4467442,39.8960136 25.19849,38.8599685 24.3189894,37.5577099 C23.8792391,36.906727 23.5314818,36.1899233 23.2936866,35.4252675 C23.2130217,35.16589 23.1460289,34.9005554 23.0913409,34.6307286 L44.1278714,34.6307286 C45.028466,34.6306309 45.7586488,33.9004481 45.7586488,32.9998535 C45.7586488,32.0992589 45.028466,31.3690761 44.1278714,31.3690761 L23.0905596,31.3690761 C23.1990567,30.8337194 23.3597028,30.3180894 23.5675173,29.8264831 C24.185199,28.3652386 25.2212442,27.1169844 26.5236004,26.2374838 C27.1745833,25.7977334 27.891387,25.4499762 28.6560428,25.2122786 C29.4208939,24.9744833 30.2334994,24.8459665 31.0813591,24.8459665 L44.1277737,24.8459665 C45.0283683,24.8459665 45.7586488,24.1157837 45.7586488,23.2151891 C45.7586488,22.3145945 45.0283683,21.5844117 44.1277737,21.5844117 L31.0813591,21.5844117 C29.5096643,21.5844117 28.0039858,21.9038483 26.6373711,22.4820765 C24.5866678,23.3498583 22.8469049,24.7950871 21.6163267,26.616296 C20.3856508,28.4362354 19.665136,30.6413347 19.6658191,33.0000488 C19.6658191,34.5717436 19.9852563,36.0774222 20.5635822,37.4440369 C21.4312663,39.4947402 22.8765927,41.2345031 24.697704,42.4650813 C26.5176434,43.6957572 28.7227427,44.4155883 31.0814568,44.4155883 L44.1278714,44.4155883 C45.028466,44.4155883 45.7586488,43.6854055 45.7586488,42.7848109 C45.7586488,41.8842163 45.0285636,41.1538382 44.127969,41.1538382 Z" id="set_of" fill="#000000" fill-rule="nonzero"></path>
            <path d="M32.7624859,7.45752636 C33.0386282,7.45752636 33.2624859,7.68138398 33.2624859,7.95752636 L33.2624859,57.0855723 C33.2624859,57.3617146 33.0386282,57.5855723 32.7624859,57.5855723 C32.4863435,57.5855723 32.2624859,57.3617146 32.2624859,57.0855723 L32.2624859,7.95752636 C32.2624859,7.68138398 32.4863435,7.45752636 32.7624859,7.45752636 Z" id="line_black" fill="#000000" transform="translate(32.762486, 32.521549) rotate(-320.000000) translate(-32.762486, -32.521549) "></path>
            <polygon id="line_white" fill="#FFFFFF" transform="translate(34.661982, 31.674853) rotate(-320.000000) translate(-34.661982, -31.674853) " points="34.1619821 8.063154 35.1619821 8.063154 35.1619821 55.2865512 34.1619821 55.2865512"></polygon>
        </g>
    </g>
</svg>
        </div>
        <div style="font-family: 'IBM Plex Mono', monospace, courier; color: black; font-size: 10px; display: inline-block; vertical-align: middle;">
            <div>col_vals_not_in_set()</div>
        </div>
<pre><code>    &lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;country&lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;Mongolia, Germany&lt;/td&gt;
&lt;td style=&quot;height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;&quot; class=&quot;gt_row gt_center&quot;&gt;&lt;svg width=&quot;25px&quot; height=&quot;25px&quot; viewBox=&quot;0 0 25 25&quot; version=&quot;1.1&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot; style=&quot;vertical-align: middle;&quot;&gt;
&lt;g id=&quot;unchanged&quot; stroke=&quot;none&quot; stroke-width=&quot;1&quot; fill=&quot;none&quot; fill-rule=&quot;evenodd&quot;&gt;
    &lt;g id=&quot;unchanged&quot; transform=&quot;translate(0.500000, 0.570147)&quot;&gt;
        &lt;rect id=&quot;Rectangle&quot; x=&quot;0.125132506&quot; y=&quot;0&quot; width=&quot;23.749735&quot; height=&quot;23.7894737&quot;&gt;&lt;/rect&gt;
        &lt;path d=&quot;M5.80375046,8.18194736 C3.77191832,8.18194736 2.11875046,9.83495328 2.11875046,11.8669474 C2.11875046,13.8989414 3.77191832,15.5519474 5.80375046,15.5519474 C7.8355826,15.5519474 9.48875046,13.8989414 9.48875046,11.8669474 C9.48875046,9.83495328 7.83552863,8.18194736 5.80375046,8.18194736 Z M5.80375046,14.814915 C4.17821997,14.814915 2.85578285,13.4924778 2.85578285,11.8669474 C2.85578285,10.2414169 4.17821997,8.91897975 5.80375046,8.91897975 C7.42928095,8.91897975 8.75171807,10.2414169 8.75171807,11.8669474 C8.75171807,13.4924778 7.42928095,14.814915 5.80375046,14.814915 Z&quot; id=&quot;Shape&quot; fill=&quot;#000000&quot; fill-rule=&quot;nonzero&quot;&gt;&lt;/path&gt;
        &lt;path d=&quot;M13.9638189,8.699335 C13.9364621,8.70430925 13.9091059,8.71176968 13.8842359,8.71923074 C13.7822704,8.73663967 13.6877654,8.77643115 13.6056956,8.83860518 L10.2433156,11.3852598 C10.0766886,11.5046343 9.97720993,11.6986181 9.97720993,11.9025491 C9.97720993,12.1064807 10.0766886,12.3004639 10.2433156,12.4198383 L13.6056956,14.966493 C13.891697,15.1803725 14.2970729,15.1231721 14.5109517,14.8371707 C14.7248313,14.5511692 14.6676309,14.145794 14.3816294,13.9319145 L12.5313257,12.5392127 L21.8812495,12.5392127 L21.8812495,11.2658854 L12.5313257,11.2658854 L14.3816294,9.87318364 C14.6377872,9.71650453 14.7497006,9.40066014 14.6477351,9.11714553 C14.5482564,8.83363156 14.262255,8.65954352 13.9638189,8.699335 Z&quot; id=&quot;arrow&quot; fill=&quot;#000000&quot; transform=&quot;translate(15.929230, 11.894737) rotate(-180.000000) translate(-15.929230, -11.894737) &quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
&lt;/g&gt;
</code></pre>
<p></svg></td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color:#4CA64C;">✓</span></td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_right">2000</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">1775<br />0.89</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">225<br />0.11</td>
<td style="height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color: #AAAAAA;">●</span></td>
<td style="height: 40px; background-color: #FCFCFC;" class="gt_row gt_center"><span style="color: #EBBC14;">●</span></td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color: #FF3300;">●</span></td>
<td style="height: 40px;" class="gt_row gt_center"><a href="data:text/csv;base64,X3Jvd19udW1fLHBsYXllcl9pZCxzZXNzaW9uX2lkLHNlc3Npb25fc3RhcnQsdGltZSxpdGVtX3R5cGUsaXRlbV9uYW1lLGl0ZW1fcmV2ZW51ZSxzZXNzaW9uX2R1cmF0aW9uLHN0YXJ0X2RheSxhY3F1aXNpdGlvbixjb3VudHJ5CjEsRUNQQU5PSVhMWkhGODk2LEVDUEFOT0lYTFpIRjg5Ni1lb2wyajhicywyMDE1LTAxLTAxVDAxOjMxOjAzLjAwMDAwMCswMDAwLDIwMTUtMDEtMDFUMDE6MzE6MjcuMDAwMDAwKzAwMDAsaWFwLG9mZmVyMiw4Ljk5LDE2LjMsMjAxNS0wMS0wMSxnb29nbGUsR2VybWFueQoyLEVDUEFOT0lYTFpIRjg5NixFQ1BBTk9JWExaSEY4OTYtZW9sMmo4YnMsMjAxNS0wMS0wMVQwMTozMTowMy4wMDAwMDArMDAwMCwyMDE1LTAxLTAxVDAxOjM2OjU3LjAwMDAwMCswMDAwLGlhcCxnZW1zMywyMi40OSwxNi4zLDIwMTUtMDEtMDEsZ29vZ2xlLEdlcm1hbnkKMyxFQ1BBTk9JWExaSEY4OTYsRUNQQU5PSVhMWkhGODk2LWVvbDJqOGJzLDIwMTUtMDEtMDFUMDE6MzE6MDMuMDAwMDAwKzAwMDAsMjAxNS0wMS0wMVQwMTozNzo0NS4wMDAwMDArMDAwMCxpYXAsZ29sZDcsMTA3Ljk5LDE2LjMsMjAxNS0wMS0wMSxnb29nbGUsR2VybWFueQo0LEVDUEFOT0lYTFpIRjg5NixFQ1BBTk9JWExaSEY4OTYtZW9sMmo4YnMsMjAxNS0wMS0wMVQwMTozMTowMy4wMDAwMDArMDAwMCwyMDE1LTAxLTAxVDAxOjQyOjMzLjAwMDAwMCswMDAwLGFkLGFkXzIwc2VjLDAuNzYsMTYuMywyMDE1LTAxLTAxLGdvb2dsZSxHZXJtYW55CjUsRUNQQU5PSVhMWkhGODk2LEVDUEFOT0lYTFpIRjg5Ni1oZHU5amtscywyMDE1LTAxLTAxVDExOjUwOjAyLjAwMDAwMCswMDAwLDIwMTUtMDEtMDFUMTE6NTU6MjAuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAzLDM1LjIsMjAxNS0wMS0wMSxnb29nbGUsR2VybWFueQo2LEVDUEFOT0lYTFpIRjg5NixFQ1BBTk9JWExaSEY4OTYtaGR1OWprbHMsMjAxNS0wMS0wMVQxMTo1MDowMi4wMDAwMDArMDAwMCwyMDE1LTAxLTAxVDEyOjA4OjU2LjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDcsMzUuMiwyMDE1LTAxLTAxLGdvb2dsZSxHZXJtYW55CjcsRUNQQU5PSVhMWkhGODk2LEVDUEFOT0lYTFpIRjg5Ni1oZHU5amtscywyMDE1LTAxLTAxVDExOjUwOjAyLjAwMDAwMCswMDAwLDIwMTUtMDEtMDFUMTI6MTQ6MDguMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4wOCwzNS4yLDIwMTUtMDEtMDEsZ29vZ2xlLEdlcm1hbnkKOCxFQ1BBTk9JWExaSEY4OTYsRUNQQU5PSVhMWkhGODk2LWhkdTlqa2xzLDIwMTUtMDEtMDFUMTE6NTA6MDIuMDAwMDAwKzAwMDAsMjAxNS0wMS0wMVQxMjoyMTo0NC4wMDAwMDArMDAwMCxhZCxhZF8zMHNlYywxLjE3LDM1LjIsMjAxNS0wMS0wMSxnb29nbGUsR2VybWFueQo5LEVDUEFOT0lYTFpIRjg5NixFQ1BBTk9JWExaSEY4OTYtaGR1OWprbHMsMjAxNS0wMS0wMVQxMTo1MDowMi4wMDAwMDArMDAwMCwyMDE1LTAxLTAxVDEyOjI0OjIwLjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMTQsMzUuMiwyMDE1LTAxLTAxLGdvb2dsZSxHZXJtYW55CjI4LEVDUEFOT0lYTFpIRjg5NixFQ1BBTk9JWExaSEY4OTYteGViMW1pNHIsMjAxNS0wMS0wMlQwMjo0MTo1Ny4wMDAwMDArMDAwMCwyMDE1LTAxLTAyVDAyOjQ2OjI3LjAwMDAwMCswMDAwLGlhcCxnZW1zNCw1My45OSwyOC4zLDIwMTUtMDEtMDEsZ29vZ2xlLEdlcm1hbnkKMjksRUNQQU5PSVhMWkhGODk2LEVDUEFOT0lYTFpIRjg5Ni14ZWIxbWk0ciwyMDE1LTAxLTAyVDAyOjQxOjU3LjAwMDAwMCswMDAwLDIwMTUtMDEtMDJUMDI6NTA6MjcuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyLDI4LjMsMjAxNS0wMS0wMSxnb29nbGUsR2VybWFueQozMCxFQ1BBTk9JWExaSEY4OTYsRUNQQU5PSVhMWkhGODk2LXhlYjFtaTRyLDIwMTUtMDEtMDJUMDI6NDE6NTcuMDAwMDAwKzAwMDAsMjAxNS0wMS0wMlQwMjo1ODoxNS4wMDAwMDArMDAwMCxhZCxhZF8yMHNlYywwLjUzLDI4LjMsMjAxNS0wMS0wMSxnb29nbGUsR2VybWFueQozMSxFQ1BBTk9JWExaSEY4OTYsRUNQQU5PSVhMWkhGODk2LXhlYjFtaTRyLDIwMTUtMDEtMDJUMDI6NDE6NTcuMDAwMDAwKzAwMDAsMjAxNS0wMS0wMlQwMjo1OToxNS4wMDAwMDArMDAwMCxpYXAsb2ZmZXIzLDEzLjQ5LDI4LjMsMjAxNS0wMS0wMSxnb29nbGUsR2VybWFueQozMixFQ1BBTk9JWExaSEY4OTYsRUNQQU5PSVhMWkhGODk2LXhlYjFtaTRyLDIwMTUtMDEtMDJUMDI6NDE6NTcuMDAwMDAwKzAwMDAsMjAxNS0wMS0wMlQwMzowNDowMy4wMDAwMDArMDAwMCxpYXAsZ2VtczQsNTMuOTksMjguMywyMDE1LTAxLTAxLGdvb2dsZSxHZXJtYW55CjMzLEVDUEFOT0lYTFpIRjg5NixFQ1BBTk9JWExaSEY4OTYteGViMW1pNHIsMjAxNS0wMS0wMlQwMjo0MTo1Ny4wMDAwMDArMDAwMCwyMDE1LTAxLTAyVDAzOjA0OjE1LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMywyOC4zLDIwMTUtMDEtMDEsZ29vZ2xlLEdlcm1hbnkKMzQsRUNQQU5PSVhMWkhGODk2LEVDUEFOT0lYTFpIRjg5Ni14ZWIxbWk0ciwyMDE1LTAxLTAyVDAyOjQxOjU3LjAwMDAwMCswMDAwLDIwMTUtMDEtMDJUMDM6MDQ6NTEuMDAwMDAwKzAwMDAsYWQsYWRfMTVzZWMsMC4zOCwyOC4zLDIwMTUtMDEtMDEsZ29vZ2xlLEdlcm1hbnkKMzUsRUNQQU5PSVhMWkhGODk2LEVDUEFOT0lYTFpIRjg5Ni14ZWIxbWk0ciwyMDE1LTAxLTAyVDAyOjQxOjU3LjAwMDAwMCswMDAwLDIwMTUtMDEtMDJUMDM6MDY6MzMuMDAwMDAwKzAwMDAsaWFwLG9mZmVyNSwyNi4wOSwyOC4zLDIwMTUtMDEtMDEsZ29vZ2xlLEdlcm1hbnkKNzAsRUNQQU5PSVhMWkhGODk2LEVDUEFOT0lYTFpIRjg5Ni1lb2J3Z2w0biwyMDE1LTAxLTAzVDA2OjExOjEwLjAwMDAwMCswMDAwLDIwMTUtMDEtMDNUMDY6MTY6MjguMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA3LDEwLjYsMjAxNS0wMS0wMSxnb29nbGUsR2VybWFueQo4MixFQ1BBTk9JWExaSEY4OTYsRUNQQU5PSVhMWkhGODk2LW55eGdiNjFqLDIwMTUtMDEtMDNUMjI6NTM6NTIuMDAwMDAwKzAwMDAsMjAxNS0wMS0wM1QyMjo1NDo0Ni4wMDAwMDArMDAwMCxpYXAsZ2VtczMsMjIuNDksMTUuNiwyMDE1LTAxLTAxLGdvb2dsZSxHZXJtYW55CjgzLEVDUEFOT0lYTFpIRjg5NixFQ1BBTk9JWExaSEY4OTYtbnl4Z2I2MWosMjAxNS0wMS0wM1QyMjo1Mzo1Mi4wMDAwMDArMDAwMCwyMDE1LTAxLTAzVDIzOjA0OjE2LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4xMiwxNS42LDIwMTUtMDEtMDEsZ29vZ2xlLEdlcm1hbnkKODQsRVFVRE5HWklDTUFLNDgyLEVRVUROR1pJQ01BSzQ4Mi04dWF5OXc3NSwyMDE1LTAxLTA0VDAxOjIxOjAzLjAwMDAwMCswMDAwLDIwMTUtMDEtMDRUMDE6MzY6MDMuMDAwMDAwKzAwMDAsYWQsYWRfMzBzZWMsMS4wMiwyNi44LDIwMTUtMDEtMDQsZ29vZ2xlLEdlcm1hbnkKODUsRVFVRE5HWklDTUFLNDgyLEVRVUROR1pJQ01BSzQ4Mi04dWF5OXc3NSwyMDE1LTAxLTA0VDAxOjIxOjAzLjAwMDAwMCswMDAwLDIwMTUtMDEtMDRUMDE6NDA6MzkuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA4LDI2LjgsMjAxNS0wMS0wNCxnb29nbGUsR2VybWFueQo4NixFUVVETkdaSUNNQUs0ODIsRVFVRE5HWklDTUFLNDgyLTh1YXk5dzc1LDIwMTUtMDEtMDRUMDE6MjE6MDMuMDAwMDAwKzAwMDAsMjAxNS0wMS0wNFQwMTo0Nzo1MS4wMDAwMDArMDAwMCxhZCxhZF8xNXNlYywwLjUsMjYuOCwyMDE1LTAxLTA0LGdvb2dsZSxHZXJtYW55CjkxLEVDUEFOT0lYTFpIRjg5NixFQ1BBTk9JWExaSEY4OTYtN3o5aHNhZ3EsMjAxNS0wMS0wNFQwMzoxNTozNC4wMDAwMDArMDAwMCwyMDE1LTAxLTA0VDAzOjMyOjU4LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMywzNS4xLDIwMTUtMDEtMDEsZ29vZ2xlLEdlcm1hbnkKOTIsRUNQQU5PSVhMWkhGODk2LEVDUEFOT0lYTFpIRjg5Ni03ejloc2FncSwyMDE1LTAxLTA0VDAzOjE1OjM0LjAwMDAwMCswMDAwLDIwMTUtMDEtMDRUMDM6NDM6MDQuMDAwMDAwKzAwMDAsYWQsYWRfMzBzZWMsMC43MywzNS4xLDIwMTUtMDEtMDEsZ29vZ2xlLEdlcm1hbnkKOTMsRUNQQU5PSVhMWkhGODk2LEVDUEFOT0lYTFpIRjg5Ni03ejloc2FncSwyMDE1LTAxLTA0VDAzOjE1OjM0LjAwMDAwMCswMDAwLDIwMTUtMDEtMDRUMDM6NDM6MjguMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyLDM1LjEsMjAxNS0wMS0wMSxnb29nbGUsR2VybWFueQo5NCxFQ1BBTk9JWExaSEY4OTYsRUNQQU5PSVhMWkhGODk2LTd6OWhzYWdxLDIwMTUtMDEtMDRUMDM6MTU6MzQuMDAwMDAwKzAwMDAsMjAxNS0wMS0wNFQwMzo0NToyMi4wMDAwMDArMDAwMCxpYXAsb2ZmZXIyLDguOTksMzUuMSwyMDE1LTAxLTAxLGdvb2dsZSxHZXJtYW55Cjk1LEVRVUROR1pJQ01BSzQ4MixFUVVETkdaSUNNQUs0ODItaDJuczZsdmksMjAxNS0wMS0wNFQwNDoxMzoyMS4wMDAwMDArMDAwMCwyMDE1LTAxLTA0VDA0OjE0OjE1LjAwMDAwMCswMDAwLGlhcCxnZW1zMiw4Ljk5LDE3LjIsMjAxNS0wMS0wNCxnb29nbGUsR2VybWFueQo5NixFUVVETkdaSUNNQUs0ODIsRVFVRE5HWklDTUFLNDgyLWgybnM2bHZpLDIwMTUtMDEtMDRUMDQ6MTM6MjEuMDAwMDAwKzAwMDAsMjAxNS0wMS0wNFQwNDoxNzo1Ny4wMDAwMDArMDAwMCxhZCxhZF8xNXNlYywwLjM0OSwxNy4yLDIwMTUtMDEtMDQsZ29vZ2xlLEdlcm1hbnkKOTcsRVFVRE5HWklDTUFLNDgyLEVRVUROR1pJQ01BSzQ4Mi1oMm5zNmx2aSwyMDE1LTAxLTA0VDA0OjEzOjIxLjAwMDAwMCswMDAwLDIwMTUtMDEtMDRUMDQ6Mjg6MzkuMDAwMDAwKzAwMDAsYWQsYWRfMTVzZWMsMC4yNSwxNy4yLDIwMTUtMDEtMDQsZ29vZ2xlLEdlcm1hbnkKMTEyLEVDUEFOT0lYTFpIRjg5NixFQ1BBTk9JWExaSEY4OTYtcmZscTcyaTMsMjAxNS0wMS0wNFQxODo0Mzo0Ni4wMDAwMDArMDAwMCwyMDE1LTAxLTA0VDE4OjQ4OjIyLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4xMSwxMS40LDIwMTUtMDEtMDEsZ29vZ2xlLEdlcm1hbnkKMTEzLEVDUEFOT0lYTFpIRjg5NixFQ1BBTk9JWExaSEY4OTYtcmZscTcyaTMsMjAxNS0wMS0wNFQxODo0Mzo0Ni4wMDAwMDArMDAwMCwyMDE1LTAxLTA0VDE4OjUxOjA0LjAwMDAwMCswMDAwLGlhcCxnb2xkNCwxNy45OSwxMS40LDIwMTUtMDEtMDEsZ29vZ2xlLEdlcm1hbnkKMTIyLEVRVUROR1pJQ01BSzQ4MixFUVVETkdaSUNNQUs0ODItNGt2NTg5ZW0sMjAxNS0wMS0wNVQwMjoyMDoxNi4wMDAwMDArMDAwMCwyMDE1LTAxLTA1VDAyOjIzOjM0LjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDcsMjkuOCwyMDE1LTAxLTA0LGdvb2dsZSxHZXJtYW55CjEyMyxFUVVETkdaSUNNQUs0ODIsRVFVRE5HWklDTUFLNDgyLTRrdjU4OWVtLDIwMTUtMDEtMDVUMDI6MjA6MTYuMDAwMDAwKzAwMDAsMjAxNS0wMS0wNVQwMjozMToyOC4wMDAwMDArMDAwMCxhZCxhZF8yMHNlYywwLjgyLDI5LjgsMjAxNS0wMS0wNCxnb29nbGUsR2VybWFueQoxMjQsRVFVRE5HWklDTUFLNDgyLEVRVUROR1pJQ01BSzQ4Mi00a3Y1ODllbSwyMDE1LTAxLTA1VDAyOjIwOjE2LjAwMDAwMCswMDAwLDIwMTUtMDEtMDVUMDI6NDA6MTYuMDAwMDAwKzAwMDAsYWQsYWRfMjBzZWMsMC40MSwyOS44LDIwMTUtMDEtMDQsZ29vZ2xlLEdlcm1hbnkKMTI1LEVRVUROR1pJQ01BSzQ4MixFUVVETkdaSUNNQUs0ODItNGt2NTg5ZW0sMjAxNS0wMS0wNVQwMjoyMDoxNi4wMDAwMDArMDAwMCwyMDE1LTAxLTA1VDAyOjQwOjM0LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNSwyOS44LDIwMTUtMDEtMDQsZ29vZ2xlLEdlcm1hbnkKMTMzLEVDUEFOT0lYTFpIRjg5NixFQ1BBTk9JWExaSEY4OTYtemo3cHhuY3QsMjAxNS0wMS0wNVQwOToxMzowMy4wMDAwMDArMDAwMCwyMDE1LTAxLTA1VDA5OjIwOjIxLjAwMDAwMCswMDAwLGlhcCxnZW1zNCw1My45OSwyOC4xLDIwMTUtMDEtMDEsZ29vZ2xlLEdlcm1hbnkKMTM0LEVDUEFOT0lYTFpIRjg5NixFQ1BBTk9JWExaSEY4OTYtemo3cHhuY3QsMjAxNS0wMS0wNVQwOToxMzowMy4wMDAwMDArMDAwMCwyMDE1LTAxLTA1VDA5OjI0OjE1LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4xMiwyOC4xLDIwMTUtMDEtMDEsZ29vZ2xlLEdlcm1hbnkKMTM1LEVDUEFOT0lYTFpIRjg5NixFQ1BBTk9JWExaSEY4OTYtemo3cHhuY3QsMjAxNS0wMS0wNVQwOToxMzowMy4wMDAwMDArMDAwMCwyMDE1LTAxLTA1VDA5OjI0OjIxLjAwMDAwMCswMDAwLGlhcCxvZmZlcjUsMjYuMDksMjguMSwyMDE1LTAxLTAxLGdvb2dsZSxHZXJtYW55CjEzNixFQ1BBTk9JWExaSEY4OTYsRUNQQU5PSVhMWkhGODk2LXpqN3B4bmN0LDIwMTUtMDEtMDVUMDk6MTM6MDMuMDAwMDAwKzAwMDAsMjAxNS0wMS0wNVQwOTozMjo0NS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMSwyOC4xLDIwMTUtMDEtMDEsZ29vZ2xlLEdlcm1hbnkKMTY2LEVRVUROR1pJQ01BSzQ4MixFUVVETkdaSUNNQUs0ODItNmt2aGZsejMsMjAxNS0wMS0wNlQxMToxMjoxMS4wMDAwMDArMDAwMCwyMDE1LTAxLTA2VDExOjE2OjI5LjAwMDAwMCswMDAwLGFkLGFkXzE1c2VjLDAuNDQsMjcuMiwyMDE1LTAxLTA0LGdvb2dsZSxHZXJtYW55CjE2NyxFUVVETkdaSUNNQUs0ODIsRVFVRE5HWklDTUFLNDgyLTZrdmhmbHozLDIwMTUtMDEtMDZUMTE6MTI6MTEuMDAwMDAwKzAwMDAsMjAxNS0wMS0wNlQxMToyMzoyOS4wMDAwMDArMDAwMCxhZCxhZF8zMHNlYywxLjI3LDI3LjIsMjAxNS0wMS0wNCxnb29nbGUsR2VybWFueQoxOTUsRVFVRE5HWklDTUFLNDgyLEVRVUROR1pJQ01BSzQ4Mi1reHZjbXFmciwyMDE1LTAxLTA2VDIzOjMwOjMwLjAwMDAwMCswMDAwLDIwMTUtMDEtMDZUMjM6Mzk6MTguMDAwMDAwKzAwMDAsYWQsYWRfMzBzZWMsMS4yOCwxNy40LDIwMTUtMDEtMDQsZ29vZ2xlLEdlcm1hbnkKMTk2LEVRVUROR1pJQ01BSzQ4MixFUVVETkdaSUNNQUs0ODIta3h2Y21xZnIsMjAxNS0wMS0wNlQyMzozMDozMC4wMDAwMDArMDAwMCwyMDE1LTAxLTA2VDIzOjQyOjI0LjAwMDAwMCswMDAwLGlhcCxnb2xkMiwxLjc5LDE3LjQsMjAxNS0wMS0wNCxnb29nbGUsR2VybWFueQoxOTcsRVFVRE5HWklDTUFLNDgyLEVRVUROR1pJQ01BSzQ4Mi1reHZjbXFmciwyMDE1LTAxLTA2VDIzOjMwOjMwLjAwMDAwMCswMDAwLDIwMTUtMDEtMDZUMjM6NDU6NTQuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4xLDE3LjQsMjAxNS0wMS0wNCxnb29nbGUsR2VybWFueQoxOTgsRVFVRE5HWklDTUFLNDgyLEVRVUROR1pJQ01BSzQ4Mi1reHZjbXFmciwyMDE1LTAxLTA2VDIzOjMwOjMwLjAwMDAwMCswMDAwLDIwMTUtMDEtMDZUMjM6NDc6MzAuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjEyLDE3LjQsMjAxNS0wMS0wNCxnb29nbGUsR2VybWFueQoyMTksR1NRSlhJT0tZTUVBNzEyLEdTUUpYSU9LWU1FQTcxMi00NXpldWxwZCwyMDE1LTAxLTA3VDA0OjQ2OjEyLjAwMDAwMCswMDAwLDIwMTUtMDEtMDdUMDQ6NTA6MzYuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAzLDM1LjIsMjAxNS0wMS0wNyxnb29nbGUsR2VybWFueQoyMjAsR1NRSlhJT0tZTUVBNzEyLEdTUUpYSU9LWU1FQTcxMi00NXpldWxwZCwyMDE1LTAxLTA3VDA0OjQ2OjEyLjAwMDAwMCswMDAwLDIwMTUtMDEtMDdUMDQ6NTU6MjQuMDAwMDAwKzAwMDAsYWQsYWRfMTVzZWMsMC42LDM1LjIsMjAxNS0wMS0wNyxnb29nbGUsR2VybWFueQoyMjEsR1NRSlhJT0tZTUVBNzEyLEdTUUpYSU9LWU1FQTcxMi00NXpldWxwZCwyMDE1LTAxLTA3VDA0OjQ2OjEyLjAwMDAwMCswMDAwLDIwMTUtMDEtMDdUMDU6MDM6NTQuMDAwMDAwKzAwMDAsYWQsYWRfcGxheWFibGUsMS42OCwzNS4yLDIwMTUtMDEtMDcsZ29vZ2xlLEdlcm1hbnkKMjQxLEdTUUpYSU9LWU1FQTcxMixHU1FKWElPS1lNRUE3MTItYnBka3N4bmosMjAxNS0wMS0wN1QwODo0MDowNC4wMDAwMDArMDAwMCwyMDE1LTAxLTA3VDA4OjQ0OjIyLjAwMDAwMCswMDAwLGFkLGFkX3N1cnZleSwwLjkxLDIwLjcsMjAxNS0wMS0wNyxnb29nbGUsR2VybWFueQoyNDIsR1NRSlhJT0tZTUVBNzEyLEdTUUpYSU9LWU1FQTcxMi1icGRrc3huaiwyMDE1LTAxLTA3VDA4OjQwOjA0LjAwMDAwMCswMDAwLDIwMTUtMDEtMDdUMDg6NDg6NDYuMDAwMDAwKzAwMDAsYWQsYWRfMTVzZWMsMC4xNSwyMC43LDIwMTUtMDEtMDcsZ29vZ2xlLEdlcm1hbnkKMjQzLEdTUUpYSU9LWU1FQTcxMixHU1FKWElPS1lNRUE3MTItYnBka3N4bmosMjAxNS0wMS0wN1QwODo0MDowNC4wMDAwMDArMDAwMCwyMDE1LTAxLTA3VDA4OjUzOjA0LjAwMDAwMCswMDAwLGlhcCxnb2xkMyw0LjQ5LDIwLjcsMjAxNS0wMS0wNyxnb29nbGUsR2VybWFueQoyNDQsR1NRSlhJT0tZTUVBNzEyLEdTUUpYSU9LWU1FQTcxMi1icGRrc3huaiwyMDE1LTAxLTA3VDA4OjQwOjA0LjAwMDAwMCswMDAwLDIwMTUtMDEtMDdUMDg6NTc6MjguMDAwMDAwKzAwMDAsYWQsYWRfMTVzZWMsMC40NDk1LDIwLjcsMjAxNS0wMS0wNyxnb29nbGUsR2VybWFueQoyNzAsRVFVRE5HWklDTUFLNDgyLEVRVUROR1pJQ01BSzQ4Mi00d29kaGlyeCwyMDE1LTAxLTA3VDE0OjIxOjIwLjAwMDAwMCswMDAwLDIwMTUtMDEtMDdUMTQ6MjY6NDQuMDAwMDAwKzAwMDAsaWFwLG9mZmVyMywxMy40OSwxOC40LDIwMTUtMDEtMDQsZ29vZ2xlLEdlcm1hbnkKMjcxLEVRVUROR1pJQ01BSzQ4MixFUVVETkdaSUNNQUs0ODItNHdvZGhpcngsMjAxNS0wMS0wN1QxNDoyMToyMC4wMDAwMDArMDAwMCwyMDE1LTAxLTA3VDE0OjM3OjUwLjAwMDAwMCswMDAwLGFkLGFkXzE1c2VjLDAuMzIsMTguNCwyMDE1LTAxLTA0LGdvb2dsZSxHZXJtYW55CjI3MixFUVVETkdaSUNNQUs0ODIsRVFVRE5HWklDTUFLNDgyLTR3b2RoaXJ4LDIwMTUtMDEtMDdUMTQ6MjE6MjAuMDAwMDAwKzAwMDAsMjAxNS0wMS0wN1QxNDozODo1MC4wMDAwMDArMDAwMCxhZCxhZF8zMHNlYywwLjczLDE4LjQsMjAxNS0wMS0wNCxnb29nbGUsR2VybWFueQoyNzMsRVFVRE5HWklDTUFLNDgyLEVRVUROR1pJQ01BSzQ4Mi00d29kaGlyeCwyMDE1LTAxLTA3VDE0OjIxOjIwLjAwMDAwMCswMDAwLDIwMTUtMDEtMDdUMTQ6Mzk6MjYuMDAwMDAwKzAwMDAsYWQsYWRfMTVzZWMsMC41NCwxOC40LDIwMTUtMDEtMDQsZ29vZ2xlLEdlcm1hbnkKMzI2LEVRVUROR1pJQ01BSzQ4MixFUVVETkdaSUNNQUs0ODIteTNkb3p3dnMsMjAxNS0wMS0wOFQwMjoyODozOC4wMDAwMDArMDAwMCwyMDE1LTAxLTA4VDAyOjMxOjMyLjAwMDAwMCswMDAwLGlhcCxnb2xkMyw0LjQ5LDI5LjMsMjAxNS0wMS0wNCxnb29nbGUsR2VybWFueQozMjcsRVFVRE5HWklDTUFLNDgyLEVRVUROR1pJQ01BSzQ4Mi15M2Rvend2cywyMDE1LTAxLTA4VDAyOjI4OjM4LjAwMDAwMCswMDAwLDIwMTUtMDEtMDhUMDI6Mzc6MDguMDAwMDAwKzAwMDAsaWFwLG9mZmVyMSw0LjQ5LDI5LjMsMjAxNS0wMS0wNCxnb29nbGUsR2VybWFueQozMjgsRVFVRE5HWklDTUFLNDgyLEVRVUROR1pJQ01BSzQ4Mi15M2Rvend2cywyMDE1LTAxLTA4VDAyOjI4OjM4LjAwMDAwMCswMDAwLDIwMTUtMDEtMDhUMDI6NDM6NTAuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4xNSwyOS4zLDIwMTUtMDEtMDQsZ29vZ2xlLEdlcm1hbnkKMzI5LEVRVUROR1pJQ01BSzQ4MixFUVVETkdaSUNNQUs0ODIteTNkb3p3dnMsMjAxNS0wMS0wOFQwMjoyODozOC4wMDAwMDArMDAwMCwyMDE1LTAxLTA4VDAyOjQ0OjU2LjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDksMjkuMywyMDE1LTAxLTA0LGdvb2dsZSxHZXJtYW55CjMzMCxFUVVETkdaSUNNQUs0ODIsRVFVRE5HWklDTUFLNDgyLXkzZG96d3ZzLDIwMTUtMDEtMDhUMDI6Mjg6MzguMDAwMDAwKzAwMDAsMjAxNS0wMS0wOFQwMjo0ODowMi4wMDAwMDArMDAwMCxhZCxhZF8zMHNlYywwLjkxLDI5LjMsMjAxNS0wMS0wNCxnb29nbGUsR2VybWFueQozMzEsRVFVRE5HWklDTUFLNDgyLEVRVUROR1pJQ01BSzQ4Mi15M2Rvend2cywyMDE1LTAxLTA4VDAyOjI4OjM4LjAwMDAwMCswMDAwLDIwMTUtMDEtMDhUMDI6NTU6MzguMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA2LDI5LjMsMjAxNS0wMS0wNCxnb29nbGUsR2VybWFueQozMzIsRVFVRE5HWklDTUFLNDgyLEVRVUROR1pJQ01BSzQ4Mi15M2Rvend2cywyMDE1LTAxLTA4VDAyOjI4OjM4LjAwMDAwMCswMDAwLDIwMTUtMDEtMDhUMDI6NTc6MzIuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4xOCwyOS4zLDIwMTUtMDEtMDQsZ29vZ2xlLEdlcm1hbnkKMzc3LEdTUUpYSU9LWU1FQTcxMixHU1FKWElPS1lNRUE3MTItNW00dnM5a2MsMjAxNS0wMS0wOFQyMDowODo1Mi4wMDAwMDArMDAwMCwyMDE1LTAxLTA4VDIwOjExOjI4LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMiwzMS42LDIwMTUtMDEtMDcsZ29vZ2xlLEdlcm1hbnkKMzc4LEdTUUpYSU9LWU1FQTcxMixHU1FKWElPS1lNRUE3MTItNW00dnM5a2MsMjAxNS0wMS0wOFQyMDowODo1Mi4wMDAwMDArMDAwMCwyMDE1LTAxLTA4VDIwOjExOjU4LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4xMiwzMS42LDIwMTUtMDEtMDcsZ29vZ2xlLEdlcm1hbnkKMzc5LEdTUUpYSU9LWU1FQTcxMixHU1FKWElPS1lNRUE3MTItNW00dnM5a2MsMjAxNS0wMS0wOFQyMDowODo1Mi4wMDAwMDArMDAwMCwyMDE1LTAxLTA4VDIwOjIxOjUyLjAwMDAwMCswMDAwLGFkLGFkXzIwc2VjLDAuNjksMzEuNiwyMDE1LTAxLTA3LGdvb2dsZSxHZXJtYW55CjM4MCxHU1FKWElPS1lNRUE3MTIsR1NRSlhJT0tZTUVBNzEyLTVtNHZzOWtjLDIwMTUtMDEtMDhUMjA6MDg6NTIuMDAwMDAwKzAwMDAsMjAxNS0wMS0wOFQyMDoyNjoyOC4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjIsMzEuNiwyMDE1LTAxLTA3LGdvb2dsZSxHZXJtYW55CjM4MSxHU1FKWElPS1lNRUE3MTIsR1NRSlhJT0tZTUVBNzEyLTVtNHZzOWtjLDIwMTUtMDEtMDhUMjA6MDg6NTIuMDAwMDAwKzAwMDAsMjAxNS0wMS0wOFQyMDozMTo0Ni4wMDAwMDArMDAwMCxpYXAsZ2VtczIsOC45OSwzMS42LDIwMTUtMDEtMDcsZ29vZ2xlLEdlcm1hbnkKMzgyLEdTUUpYSU9LWU1FQTcxMixHU1FKWElPS1lNRUE3MTItNW00dnM5a2MsMjAxNS0wMS0wOFQyMDowODo1Mi4wMDAwMDArMDAwMCwyMDE1LTAxLTA4VDIwOjM1OjQwLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4xMSwzMS42LDIwMTUtMDEtMDcsZ29vZ2xlLEdlcm1hbnkKMzg5LEdTUUpYSU9LWU1FQTcxMixHU1FKWElPS1lNRUE3MTItcm51MXBmYmgsMjAxNS0wMS0wOVQwMDo1MjowMS4wMDAwMDArMDAwMCwyMDE1LTAxLTA5VDAwOjUyOjQ5LjAwMDAwMCswMDAwLGlhcCxnZW1zMywyMi40OSwyMi40LDIwMTUtMDEtMDcsZ29vZ2xlLEdlcm1hbnkKMzkwLEdTUUpYSU9LWU1FQTcxMixHU1FKWElPS1lNRUE3MTItcm51MXBmYmgsMjAxNS0wMS0wOVQwMDo1MjowMS4wMDAwMDArMDAwMCwyMDE1LTAxLTA5VDAwOjU4OjEzLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4xMSwyMi40LDIwMTUtMDEtMDcsZ29vZ2xlLEdlcm1hbnkKMzkxLEdTUUpYSU9LWU1FQTcxMixHU1FKWElPS1lNRUE3MTItcm51MXBmYmgsMjAxNS0wMS0wOVQwMDo1MjowMS4wMDAwMDArMDAwMCwyMDE1LTAxLTA5VDAxOjAzOjQzLjAwMDAwMCswMDAwLGFkLGFkXzE1c2VjLDAuNDksMjIuNCwyMDE1LTAxLTA3LGdvb2dsZSxHZXJtYW55CjM5MixHU1FKWElPS1lNRUE3MTIsR1NRSlhJT0tZTUVBNzEyLXJudTFwZmJoLDIwMTUtMDEtMDlUMDA6NTI6MDEuMDAwMDAwKzAwMDAsMjAxNS0wMS0wOVQwMTowODozNy4wMDAwMDArMDAwMCxhZCxhZF9wbGF5YWJsZSwwLjk2LDIyLjQsMjAxNS0wMS0wNyxnb29nbGUsR2VybWFueQozOTUsR1NRSlhJT0tZTUVBNzEyLEdTUUpYSU9LWU1FQTcxMi15dWdmNmFkaCwyMDE1LTAxLTA5VDAxOjU4OjUyLjAwMDAwMCswMDAwLDIwMTUtMDEtMDlUMDI6MTE6NTIuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA3LDI3LjcsMjAxNS0wMS0wNyxnb29nbGUsR2VybWFueQozOTYsR1NRSlhJT0tZTUVBNzEyLEdTUUpYSU9LWU1FQTcxMi15dWdmNmFkaCwyMDE1LTAxLTA5VDAxOjU4OjUyLjAwMDAwMCswMDAwLDIwMTUtMDEtMDlUMDI6MjE6MjIuMDAwMDAwKzAwMDAsaWFwLGdvbGQyLDEuNzksMjcuNywyMDE1LTAxLTA3LGdvb2dsZSxHZXJtYW55CjM5NyxHU1FKWElPS1lNRUE3MTIsR1NRSlhJT0tZTUVBNzEyLXl1Z2Y2YWRoLDIwMTUtMDEtMDlUMDE6NTg6NTIuMDAwMDAwKzAwMDAsMjAxNS0wMS0wOVQwMjoyMjo1OC4wMDAwMDArMDAwMCxpYXAsZ29sZDIsMS43OSwyNy43LDIwMTUtMDEtMDcsZ29vZ2xlLEdlcm1hbnkKMzk4LEdTUUpYSU9LWU1FQTcxMixHU1FKWElPS1lNRUE3MTIteXVnZjZhZGgsMjAxNS0wMS0wOVQwMTo1ODo1Mi4wMDAwMDArMDAwMCwyMDE1LTAxLTA5VDAyOjIzOjU4LjAwMDAwMCswMDAwLGFkLGFkXzMwc2VjLDAuODIsMjcuNywyMDE1LTAxLTA3LGdvb2dsZSxHZXJtYW55CjQxMCxFUVVETkdaSUNNQUs0ODIsRVFVRE5HWklDTUFLNDgyLW40ZWpkZ3Z3LDIwMTUtMDEtMDlUMDc6MTE6MzUuMDAwMDAwKzAwMDAsMjAxNS0wMS0wOVQwNzoxMjo1OS4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjE5LDYuOCwyMDE1LTAxLTA0LGdvb2dsZSxHZXJtYW55CjQxNyxFUVVETkdaSUNNQUs0ODIsRVFVRE5HWklDTUFLNDgyLXVwdjNkODVoLDIwMTUtMDEtMDlUMDg6MjI6MDAuMDAwMDAwKzAwMDAsMjAxNS0wMS0wOVQwODoyNjo1NC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDIsMzguOSwyMDE1LTAxLTA0LGdvb2dsZSxHZXJtYW55CjQxOCxFUVVETkdaSUNNQUs0ODIsRVFVRE5HWklDTUFLNDgyLXVwdjNkODVoLDIwMTUtMDEtMDlUMDg6MjI6MDAuMDAwMDAwKzAwMDAsMjAxNS0wMS0wOVQwODoyOTo0Mi4wMDAwMDArMDAwMCxhZCxhZF9zdXJ2ZXksMC44NywzOC45LDIwMTUtMDEtMDQsZ29vZ2xlLEdlcm1hbnkKNDIzLE1QVVhEWUJKVFpDRjQ4NixNUFVYRFlCSlRaQ0Y0ODYtd2R2bGszOGEsMjAxNS0wMS0wOVQxMjowMjo0OC4wMDAwMDArMDAwMCwyMDE1LTAxLTA5VDEyOjA5OjEyLjAwMDAwMCswMDAwLGFkLGFkX3N1cnZleSwwLjc4LDE1LjIsMjAxNS0wMS0wOSxvcmdhbmljLEdlcm1hbnkKNDI0LE1QVVhEWUJKVFpDRjQ4NixNUFVYRFlCSlRaQ0Y0ODYtd2R2bGszOGEsMjAxNS0wMS0wOVQxMjowMjo0OC4wMDAwMDArMDAwMCwyMDE1LTAxLTA5VDEyOjExOjA2LjAwMDAwMCswMDAwLGFkLGFkXzE1c2VjLDAuMjIsMTUuMiwyMDE1LTAxLTA5LG9yZ2FuaWMsR2VybWFueQo0MjUsTVBVWERZQkpUWkNGNDg2LE1QVVhEWUJKVFpDRjQ4Ni13ZHZsazM4YSwyMDE1LTAxLTA5VDEyOjAyOjQ4LjAwMDAwMCswMDAwLDIwMTUtMDEtMDlUMTI6MTc6MDAuMDAwMDAwKzAwMDAsYWQsYWRfMTVzZWMsMC4yMjgsMTUuMiwyMDE1LTAxLTA5LG9yZ2FuaWMsR2VybWFueQo0NTMsRVFVRE5HWklDTUFLNDgyLEVRVUROR1pJQ01BSzQ4Mi12bmw5cDh3eiwyMDE1LTAxLTA5VDIxOjIzOjAxLjAwMDAwMCswMDAwLDIwMTUtMDEtMDlUMjE6MzM6MzcuMDAwMDAwKzAwMDAsaWFwLG9mZmVyMywxMy40OSwzMy45LDIwMTUtMDEtMDQsZ29vZ2xlLEdlcm1hbnkKNDU0LEVRVUROR1pJQ01BSzQ4MixFUVVETkdaSUNNQUs0ODItdm5sOXA4d3osMjAxNS0wMS0wOVQyMToyMzowMS4wMDAwMDArMDAwMCwyMDE1LTAxLTA5VDIxOjM0OjAxLjAwMDAwMCswMDAwLGFkLGFkXzIwc2VjLDAuNjEsMzMuOSwyMDE1LTAxLTA0LGdvb2dsZSxHZXJtYW55CjQ1NSxFUVVETkdaSUNNQUs0ODIsRVFVRE5HWklDTUFLNDgyLXZubDlwOHd6LDIwMTUtMDEtMDlUMjE6MjM6MDEuMDAwMDAwKzAwMDAsMjAxNS0wMS0wOVQyMTozNTowMS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMTIsMzMuOSwyMDE1LTAxLTA0LGdvb2dsZSxHZXJtYW55CjQ1NixFUVVETkdaSUNNQUs0ODIsRVFVRE5HWklDTUFLNDgyLXZubDlwOHd6LDIwMTUtMDEtMDlUMjE6MjM6MDEuMDAwMDAwKzAwMDAsMjAxNS0wMS0wOVQyMTozNzozMS4wMDAwMDArMDAwMCxhZCxhZF9zdXJ2ZXksMC41NiwzMy45LDIwMTUtMDEtMDQsZ29vZ2xlLEdlcm1hbnkKNDU3LEVRVUROR1pJQ01BSzQ4MixFUVVETkdaSUNNQUs0ODItdm5sOXA4d3osMjAxNS0wMS0wOVQyMToyMzowMS4wMDAwMDArMDAwMCwyMDE1LTAxLTA5VDIxOjQyOjE5LjAwMDAwMCswMDAwLGFkLGFkXzIwc2VjLDAuNjQ5LDMzLjksMjAxNS0wMS0wNCxnb29nbGUsR2VybWFueQo0NTgsRVFVRE5HWklDTUFLNDgyLEVRVUROR1pJQ01BSzQ4Mi12bmw5cDh3eiwyMDE1LTAxLTA5VDIxOjIzOjAxLjAwMDAwMCswMDAwLDIwMTUtMDEtMDlUMjE6NTU6MTkuMDAwMDAwKzAwMDAsYWQsYWRfcGxheWFibGUsMC43MSwzMy45LDIwMTUtMDEtMDQsZ29vZ2xlLEdlcm1hbnkKNDY5LEdTUUpYSU9LWU1FQTcxMixHU1FKWElPS1lNRUE3MTItM3hxN3dnMWwsMjAxNS0wMS0xMFQwMDo1NzozMS4wMDAwMDArMDAwMCwyMDE1LTAxLTEwVDAwOjU5OjA3LjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMDgsMzkuOCwyMDE1LTAxLTA3LGdvb2dsZSxHZXJtYW55CjQ3MCxHU1FKWElPS1lNRUE3MTIsR1NRSlhJT0tZTUVBNzEyLTN4cTd3ZzFsLDIwMTUtMDEtMTBUMDA6NTc6MzEuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMFQwMTowNzoxMy4wMDAwMDArMDAwMCxpYXAsb2ZmZXIyLDguOTksMzkuOCwyMDE1LTAxLTA3LGdvb2dsZSxHZXJtYW55CjQ3MSxHU1FKWElPS1lNRUE3MTIsR1NRSlhJT0tZTUVBNzEyLTN4cTd3ZzFsLDIwMTUtMDEtMTBUMDA6NTc6MzEuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMFQwMToyODozNy4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjA4LDM5LjgsMjAxNS0wMS0wNyxnb29nbGUsR2VybWFueQo1MjUsRVFVRE5HWklDTUFLNDgyLEVRVUROR1pJQ01BSzQ4Mi1pNWtyZzluZiwyMDE1LTAxLTEwVDE0OjEyOjA5LjAwMDAwMCswMDAwLDIwMTUtMDEtMTBUMTQ6MTk6MzkuMDAwMDAwKzAwMDAsaWFwLG9mZmVyMywxMy40OTEsMTAuNiwyMDE1LTAxLTA0LGdvb2dsZSxHZXJtYW55CjUyNixFUVVETkdaSUNNQUs0ODIsRVFVRE5HWklDTUFLNDgyLWk1a3JnOW5mLDIwMTUtMDEtMTBUMTQ6MTI6MDkuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMFQxNDoyMDowOS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDMsMTAuNiwyMDE1LTAxLTA0LGdvb2dsZSxHZXJtYW55CjU5MyxHU1FKWElPS1lNRUE3MTIsR1NRSlhJT0tZTUVBNzEyLWk1N3Y0ZmJ4LDIwMTUtMDEtMTFUMDM6MDg6NDYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMVQwMzoxMzoyMi4wMDAwMDArMDAwMCxpYXAsZ2VtczEsMi4yNCwxMC44LDIwMTUtMDEtMDcsZ29vZ2xlLEdlcm1hbnkKNTk0LEdTUUpYSU9LWU1FQTcxMixHU1FKWElPS1lNRUE3MTItaTU3djRmYngsMjAxNS0wMS0xMVQwMzowODo0Ni4wMDAwMDArMDAwMCwyMDE1LTAxLTExVDAzOjE2OjA0LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4xMSwxMC44LDIwMTUtMDEtMDcsZ29vZ2xlLEdlcm1hbnkKNTk1LEdTUUpYSU9LWU1FQTcxMixHU1FKWElPS1lNRUE3MTItaTU3djRmYngsMjAxNS0wMS0xMVQwMzowODo0Ni4wMDAwMDArMDAwMCwyMDE1LTAxLTExVDAzOjE3OjIyLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wOCwxMC44LDIwMTUtMDEtMDcsZ29vZ2xlLEdlcm1hbnkKNjAwLEdTUUpYSU9LWU1FQTcxMixHU1FKWElPS1lNRUE3MTItbHlrYXN4bzcsMjAxNS0wMS0xMVQwNToxNjo0Ni4wMDAwMDArMDAwMCwyMDE1LTAxLTExVDA1OjE2OjUyLjAwMDAwMCswMDAwLGFkLGFkXzIwc2VjLDEuMSwyMC4xLDIwMTUtMDEtMDcsZ29vZ2xlLEdlcm1hbnkKNjAxLEdTUUpYSU9LWU1FQTcxMixHU1FKWElPS1lNRUE3MTItbHlrYXN4bzcsMjAxNS0wMS0xMVQwNToxNjo0Ni4wMDAwMDArMDAwMCwyMDE1LTAxLTExVDA1OjE3OjM0LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNSwyMC4xLDIwMTUtMDEtMDcsZ29vZ2xlLEdlcm1hbnkKNjAyLEdTUUpYSU9LWU1FQTcxMixHU1FKWElPS1lNRUE3MTItbHlrYXN4bzcsMjAxNS0wMS0xMVQwNToxNjo0Ni4wMDAwMDArMDAwMCwyMDE1LTAxLTExVDA1OjI0OjQwLjAwMDAwMCswMDAwLGFkLGFkX3BsYXlhYmxlLDAuNzUsMjAuMSwyMDE1LTAxLTA3LGdvb2dsZSxHZXJtYW55CjYwMyxHU1FKWElPS1lNRUE3MTIsR1NRSlhJT0tZTUVBNzEyLWx5a2FzeG83LDIwMTUtMDEtMTFUMDU6MTY6NDYuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMVQwNToyNTo1OC4wMDAwMDArMDAwMCxhZCxhZF9zdXJ2ZXksMC44OCwyMC4xLDIwMTUtMDEtMDcsZ29vZ2xlLEdlcm1hbnkKNjQ5LEdTUUpYSU9LWU1FQTcxMixHU1FKWElPS1lNRUE3MTItdm1sZmpic2MsMjAxNS0wMS0xMVQxNDoxMjoxOC4wMDAwMDArMDAwMCwyMDE1LTAxLTExVDE0OjI1OjA2LjAwMDAwMCswMDAwLGFkLGFkXzE1c2VjLDAuMjUsMzEuNCwyMDE1LTAxLTA3LGdvb2dsZSxHZXJtYW55CjY1MCxHU1FKWElPS1lNRUE3MTIsR1NRSlhJT0tZTUVBNzEyLXZtbGZqYnNjLDIwMTUtMDEtMTFUMTQ6MTI6MTguMDAwMDAwKzAwMDAsMjAxNS0wMS0xMVQxNDozMDowMC4wMDAwMDArMDAwMCxhZCxhZF8xNXNlYywwLjE5LDMxLjQsMjAxNS0wMS0wNyxnb29nbGUsR2VybWFueQo2NTEsR1NRSlhJT0tZTUVBNzEyLEdTUUpYSU9LWU1FQTcxMi12bWxmamJzYywyMDE1LTAxLTExVDE0OjEyOjE4LjAwMDAwMCswMDAwLDIwMTUtMDEtMTFUMTQ6MzM6NDguMDAwMDAwKzAwMDAsaWFwLG9mZmVyMSw0LjQ5LDMxLjQsMjAxNS0wMS0wNyxnb29nbGUsR2VybWFueQo2NTIsR1NRSlhJT0tZTUVBNzEyLEdTUUpYSU9LWU1FQTcxMi12bWxmamJzYywyMDE1LTAxLTExVDE0OjEyOjE4LjAwMDAwMCswMDAwLDIwMTUtMDEtMTFUMTQ6Mzk6MjQuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4xMywzMS40LDIwMTUtMDEtMDcsZ29vZ2xlLEdlcm1hbnkKNjUzLEdTUUpYSU9LWU1FQTcxMixHU1FKWElPS1lNRUE3MTItdm1sZmpic2MsMjAxNS0wMS0xMVQxNDoxMjoxOC4wMDAwMDArMDAwMCwyMDE1LTAxLTExVDE0OjQxOjM2LjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMTUsMzEuNCwyMDE1LTAxLTA3LGdvb2dsZSxHZXJtYW55CjY2NCxFUVVETkdaSUNNQUs0ODIsRVFVRE5HWklDTUFLNDgyLWt3eWk0ZHN2LDIwMTUtMDEtMTFUMTY6MzE6NTAuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMVQxNjozNDoyNi4wMDAwMDArMDAwMCxpYXAsb2ZmZXI0LDE3Ljk5LDIxLjIsMjAxNS0wMS0wNCxnb29nbGUsR2VybWFueQo2NjUsRVFVRE5HWklDTUFLNDgyLEVRVUROR1pJQ01BSzQ4Mi1rd3lpNGRzdiwyMDE1LTAxLTExVDE2OjMxOjUwLjAwMDAwMCswMDAwLDIwMTUtMDEtMTFUMTY6Mzg6NTYuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4yMywyMS4yLDIwMTUtMDEtMDQsZ29vZ2xlLEdlcm1hbnkKNjY2LEVRVUROR1pJQ01BSzQ4MixFUVVETkdaSUNNQUs0ODIta3d5aTRkc3YsMjAxNS0wMS0xMVQxNjozMTo1MC4wMDAwMDArMDAwMCwyMDE1LTAxLTExVDE2OjQwOjU2LjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMTIsMjEuMiwyMDE1LTAxLTA0LGdvb2dsZSxHZXJtYW55CjY2NyxFUVVETkdaSUNNQUs0ODIsRVFVRE5HWklDTUFLNDgyLWt3eWk0ZHN2LDIwMTUtMDEtMTFUMTY6MzE6NTAuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMVQxNjo0NDoyMC4wMDAwMDArMDAwMCxhZCxhZF9zdXJ2ZXksMC44NSwyMS4yLDIwMTUtMDEtMDQsZ29vZ2xlLEdlcm1hbnkKNjY4LEVRVUROR1pJQ01BSzQ4MixFUVVETkdaSUNNQUs0ODIta3d5aTRkc3YsMjAxNS0wMS0xMVQxNjozMTo1MC4wMDAwMDArMDAwMCwyMDE1LTAxLTExVDE2OjQ5OjI2LjAwMDAwMCswMDAwLGlhcCxnb2xkMyw0LjQ5LDIxLjIsMjAxNS0wMS0wNCxnb29nbGUsR2VybWFueQo2OTUsRVFVRE5HWklDTUFLNDgyLEVRVUROR1pJQ01BSzQ4Mi1oeGoxdzY0YiwyMDE1LTAxLTExVDIyOjU4OjE3LjAwMDAwMCswMDAwLDIwMTUtMDEtMTFUMjM6MDk6NTMuMDAwMDAwKzAwMDAsYWQsYWRfMTVzZWMsMC4yNSwxOS40LDIwMTUtMDEtMDQsZ29vZ2xlLEdlcm1hbnkKNjk2LEVRVUROR1pJQ01BSzQ4MixFUVVETkdaSUNNQUs0ODItaHhqMXc2NGIsMjAxNS0wMS0xMVQyMjo1ODoxNy4wMDAwMDArMDAwMCwyMDE1LTAxLTExVDIzOjEwOjE3LjAwMDAwMCswMDAwLGlhcCxnb2xkMiwxLjc5LDE5LjQsMjAxNS0wMS0wNCxnb29nbGUsR2VybWFueQo2OTcsRVFVRE5HWklDTUFLNDgyLEVRVUROR1pJQ01BSzQ4Mi1oeGoxdzY0YiwyMDE1LTAxLTExVDIyOjU4OjE3LjAwMDAwMCswMDAwLDIwMTUtMDEtMTFUMjM6MTI6MjMuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4wNywxOS40LDIwMTUtMDEtMDQsZ29vZ2xlLEdlcm1hbnkKNjk5LEdTUUpYSU9LWU1FQTcxMixHU1FKWElPS1lNRUE3MTItMnF4bnRzd2MsMjAxNS0wMS0xMlQwMDoyNToxMy4wMDAwMDArMDAwMCwyMDE1LTAxLTEyVDAwOjI1OjMxLjAwMDAwMCswMDAwLGFkLGFkXzE1c2VjLDAuNCwzMy4zLDIwMTUtMDEtMDcsZ29vZ2xlLEdlcm1hbnkKNzAwLEdTUUpYSU9LWU1FQTcxMixHU1FKWElPS1lNRUE3MTItMnF4bnRzd2MsMjAxNS0wMS0xMlQwMDoyNToxMy4wMDAwMDArMDAwMCwyMDE1LTAxLTEyVDAwOjQ2OjU1LjAwMDAwMCswMDAwLGlhcCxvZmZlcjEsNC40OSwzMy4zLDIwMTUtMDEtMDcsZ29vZ2xlLEdlcm1hbnkKNzAxLEdTUUpYSU9LWU1FQTcxMixHU1FKWElPS1lNRUE3MTItMnF4bnRzd2MsMjAxNS0wMS0xMlQwMDoyNToxMy4wMDAwMDArMDAwMCwyMDE1LTAxLTEyVDAwOjQ2OjU1LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNSwzMy4zLDIwMTUtMDEtMDcsZ29vZ2xlLEdlcm1hbnkKNzQ4LEVRVUROR1pJQ01BSzQ4MixFUVVETkdaSUNNQUs0ODItd3JkN3FzbWIsMjAxNS0wMS0xMlQxMDowNTo1OC4wMDAwMDArMDAwMCwyMDE1LTAxLTEyVDEwOjI0OjEwLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4xMSwyMy4yLDIwMTUtMDEtMDQsZ29vZ2xlLEdlcm1hbnkKNzU2LEdTUUpYSU9LWU1FQTcxMixHU1FKWElPS1lNRUE3MTItOWkycms2YWMsMjAxNS0wMS0xMlQxMzozOTowMC4wMDAwMDArMDAwMCwyMDE1LTAxLTEyVDEzOjQxOjE4LjAwMDAwMCswMDAwLGlhcCxvZmZlcjQsMTcuOTkxLDE1LjEsMjAxNS0wMS0wNyxnb29nbGUsR2VybWFueQo3NTcsR1NRSlhJT0tZTUVBNzEyLEdTUUpYSU9LWU1FQTcxMi05aTJyazZhYywyMDE1LTAxLTEyVDEzOjM5OjAwLjAwMDAwMCswMDAwLDIwMTUtMDEtMTJUMTM6NDI6NTQuMDAwMDAwKzAwMDAsaWFwLGdvbGQ0LDE3Ljk5MSwxNS4xLDIwMTUtMDEtMDcsZ29vZ2xlLEdlcm1hbnkKNzU4LEdTUUpYSU9LWU1FQTcxMixHU1FKWElPS1lNRUE3MTItOWkycms2YWMsMjAxNS0wMS0xMlQxMzozOTowMC4wMDAwMDArMDAwMCwyMDE1LTAxLTEyVDEzOjQ1OjMwLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wNSwxNS4xLDIwMTUtMDEtMDcsZ29vZ2xlLEdlcm1hbnkKNzYxLEVRVUROR1pJQ01BSzQ4MixFUVVETkdaSUNNQUs0ODItYXplaW91cTIsMjAxNS0wMS0xMlQxNToyMToyNy4wMDAwMDArMDAwMCwyMDE1LTAxLTEyVDE1OjM0OjA5LjAwMDAwMCswMDAwLGFkLGFkXzMwc2VjLDAuODMsMzguNSwyMDE1LTAxLTA0LGdvb2dsZSxHZXJtYW55Cjc2MixFUVVETkdaSUNNQUs0ODIsRVFVRE5HWklDTUFLNDgyLWF6ZWlvdXEyLDIwMTUtMDEtMTJUMTU6MjE6MjcuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMlQxNTozNzowOS4wMDAwMDArMDAwMCxhZCxhZF8xNXNlYywwLjM3LDM4LjUsMjAxNS0wMS0wNCxnb29nbGUsR2VybWFueQo3NjMsR1NRSlhJT0tZTUVBNzEyLEdTUUpYSU9LWU1FQTcxMi03dzJiNWt5diwyMDE1LTAxLTEyVDE2OjI0OjA5LjAwMDAwMCswMDAwLDIwMTUtMDEtMTJUMTY6MzA6NTEuMDAwMDAwKzAwMDAsYWQsYWRfc3VydmV5LDAuNjksMTIuOSwyMDE1LTAxLTA3LGdvb2dsZSxHZXJtYW55Cjc2NCxHU1FKWElPS1lNRUE3MTIsR1NRSlhJT0tZTUVBNzEyLTd3MmI1a3l2LDIwMTUtMDEtMTJUMTY6MjQ6MDkuMDAwMDAwKzAwMDAsMjAxNS0wMS0xMlQxNjozMzowOS4wMDAwMDArMDAwMCxhZCxhZF8xNXNlYywwLjQ1LDEyLjksMjAxNS0wMS0wNyxnb29nbGUsR2VybWFueQo4OTcsR1NRSlhJT0tZTUVBNzEyLEdTUUpYSU9LWU1FQTcxMi0zcTgydmtnOSwyMDE1LTAxLTEzVDE5OjE2OjUxLjAwMDAwMCswMDAwLDIwMTUtMDEtMTNUMTk6Mjc6MDkuMDAwMDAwKzAwMDAsYWQsYWRfMzBzZWMsMC43NCwzNC4wLDIwMTUtMDEtMDcsZ29vZ2xlLEdlcm1hbnkKODk4LEdTUUpYSU9LWU1FQTcxMixHU1FKWElPS1lNRUE3MTItM3E4MnZrZzksMjAxNS0wMS0xM1QxOToxNjo1MS4wMDAwMDArMDAwMCwyMDE1LTAxLTEzVDE5OjI3OjI3LjAwMDAwMCswMDAwLGFkLGFkXzE1c2VjLDAuNTcsMzQuMCwyMDE1LTAxLTA3LGdvb2dsZSxHZXJtYW55Cjg5OSxHU1FKWElPS1lNRUE3MTIsR1NRSlhJT0tZTUVBNzEyLTNxODJ2a2c5LDIwMTUtMDEtMTNUMTk6MTY6NTEuMDAwMDAwKzAwMDAsMjAxNS0wMS0xM1QxOTo0MToxNS4wMDAwMDArMDAwMCxhZCxhZF8yMHNlYywwLjY1LDM0LjAsMjAxNS0wMS0wNyxnb29nbGUsR2VybWFueQo5MDAsR1NRSlhJT0tZTUVBNzEyLEdTUUpYSU9LWU1FQTcxMi0zcTgydmtnOSwyMDE1LTAxLTEzVDE5OjE2OjUxLjAwMDAwMCswMDAwLDIwMTUtMDEtMTNUMTk6NDc6MzMuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA2LDM0LjAsMjAxNS0wMS0wNyxnb29nbGUsR2VybWFueQo5MDEsR1NRSlhJT0tZTUVBNzEyLEdTUUpYSU9LWU1FQTcxMi10OThhYzdvdSwyMDE1LTAxLTEzVDIwOjM1OjQ5LjAwMDAwMCswMDAwLDIwMTUtMDEtMTNUMjA6MzY6MjUuMDAwMDAwKzAwMDAsYWQsYWRfc3VydmV5LDEuMTksMTIuMiwyMDE1LTAxLTA3LGdvb2dsZSxHZXJtYW55CjkwMixHU1FKWElPS1lNRUE3MTIsR1NRSlhJT0tZTUVBNzEyLXQ5OGFjN291LDIwMTUtMDEtMTNUMjA6MzU6NDkuMDAwMDAwKzAwMDAsMjAxNS0wMS0xM1QyMDozODowMS4wMDAwMDArMDAwMCxhZCxhZF8xNXNlYywwLjM0OTcsMTIuMiwyMDE1LTAxLTA3LGdvb2dsZSxHZXJtYW55CjkwMyxHU1FKWElPS1lNRUE3MTIsR1NRSlhJT0tZTUVBNzEyLXQ5OGFjN291LDIwMTUtMDEtMTNUMjA6MzU6NDkuMDAwMDAwKzAwMDAsMjAxNS0wMS0xM1QyMDo0NjowMS4wMDAwMDArMDAwMCxpYXAsb2ZmZXI1LDI2LjA5LDEyLjIsMjAxNS0wMS0wNyxnb29nbGUsR2VybWFueQo5MjcsR1NRSlhJT0tZTUVBNzEyLEdTUUpYSU9LWU1FQTcxMi04ZjUxNGtkYywyMDE1LTAxLTE0VDAwOjU5OjEwLjAwMDAwMCswMDAwLDIwMTUtMDEtMTRUMDA6NTk6NDAuMDAwMDAwKzAwMDAsaWFwLGdlbXMxLDIuMjQsOC40LDIwMTUtMDEtMDcsZ29vZ2xlLEdlcm1hbnkKOTI4LEdTUUpYSU9LWU1FQTcxMixHU1FKWElPS1lNRUE3MTItOGY1MTRrZGMsMjAxNS0wMS0xNFQwMDo1OToxMC4wMDAwMDArMDAwMCwyMDE1LTAxLTE0VDAxOjAwOjA0LjAwMDAwMCswMDAwLGFkLGFkXzMwc2VjLDEuMTgsOC40LDIwMTUtMDEtMDcsZ29vZ2xlLEdlcm1hbnkKOTQxLE1UQ0lXS09WQVNZUDkyNSxNVENJV0tPVkFTWVA5MjUtNHpxdWs1ZnIsMjAxNS0wMS0xNFQwMjo0NToyMC4wMDAwMDArMDAwMCwyMDE1LTAxLTE0VDAyOjQ4OjI2LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4xMSwxMS41LDIwMTUtMDEtMTQsb3JnYW5pYyxHZXJtYW55Cjk0MixNVENJV0tPVkFTWVA5MjUsTVRDSVdLT1ZBU1lQOTI1LTR6cXVrNWZyLDIwMTUtMDEtMTRUMDI6NDU6MjAuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNFQwMjo1MzoyNi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDIsMTEuNSwyMDE1LTAxLTE0LG9yZ2FuaWMsR2VybWFueQo5NDMsTVRDSVdLT1ZBU1lQOTI1LE1UQ0lXS09WQVNZUDkyNS00enF1azVmciwyMDE1LTAxLTE0VDAyOjQ1OjIwLjAwMDAwMCswMDAwLDIwMTUtMDEtMTRUMDI6NTY6NTAuMDAwMDAwKzAwMDAsaWFwLGdvbGQyLDEuNzksMTEuNSwyMDE1LTAxLTE0LG9yZ2FuaWMsR2VybWFueQo5ODIsR1NRSlhJT0tZTUVBNzEyLEdTUUpYSU9LWU1FQTcxMi1vYXliMzZkYywyMDE1LTAxLTE0VDA3OjQzOjM4LjAwMDAwMCswMDAwLDIwMTUtMDEtMTRUMDc6NDU6MjYuMDAwMDAwKzAwMDAsYWQsYWRfMTVzZWMsMC4yNiwyMy40LDIwMTUtMDEtMDcsZ29vZ2xlLEdlcm1hbnkKOTgzLEdTUUpYSU9LWU1FQTcxMixHU1FKWElPS1lNRUE3MTItb2F5YjM2ZGMsMjAxNS0wMS0xNFQwNzo0MzozOC4wMDAwMDArMDAwMCwyMDE1LTAxLTE0VDA3OjU3OjE0LjAwMDAwMCswMDAwLGFkLGFkX3N1cnZleSwwLjcsMjMuNCwyMDE1LTAxLTA3LGdvb2dsZSxHZXJtYW55CjEwMDIsTVRDSVdLT1ZBU1lQOTI1LE1UQ0lXS09WQVNZUDkyNS04YTZ4ZnFvaywyMDE1LTAxLTE0VDEwOjE4OjMyLjAwMDAwMCswMDAwLDIwMTUtMDEtMTRUMTA6MjM6MjYuMDAwMDAwKzAwMDAsaWFwLG9mZmVyNCwxNy45OSwxNi4zLDIwMTUtMDEtMTQsb3JnYW5pYyxHZXJtYW55CjEwMDMsTVRDSVdLT1ZBU1lQOTI1LE1UQ0lXS09WQVNZUDkyNS04YTZ4ZnFvaywyMDE1LTAxLTE0VDEwOjE4OjMyLjAwMDAwMCswMDAwLDIwMTUtMDEtMTRUMTA6Mjc6MjYuMDAwMDAwKzAwMDAsYWQsYWRfMTVzZWMsMC4yOSwxNi4zLDIwMTUtMDEtMTQsb3JnYW5pYyxHZXJtYW55CjEwMDQsTVRDSVdLT1ZBU1lQOTI1LE1UQ0lXS09WQVNZUDkyNS04YTZ4ZnFvaywyMDE1LTAxLTE0VDEwOjE4OjMyLjAwMDAwMCswMDAwLDIwMTUtMDEtMTRUMTA6Mjk6NTYuMDAwMDAwKzAwMDAsYWQsYWRfcGxheWFibGUsMC42NiwxNi4zLDIwMTUtMDEtMTQsb3JnYW5pYyxHZXJtYW55CjEwMDUsTVRDSVdLT1ZBU1lQOTI1LE1UQ0lXS09WQVNZUDkyNS04YTZ4ZnFvaywyMDE1LTAxLTE0VDEwOjE4OjMyLjAwMDAwMCswMDAwLDIwMTUtMDEtMTRUMTA6MzE6MjAuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA0LDE2LjMsMjAxNS0wMS0xNCxvcmdhbmljLEdlcm1hbnkKMTAwNixNVENJV0tPVkFTWVA5MjUsTVRDSVdLT1ZBU1lQOTI1LThhNnhmcW9rLDIwMTUtMDEtMTRUMTA6MTg6MzIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNFQxMDozMjowOC4wMDAwMDArMDAwMCxpYXAsb2ZmZXIyLDguOTksMTYuMywyMDE1LTAxLTE0LG9yZ2FuaWMsR2VybWFueQoxMDc5LE1UQ0lXS09WQVNZUDkyNSxNVENJV0tPVkFTWVA5MjUtOWU2YXNsaDIsMjAxNS0wMS0xNVQwMjoxNToxMS4wMDAwMDArMDAwMCwyMDE1LTAxLTE1VDAyOjE3OjE3LjAwMDAwMCswMDAwLGFkLGFkXzIwc2VjLDAuMzUsMzUuMywyMDE1LTAxLTE0LG9yZ2FuaWMsR2VybWFueQoxMDgwLE1UQ0lXS09WQVNZUDkyNSxNVENJV0tPVkFTWVA5MjUtOWU2YXNsaDIsMjAxNS0wMS0xNVQwMjoxNToxMS4wMDAwMDArMDAwMCwyMDE1LTAxLTE1VDAyOjI2OjQxLjAwMDAwMCswMDAwLGlhcCxnb2xkMyw0LjQ5LDM1LjMsMjAxNS0wMS0xNCxvcmdhbmljLEdlcm1hbnkKMTA4MSxNVENJV0tPVkFTWVA5MjUsTVRDSVdLT1ZBU1lQOTI1LTllNmFzbGgyLDIwMTUtMDEtMTVUMDI6MTU6MTEuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNVQwMjozMToxNy4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDMsMzUuMywyMDE1LTAxLTE0LG9yZ2FuaWMsR2VybWFueQoxMDgyLE1UQ0lXS09WQVNZUDkyNSxNVENJV0tPVkFTWVA5MjUtOWU2YXNsaDIsMjAxNS0wMS0xNVQwMjoxNToxMS4wMDAwMDArMDAwMCwyMDE1LTAxLTE1VDAyOjMyOjExLjAwMDAwMCswMDAwLGlhcCxnZW1zMiw4Ljk5LDM1LjMsMjAxNS0wMS0xNCxvcmdhbmljLEdlcm1hbnkKMTA4MyxNVENJV0tPVkFTWVA5MjUsTVRDSVdLT1ZBU1lQOTI1LTllNmFzbGgyLDIwMTUtMDEtMTVUMDI6MTU6MTEuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNVQwMjozMjo1OS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDYsMzUuMywyMDE1LTAxLTE0LG9yZ2FuaWMsR2VybWFueQoxMDg0LE1UQ0lXS09WQVNZUDkyNSxNVENJV0tPVkFTWVA5MjUtOWU2YXNsaDIsMjAxNS0wMS0xNVQwMjoxNToxMS4wMDAwMDArMDAwMCwyMDE1LTAxLTE1VDAyOjQ0OjU5LjAwMDAwMCswMDAwLGFkLGFkXzE1c2VjLDAuNDQsMzUuMywyMDE1LTAxLTE0LG9yZ2FuaWMsR2VybWFueQoxMTMzLEdTUUpYSU9LWU1FQTcxMixHU1FKWElPS1lNRUE3MTItczdrZTVicjgsMjAxNS0wMS0xNVQwOToyMjozOS4wMDAwMDArMDAwMCwyMDE1LTAxLTE1VDA5OjMxOjE1LjAwMDAwMCswMDAwLGFkLGFkX3N1cnZleSwxLjI0LDE2LjMsMjAxNS0wMS0wNyxnb29nbGUsR2VybWFueQoxMTM0LEdTUUpYSU9LWU1FQTcxMixHU1FKWElPS1lNRUE3MTItczdrZTVicjgsMjAxNS0wMS0xNVQwOToyMjozOS4wMDAwMDArMDAwMCwyMDE1LTAxLTE1VDA5OjM1OjE1LjAwMDAwMCswMDAwLGFkLGFkXzE1c2VjLDAuNTUsMTYuMywyMDE1LTAxLTA3LGdvb2dsZSxHZXJtYW55CjExODQsTVRDSVdLT1ZBU1lQOTI1LE1UQ0lXS09WQVNZUDkyNS15c3BkaWtxaiwyMDE1LTAxLTE1VDE3OjA2OjMzLjAwMDAwMCswMDAwLDIwMTUtMDEtMTVUMTc6MDg6MjcuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA1LDMxLjAsMjAxNS0wMS0xNCxvcmdhbmljLEdlcm1hbnkKMTE4NSxNVENJV0tPVkFTWVA5MjUsTVRDSVdLT1ZBU1lQOTI1LXlzcGRpa3FqLDIwMTUtMDEtMTVUMTc6MDY6MzMuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNVQxNzowOTo1MS4wMDAwMDArMDAwMCxpYXAsb2ZmZXI0LDE3Ljk5LDMxLjAsMjAxNS0wMS0xNCxvcmdhbmljLEdlcm1hbnkKMTE4NixNVENJV0tPVkFTWVA5MjUsTVRDSVdLT1ZBU1lQOTI1LXlzcGRpa3FqLDIwMTUtMDEtMTVUMTc6MDY6MzMuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNVQxNzoxMToyMS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDQsMzEuMCwyMDE1LTAxLTE0LG9yZ2FuaWMsR2VybWFueQoxMTg3LE1UQ0lXS09WQVNZUDkyNSxNVENJV0tPVkFTWVA5MjUteXNwZGlrcWosMjAxNS0wMS0xNVQxNzowNjozMy4wMDAwMDArMDAwMCwyMDE1LTAxLTE1VDE3OjIzOjUxLjAwMDAwMCswMDAwLGlhcCxvZmZlcjQsMTcuOTksMzEuMCwyMDE1LTAxLTE0LG9yZ2FuaWMsR2VybWFueQoxMjA1LEdTUUpYSU9LWU1FQTcxMixHU1FKWElPS1lNRUE3MTItd21kZjQ5b3gsMjAxNS0wMS0xNVQyMzoxMTo1NS4wMDAwMDArMDAwMCwyMDE1LTAxLTE1VDIzOjE1OjEzLjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMTQsMjAuNywyMDE1LTAxLTA3LGdvb2dsZSxHZXJtYW55CjEyMDYsR1NRSlhJT0tZTUVBNzEyLEdTUUpYSU9LWU1FQTcxMi13bWRmNDlveCwyMDE1LTAxLTE1VDIzOjExOjU1LjAwMDAwMCswMDAwLDIwMTUtMDEtMTVUMjM6MTU6MzEuMDAwMDAwKzAwMDAsYWQsYWRfc3VydmV5LDAuNTcsMjAuNywyMDE1LTAxLTA3LGdvb2dsZSxHZXJtYW55CjEyMDcsR1NRSlhJT0tZTUVBNzEyLEdTUUpYSU9LWU1FQTcxMi13bWRmNDlveCwyMDE1LTAxLTE1VDIzOjExOjU1LjAwMDAwMCswMDAwLDIwMTUtMDEtMTVUMjM6Mjk6NDMuMDAwMDAwKzAwMDAsYWQsYWRfMTVzZWMsMC4zNDk3LDIwLjcsMjAxNS0wMS0wNyxnb29nbGUsR2VybWFueQoxMjA4LEdTUUpYSU9LWU1FQTcxMixHU1FKWElPS1lNRUE3MTItd21kZjQ5b3gsMjAxNS0wMS0xNVQyMzoxMTo1NS4wMDAwMDArMDAwMCwyMDE1LTAxLTE1VDIzOjMwOjE5LjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMjIsMjAuNywyMDE1LTAxLTA3LGdvb2dsZSxHZXJtYW55CjEyNDUsVVBGTUxJRUtXSFlYOTY0LFVQRk1MSUVLV0hZWDk2NC14cm9nbWRiaywyMDE1LTAxLTE2VDA4OjAzOjM5LjAwMDAwMCswMDAwLDIwMTUtMDEtMTZUMDg6MDg6MjcuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjEsMzMuNCwyMDE1LTAxLTE2LG9yZ2FuaWMsR2VybWFueQoxMjQ2LFVQRk1MSUVLV0hZWDk2NCxVUEZNTElFS1dIWVg5NjQteHJvZ21kYmssMjAxNS0wMS0xNlQwODowMzozOS4wMDAwMDArMDAwMCwyMDE1LTAxLTE2VDA4OjEzOjU3LjAwMDAwMCswMDAwLGlhcCxvZmZlcjEsNC40OSwzMy40LDIwMTUtMDEtMTYsb3JnYW5pYyxHZXJtYW55CjEyNDcsVVBGTUxJRUtXSFlYOTY0LFVQRk1MSUVLV0hZWDk2NC14cm9nbWRiaywyMDE1LTAxLTE2VDA4OjAzOjM5LjAwMDAwMCswMDAwLDIwMTUtMDEtMTZUMDg6MTk6MDkuMDAwMDAwKzAwMDAsYWQsYWRfMTBzZWMsMC4xMiwzMy40LDIwMTUtMDEtMTYsb3JnYW5pYyxHZXJtYW55CjEyNDgsVVBGTUxJRUtXSFlYOTY0LFVQRk1MSUVLV0hZWDk2NC14cm9nbWRiaywyMDE1LTAxLTE2VDA4OjAzOjM5LjAwMDAwMCswMDAwLDIwMTUtMDEtMTZUMDg6MjI6MjcuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAzLDMzLjQsMjAxNS0wMS0xNixvcmdhbmljLEdlcm1hbnkKMTI0OSxVUEZNTElFS1dIWVg5NjQsVVBGTUxJRUtXSFlYOTY0LXhyb2dtZGJrLDIwMTUtMDEtMTZUMDg6MDM6MzkuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNlQwODoyNzo1MS4wMDAwMDArMDAwMCxhZCxhZF8xNXNlYywwLjQ5LDMzLjQsMjAxNS0wMS0xNixvcmdhbmljLEdlcm1hbnkKMTI4NixNVENJV0tPVkFTWVA5MjUsTVRDSVdLT1ZBU1lQOTI1LWhzNGk1MnZnLDIwMTUtMDEtMTZUMTI6MjI6MjMuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNlQxMjozMDoyMy4wMDAwMDArMDAwMCxhZCxhZF8xMHNlYywwLjIzLDQxLjAsMjAxNS0wMS0xNCxvcmdhbmljLEdlcm1hbnkKMTI4NyxNVENJV0tPVkFTWVA5MjUsTVRDSVdLT1ZBU1lQOTI1LWhzNGk1MnZnLDIwMTUtMDEtMTZUMTI6MjI6MjMuMDAwMDAwKzAwMDAsMjAxNS0wMS0xNlQxMjozMDozNS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMSw0MS4wLDIwMTUtMDEtMTQsb3JnYW5pYyxHZXJtYW55CjEyODgsTVRDSVdLT1ZBU1lQOTI1LE1UQ0lXS09WQVNZUDkyNS1oczRpNTJ2ZywyMDE1LTAxLTE2VDEyOjIyOjIzLjAwMDAwMCswMDAwLDIwMTUtMDEtMTZUMTI6Mzg6NTkuMDAwMDAwKzAwMDAsYWQsYWRfMzBzZWMsMS4yNyw0MS4wLDIwMTUtMDEtMTQsb3JnYW5pYyxHZXJtYW55CjEyODksTVRDSVdLT1ZBU1lQOTI1LE1UQ0lXS09WQVNZUDkyNS1oczRpNTJ2ZywyMDE1LTAxLTE2VDEyOjIyOjIzLjAwMDAwMCswMDAwLDIwMTUtMDEtMTZUMTI6NDg6MjMuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjEsNDEuMCwyMDE1LTAxLTE0LG9yZ2FuaWMsR2VybWFueQoxMjkwLE1UQ0lXS09WQVNZUDkyNSxNVENJV0tPVkFTWVA5MjUtaHM0aTUydmcsMjAxNS0wMS0xNlQxMjoyMjoyMy4wMDAwMDArMDAwMCwyMDE1LTAxLTE2VDEyOjU5OjExLjAwMDAwMCswMDAwLGFkLGFkX3BsYXlhYmxlLDEuMjIsNDEuMCwyMDE1LTAxLTE0LG9yZ2FuaWMsR2VybWFueQoxMzIwLE1UQ0lXS09WQVNZUDkyNSxNVENJV0tPVkFTWVA5MjUtZnRjYnMyMTcsMjAxNS0wMS0xNlQxNToyNzoyNC4wMDAwMDArMDAwMCwyMDE1LTAxLTE2VDE1OjMwOjI0LjAwMDAwMCswMDAwLGFkLGFkXzIwc2VjLDAuNzksNy4xLDIwMTUtMDEtMTQsb3JnYW5pYyxHZXJtYW55CjEzOTIsVVBGTUxJRUtXSFlYOTY0LFVQRk1MSUVLV0hZWDk2NC1waDh6NTd3dCwyMDE1LTAxLTE3VDAzOjE2OjQxLjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMDM6MjU6MjkuMDAwMDAwKzAwMDAsYWQsYWRfMzBzZWMsMS4xMyw0MC42LDIwMTUtMDEtMTYsb3JnYW5pYyxHZXJtYW55CjEzOTMsVVBGTUxJRUtXSFlYOTY0LFVQRk1MSUVLV0hZWDk2NC1waDh6NTd3dCwyMDE1LTAxLTE3VDAzOjE2OjQxLjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMDM6Mzk6MDUuMDAwMDAwKzAwMDAsYWQsYWRfMTVzZWMsMC41LDQwLjYsMjAxNS0wMS0xNixvcmdhbmljLEdlcm1hbnkKMTM5NCxVUEZNTElFS1dIWVg5NjQsVVBGTUxJRUtXSFlYOTY0LXBoOHo1N3d0LDIwMTUtMDEtMTdUMDM6MTY6NDEuMDAwMDAwKzAwMDAsMjAxNS0wMS0xN1QwMzo0MzozNS4wMDAwMDArMDAwMCxhZCxhZF8zMHNlYywxLjA3OTgsNDAuNiwyMDE1LTAxLTE2LG9yZ2FuaWMsR2VybWFueQoxMzk1LFVQRk1MSUVLV0hZWDk2NCxVUEZNTElFS1dIWVg5NjQtcGg4ejU3d3QsMjAxNS0wMS0xN1QwMzoxNjo0MS4wMDAwMDArMDAwMCwyMDE1LTAxLTE3VDAzOjQ2OjIzLjAwMDAwMCswMDAwLGlhcCxvZmZlcjIsOC45OSw0MC42LDIwMTUtMDEtMTYsb3JnYW5pYyxHZXJtYW55CjEzOTYsVVBGTUxJRUtXSFlYOTY0LFVQRk1MSUVLV0hZWDk2NC1waDh6NTd3dCwyMDE1LTAxLTE3VDAzOjE2OjQxLjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMDM6NTQ6NTMuMDAwMDAwKzAwMDAsYWQsYWRfMzBzZWMsMS4zNSw0MC42LDIwMTUtMDEtMTYsb3JnYW5pYyxHZXJtYW55CjEzOTcsVVBGTUxJRUtXSFlYOTY0LFVQRk1MSUVLV0hZWDk2NC1waDh6NTd3dCwyMDE1LTAxLTE3VDAzOjE2OjQxLjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMDM6NTU6NDEuMDAwMDAwKzAwMDAsYWQsYWRfMTVzZWMsMC41NSw0MC42LDIwMTUtMDEtMTYsb3JnYW5pYyxHZXJtYW55CjE0MDcsR1NRSlhJT0tZTUVBNzEyLEdTUUpYSU9LWU1FQTcxMi1jZjQ1YWJvbiwyMDE1LTAxLTE3VDA0OjA2OjEwLjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMDQ6MjU6MjguMDAwMDAwKzAwMDAsYWQsYWRfMzBzZWMsMC45NCwyMC40LDIwMTUtMDEtMDcsZ29vZ2xlLEdlcm1hbnkKMTQ1OCxNVENJV0tPVkFTWVA5MjUsTVRDSVdLT1ZBU1lQOTI1LW51OWR3M2JvLDIwMTUtMDEtMTdUMTI6MDM6MjcuMDAwMDAwKzAwMDAsMjAxNS0wMS0xN1QxMjowOTo1Ny4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMTEsMzAuMCwyMDE1LTAxLTE0LG9yZ2FuaWMsR2VybWFueQoxNDU5LE1UQ0lXS09WQVNZUDkyNSxNVENJV0tPVkFTWVA5MjUtbnU5ZHczYm8sMjAxNS0wMS0xN1QxMjowMzoyNy4wMDAwMDArMDAwMCwyMDE1LTAxLTE3VDEyOjE4OjA5LjAwMDAwMCswMDAwLGlhcCxvZmZlcjMsMTMuNDkxLDMwLjAsMjAxNS0wMS0xNCxvcmdhbmljLEdlcm1hbnkKMTQ2MCxNVENJV0tPVkFTWVA5MjUsTVRDSVdLT1ZBU1lQOTI1LW51OWR3M2JvLDIwMTUtMDEtMTdUMTI6MDM6MjcuMDAwMDAwKzAwMDAsMjAxNS0wMS0xN1QxMjoxOTo1MS4wMDAwMDArMDAwMCxhZCxhZF8xNXNlYywwLjI0LDMwLjAsMjAxNS0wMS0xNCxvcmdhbmljLEdlcm1hbnkKMTQ2MSxNVENJV0tPVkFTWVA5MjUsTVRDSVdLT1ZBU1lQOTI1LW51OWR3M2JvLDIwMTUtMDEtMTdUMTI6MDM6MjcuMDAwMDAwKzAwMDAsMjAxNS0wMS0xN1QxMjoyNjowOS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDcsMzAuMCwyMDE1LTAxLTE0LG9yZ2FuaWMsR2VybWFueQoxNDYyLE1UQ0lXS09WQVNZUDkyNSxNVENJV0tPVkFTWVA5MjUtbnU5ZHczYm8sMjAxNS0wMS0xN1QxMjowMzoyNy4wMDAwMDArMDAwMCwyMDE1LTAxLTE3VDEyOjI2OjM5LjAwMDAwMCswMDAwLGlhcCxnZW1zMSwyLjI0LDMwLjAsMjAxNS0wMS0xNCxvcmdhbmljLEdlcm1hbnkKMTQ2MyxNVENJV0tPVkFTWVA5MjUsTVRDSVdLT1ZBU1lQOTI1LW51OWR3M2JvLDIwMTUtMDEtMTdUMTI6MDM6MjcuMDAwMDAwKzAwMDAsMjAxNS0wMS0xN1QxMjoyNzo1MS4wMDAwMDArMDAwMCxpYXAsZ29sZDMsNC40OSwzMC4wLDIwMTUtMDEtMTQsb3JnYW5pYyxHZXJtYW55CjE0NjQsTVRDSVdLT1ZBU1lQOTI1LE1UQ0lXS09WQVNZUDkyNS1udTlkdzNibywyMDE1LTAxLTE3VDEyOjAzOjI3LjAwMDAwMCswMDAwLDIwMTUtMDEtMTdUMTI6MzE6MDMuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAzLDMwLjAsMjAxNS0wMS0xNCxvcmdhbmljLEdlcm1hbnkKMTQ4MCxVUEZNTElFS1dIWVg5NjQsVVBGTUxJRUtXSFlYOTY0LTJxb204bmV5LDIwMTUtMDEtMTdUMTQ6NTI6MDkuMDAwMDAwKzAwMDAsMjAxNS0wMS0xN1QxNDo1NTo1Ny4wMDAwMDArMDAwMCxhZCxhZF8zMHNlYywxLjI4LDE4LjAsMjAxNS0wMS0xNixvcmdhbmljLEdlcm1hbnkKMTQ4MSxVUEZNTElFS1dIWVg5NjQsVVBGTUxJRUtXSFlYOTY0LTJxb204bmV5LDIwMTUtMDEtMTdUMTQ6NTI6MDkuMDAwMDAwKzAwMDAsMjAxNS0wMS0xN1QxNDo1NzowOS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDMsMTguMCwyMDE1LTAxLTE2LG9yZ2FuaWMsR2VybWFueQoxNTA5LE1UQ0lXS09WQVNZUDkyNSxNVENJV0tPVkFTWVA5MjUtNXd2M3RhMm8sMjAxNS0wMS0xN1QxOToxNjoxOS4wMDAwMDArMDAwMCwyMDE1LTAxLTE3VDE5OjI4OjQ5LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wOSwxNi4yLDIwMTUtMDEtMTQsb3JnYW5pYyxHZXJtYW55CjE2MjQsTVRDSVdLT1ZBU1lQOTI1LE1UQ0lXS09WQVNZUDkyNS1wY244a3QybSwyMDE1LTAxLTE4VDExOjE0OjI5LjAwMDAwMCswMDAwLDIwMTUtMDEtMThUMTE6MTc6MTcuMDAwMDAwKzAwMDAsaWFwLG9mZmVyMSw0LjQ5LDI1LjksMjAxNS0wMS0xNCxvcmdhbmljLEdlcm1hbnkKMTYyNSxNVENJV0tPVkFTWVA5MjUsTVRDSVdLT1ZBU1lQOTI1LXBjbjhrdDJtLDIwMTUtMDEtMThUMTE6MTQ6MjkuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOFQxMToyMDoxMS4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDgsMjUuOSwyMDE1LTAxLTE0LG9yZ2FuaWMsR2VybWFueQoxNjI2LE1UQ0lXS09WQVNZUDkyNSxNVENJV0tPVkFTWVA5MjUtcGNuOGt0Mm0sMjAxNS0wMS0xOFQxMToxNDoyOS4wMDAwMDArMDAwMCwyMDE1LTAxLTE4VDExOjI3OjExLjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMTMsMjUuOSwyMDE1LTAxLTE0LG9yZ2FuaWMsR2VybWFueQoxNjI3LE1UQ0lXS09WQVNZUDkyNSxNVENJV0tPVkFTWVA5MjUtcGNuOGt0Mm0sMjAxNS0wMS0xOFQxMToxNDoyOS4wMDAwMDArMDAwMCwyMDE1LTAxLTE4VDExOjMzOjI5LjAwMDAwMCswMDAwLGFkLGFkX3N1cnZleSwxLjIyLDI1LjksMjAxNS0wMS0xNCxvcmdhbmljLEdlcm1hbnkKMTYyOCxNVENJV0tPVkFTWVA5MjUsTVRDSVdLT1ZBU1lQOTI1LXBjbjhrdDJtLDIwMTUtMDEtMThUMTE6MTQ6MjkuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOFQxMTozNjoyMy4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDYsMjUuOSwyMDE1LTAxLTE0LG9yZ2FuaWMsR2VybWFueQoxNjc3LE1UQ0lXS09WQVNZUDkyNSxNVENJV0tPVkFTWVA5MjUtbjlnbGJoMjcsMjAxNS0wMS0xOFQyMDoxMDo0Mi4wMDAwMDArMDAwMCwyMDE1LTAxLTE4VDIwOjE0OjA2LjAwMDAwMCswMDAwLGlhcCxnZW1zMSwyLjI0LDIwLjYsMjAxNS0wMS0xNCxvcmdhbmljLEdlcm1hbnkKMTY3OCxNVENJV0tPVkFTWVA5MjUsTVRDSVdLT1ZBU1lQOTI1LW45Z2xiaDI3LDIwMTUtMDEtMThUMjA6MTA6NDIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOFQyMDoyMDoyNC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMSwyMC42LDIwMTUtMDEtMTQsb3JnYW5pYyxHZXJtYW55CjE2NzksTVRDSVdLT1ZBU1lQOTI1LE1UQ0lXS09WQVNZUDkyNS1uOWdsYmgyNywyMDE1LTAxLTE4VDIwOjEwOjQyLjAwMDAwMCswMDAwLDIwMTUtMDEtMThUMjA6MzA6MDYuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA5LDIwLjYsMjAxNS0wMS0xNCxvcmdhbmljLEdlcm1hbnkKMTY4MCxNVENJV0tPVkFTWVA5MjUsTVRDSVdLT1ZBU1lQOTI1LW45Z2xiaDI3LDIwMTUtMDEtMThUMjA6MTA6NDIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOFQyMDozMDoxOC4wMDAwMDArMDAwMCxhZCxhZF9zdXJ2ZXksMC43MiwyMC42LDIwMTUtMDEtMTQsb3JnYW5pYyxHZXJtYW55CjE2ODEsTVRDSVdLT1ZBU1lQOTI1LE1UQ0lXS09WQVNZUDkyNS1uOWdsYmgyNywyMDE1LTAxLTE4VDIwOjEwOjQyLjAwMDAwMCswMDAwLDIwMTUtMDEtMThUMjA6MzA6MzAuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyLDIwLjYsMjAxNS0wMS0xNCxvcmdhbmljLEdlcm1hbnkKMTY4OSxNVENJV0tPVkFTWVA5MjUsTVRDSVdLT1ZBU1lQOTI1LThycHpkNm13LDIwMTUtMDEtMThUMjM6MzQ6NDEuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOFQyMzozNDo1My4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDgsMjkuNiwyMDE1LTAxLTE0LG9yZ2FuaWMsR2VybWFueQoxNjkwLE1UQ0lXS09WQVNZUDkyNSxNVENJV0tPVkFTWVA5MjUtOHJwemQ2bXcsMjAxNS0wMS0xOFQyMzozNDo0MS4wMDAwMDArMDAwMCwyMDE1LTAxLTE5VDAwOjAwOjUzLjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4xMiwyOS42LDIwMTUtMDEtMTQsb3JnYW5pYyxHZXJtYW55CjE2OTEsTVRDSVdLT1ZBU1lQOTI1LE1UQ0lXS09WQVNZUDkyNS04cnB6ZDZtdywyMDE1LTAxLTE4VDIzOjM0OjQxLjAwMDAwMCswMDAwLDIwMTUtMDEtMTlUMDA6MDM6NDcuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyLDI5LjYsMjAxNS0wMS0xNCxvcmdhbmljLEdlcm1hbnkKMTY5MixHU1FKWElPS1lNRUE3MTIsR1NRSlhJT0tZTUVBNzEyLTR5MmV1NXA2LDIwMTUtMDEtMThUMjM6NDM6NDEuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOFQyMzo1NzoyOS4wMDAwMDArMDAwMCxhZCxhZF8zMHNlYywxLjI1LDM2LjMsMjAxNS0wMS0wNyxnb29nbGUsR2VybWFueQoxNjkzLEdTUUpYSU9LWU1FQTcxMixHU1FKWElPS1lNRUE3MTItNHkyZXU1cDYsMjAxNS0wMS0xOFQyMzo0Mzo0MS4wMDAwMDArMDAwMCwyMDE1LTAxLTE4VDIzOjU5OjQ3LjAwMDAwMCswMDAwLGFkLGFkX3N1cnZleSwwLjU1LDM2LjMsMjAxNS0wMS0wNyxnb29nbGUsR2VybWFueQoxNjk0LEdTUUpYSU9LWU1FQTcxMixHU1FKWElPS1lNRUE3MTItNHkyZXU1cDYsMjAxNS0wMS0xOFQyMzo0Mzo0MS4wMDAwMDArMDAwMCwyMDE1LTAxLTE5VDAwOjE1OjU5LjAwMDAwMCswMDAwLGFkLGFkX3BsYXlhYmxlLDEuNTgsMzYuMywyMDE1LTAxLTA3LGdvb2dsZSxHZXJtYW55CjE3MzcsTVRDSVdLT1ZBU1lQOTI1LE1UQ0lXS09WQVNZUDkyNS1lcWJjdnlndCwyMDE1LTAxLTE5VDA0OjM4OjU0LjAwMDAwMCswMDAwLDIwMTUtMDEtMTlUMDQ6Mzk6MTIuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjAyLDkuNCwyMDE1LTAxLTE0LG9yZ2FuaWMsR2VybWFueQoxNzc2LEdTUUpYSU9LWU1FQTcxMixHU1FKWElPS1lNRUE3MTItMmQ2enVjYjMsMjAxNS0wMS0xOVQwOTowMjoyOS4wMDAwMDArMDAwMCwyMDE1LTAxLTE5VDA5OjA5OjA1LjAwMDAwMCswMDAwLGlhcCxnb2xkMiwxLjc5LDE1LjMsMjAxNS0wMS0wNyxnb29nbGUsR2VybWFueQoxNzc3LEdTUUpYSU9LWU1FQTcxMixHU1FKWElPS1lNRUE3MTItMmQ2enVjYjMsMjAxNS0wMS0xOVQwOTowMjoyOS4wMDAwMDArMDAwMCwyMDE1LTAxLTE5VDA5OjEwOjI5LjAwMDAwMCswMDAwLGFkLGFkXzVzZWMsMC4wMiwxNS4zLDIwMTUtMDEtMDcsZ29vZ2xlLEdlcm1hbnkKMTgzNSxHU1FKWElPS1lNRUE3MTIsR1NRSlhJT0tZTUVBNzEyLThkYnlpbXc3LDIwMTUtMDEtMTlUMjA6MDE6NTIuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOVQyMDowNDoyOC4wMDAwMDArMDAwMCxpYXAsb2ZmZXI0LDE3Ljk5LDIzLjYsMjAxNS0wMS0wNyxnb29nbGUsR2VybWFueQoxODM2LEdTUUpYSU9LWU1FQTcxMixHU1FKWElPS1lNRUE3MTItOGRieWltdzcsMjAxNS0wMS0xOVQyMDowMTo1Mi4wMDAwMDArMDAwMCwyMDE1LTAxLTE5VDIwOjEwOjE2LjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMTQsMjMuNiwyMDE1LTAxLTA3LGdvb2dsZSxHZXJtYW55CjE4MzcsR1NRSlhJT0tZTUVBNzEyLEdTUUpYSU9LWU1FQTcxMi04ZGJ5aW13NywyMDE1LTAxLTE5VDIwOjAxOjUyLjAwMDAwMCswMDAwLDIwMTUtMDEtMTlUMjA6MTQ6MDQuMDAwMDAwKzAwMDAsYWQsYWRfMzBzZWMsMS4wOSwyMy42LDIwMTUtMDEtMDcsZ29vZ2xlLEdlcm1hbnkKMTg0NCxNVENJV0tPVkFTWVA5MjUsTVRDSVdLT1ZBU1lQOTI1LXp5a2Jkbzc1LDIwMTUtMDEtMTlUMjE6NTc6MjQuMDAwMDAwKzAwMDAsMjAxNS0wMS0xOVQyMTo1ODo0OC4wMDAwMDArMDAwMCxhZCxhZF9zdXJ2ZXksMC41MywxOC44LDIwMTUtMDEtMTQsb3JnYW5pYyxHZXJtYW55CjE4OTMsR1NRSlhJT0tZTUVBNzEyLEdTUUpYSU9LWU1FQTcxMi1vNHl3ZGt6diwyMDE1LTAxLTIwVDA2OjQ5OjI4LjAwMDAwMCswMDAwLDIwMTUtMDEtMjBUMDY6NTU6MjguMDAwMDAwKzAwMDAsaWFwLG9mZmVyNSwyNi4wOSw0MC45LDIwMTUtMDEtMDcsZ29vZ2xlLEdlcm1hbnkKMTg5NCxHU1FKWElPS1lNRUE3MTIsR1NRSlhJT0tZTUVBNzEyLW80eXdka3p2LDIwMTUtMDEtMjBUMDY6NDk6MjguMDAwMDAwKzAwMDAsMjAxNS0wMS0yMFQwNzoxMjoyOC4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDUsNDAuOSwyMDE1LTAxLTA3LGdvb2dsZSxHZXJtYW55CjE5MTMsTVRDSVdLT1ZBU1lQOTI1LE1UQ0lXS09WQVNZUDkyNS0xcTN4dmZtcCwyMDE1LTAxLTIwVDEyOjM0OjQzLjAwMDAwMCswMDAwLDIwMTUtMDEtMjBUMTI6MzU6MzcuMDAwMDAwKzAwMDAsaWFwLG9mZmVyNSwyNi4wOSwzLjksMjAxNS0wMS0xNCxvcmdhbmljLEdlcm1hbnkKMTkxNCxNVENJV0tPVkFTWVA5MjUsTVRDSVdLT1ZBU1lQOTI1LTFxM3h2Zm1wLDIwMTUtMDEtMjBUMTI6MzQ6NDMuMDAwMDAwKzAwMDAsMjAxNS0wMS0yMFQxMjozNzoyNS4wMDAwMDArMDAwMCxpYXAsZ29sZDIsMS43OSwzLjksMjAxNS0wMS0xNCxvcmdhbmljLEdlcm1hbnkKMTkxNSxHU1FKWElPS1lNRUE3MTIsR1NRSlhJT0tZTUVBNzEyLWV1MmxtcjF0LDIwMTUtMDEtMjBUMTM6MjU6MjQuMDAwMDAwKzAwMDAsMjAxNS0wMS0yMFQxMzoyNjowNi4wMDAwMDArMDAwMCxhZCxhZF81c2VjLDAuMDIsMjQuMSwyMDE1LTAxLTA3LGdvb2dsZSxHZXJtYW55CjE5MTYsR1NRSlhJT0tZTUVBNzEyLEdTUUpYSU9LWU1FQTcxMi1ldTJsbXIxdCwyMDE1LTAxLTIwVDEzOjI1OjI0LjAwMDAwMCswMDAwLDIwMTUtMDEtMjBUMTM6MjY6MjQuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjA5LDI0LjEsMjAxNS0wMS0wNyxnb29nbGUsR2VybWFueQoxOTE3LEdTUUpYSU9LWU1FQTcxMixHU1FKWElPS1lNRUE3MTItZXUybG1yMXQsMjAxNS0wMS0yMFQxMzoyNToyNC4wMDAwMDArMDAwMCwyMDE1LTAxLTIwVDEzOjQxOjAwLjAwMDAwMCswMDAwLGlhcCxnb2xkMiwxLjc5LDI0LjEsMjAxNS0wMS0wNyxnb29nbGUsR2VybWFueQoxOTE4LEdTUUpYSU9LWU1FQTcxMixHU1FKWElPS1lNRUE3MTItZXUybG1yMXQsMjAxNS0wMS0yMFQxMzoyNToyNC4wMDAwMDArMDAwMCwyMDE1LTAxLTIwVDEzOjQzOjU0LjAwMDAwMCswMDAwLGFkLGFkXzEwc2VjLDAuMTgsMjQuMSwyMDE1LTAxLTA3LGdvb2dsZSxHZXJtYW55CjE5ODcsVlBOUllMTUJLSkdUOTI1LFZQTlJZTE1CS0pHVDkyNS12dDI2cTlnYiwyMDE1LTAxLTIxVDAxOjA3OjI0LjAwMDAwMCswMDAwLDIwMTUtMDEtMjFUMDE6MTA6MzAuMDAwMDAwKzAwMDAsYWQsYWRfNXNlYywwLjEsMjQuOSwyMDE1LTAxLTIxLG90aGVyX2NhbXBhaWduLEdlcm1hbnkKMTk4OCxWUE5SWUxNQktKR1Q5MjUsVlBOUllMTUJLSkdUOTI1LXZ0MjZxOWdiLDIwMTUtMDEtMjFUMDE6MDc6MjQuMDAwMDAwKzAwMDAsMjAxNS0wMS0yMVQwMToxMTo1NC4wMDAwMDArMDAwMCxpYXAsb2ZmZXI0LDE3Ljk5LDI0LjksMjAxNS0wMS0yMSxvdGhlcl9jYW1wYWlnbixHZXJtYW55CjE5ODksVlBOUllMTUJLSkdUOTI1LFZQTlJZTE1CS0pHVDkyNS12dDI2cTlnYiwyMDE1LTAxLTIxVDAxOjA3OjI0LjAwMDAwMCswMDAwLDIwMTUtMDEtMjFUMDE6MjE6MjQuMDAwMDAwKzAwMDAsYWQsYWRfMTVzZWMsMC4yNiwyNC45LDIwMTUtMDEtMjEsb3RoZXJfY2FtcGFpZ24sR2VybWFueQoxOTkwLFZQTlJZTE1CS0pHVDkyNSxWUE5SWUxNQktKR1Q5MjUtdnQyNnE5Z2IsMjAxNS0wMS0yMVQwMTowNzoyNC4wMDAwMDArMDAwMCwyMDE1LTAxLTIxVDAxOjIzOjM2LjAwMDAwMCswMDAwLGFkLGFkX3N1cnZleSwxLjE3LDI0LjksMjAxNS0wMS0yMSxvdGhlcl9jYW1wYWlnbixHZXJtYW55CjE5OTEsVlBOUllMTUJLSkdUOTI1LFZQTlJZTE1CS0pHVDkyNS12dDI2cTlnYiwyMDE1LTAxLTIxVDAxOjA3OjI0LjAwMDAwMCswMDAwLDIwMTUtMDEtMjFUMDE6MjY6MTIuMDAwMDAwKzAwMDAsYWQsYWRfc3VydmV5LDAuNzIsMjQuOSwyMDE1LTAxLTIxLG90aGVyX2NhbXBhaWduLEdlcm1hbnkK" download="extract_0006.csv"><button style="background-color: #67C2DC; color: #FFFFFF; border: none; padding: 5px; font-weight: bold; cursor: pointer; border-radius: 4px;">CSV</button></a></td></p>
  </tr>
  <tr>
    <td style="height: 40px; background-color: #4CA64C; color: transparent;font-size: 0px;" class="gt_row gt_left">#4CA64C</td>
    <td style="height: 40px; color: #666666;font-size: 13px;font-weight: bold;" class="gt_row gt_right">7</td>
    <td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_left">
        <div style="margin: 0; padding: 0; display: inline-block; height: 30px; vertical-align: middle; width: 16%;">
            <!--?xml version="1.0" encoding="UTF-8"?--><?xml version="1.0" encoding="UTF-8"?>
<svg width="30px" height="30px" viewBox="0 0 67 67" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <title>col_vals_between</title>
    <g id="Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="col_vals_between" transform="translate(0.000000, 0.206897)">
            <path d="M56.712234,1 C59.1975153,1 61.4475153,2.00735931 63.076195,3.63603897 C64.7048747,5.26471863 65.712234,7.51471863 65.712234,10 L65.712234,10 L65.712234,65 L10.712234,65 C8.22695259,65 5.97695259,63.9926407 4.34827294,62.363961 C2.71959328,60.7352814 1.71223397,58.4852814 1.71223397,56 L1.71223397,56 L1.71223397,10 C1.71223397,7.51471863 2.71959328,5.26471863 4.34827294,3.63603897 C5.97695259,2.00735931 8.22695259,1 10.712234,1 L10.712234,1 Z" id="rectangle" stroke="#000000" stroke-width="2" fill="#FFFFFF"></path>
            <path d="M11.993484,21.96875 C10.962234,22.082031 10.188797,22.964844 10.212234,24 L10.212234,42 C10.200515,42.722656 10.579422,43.390625 11.204422,43.753906 C11.825515,44.121094 12.598953,44.121094 13.220047,43.753906 C13.845047,43.390625 14.223953,42.722656 14.212234,42 L14.212234,24 C14.220047,23.457031 14.009109,22.9375 13.626297,22.554688 C13.243484,22.171875 12.723953,21.960938 12.180984,21.96875 C12.118484,21.964844 12.055984,21.964844 11.993484,21.96875 Z M55.993484,21.96875 C54.962234,22.082031 54.188797,22.964844 54.212234,24 L54.212234,42 C54.200515,42.722656 54.579422,43.390625 55.204422,43.753906 C55.825515,44.121094 56.598953,44.121094 57.220047,43.753906 C57.845047,43.390625 58.223953,42.722656 58.212234,42 L58.212234,24 C58.220047,23.457031 58.009109,22.9375 57.626297,22.554688 C57.243484,22.171875 56.723953,21.960938 56.180984,21.96875 C56.118484,21.964844 56.055984,21.964844 55.993484,21.96875 Z M16.212234,22 C15.661453,22 15.212234,22.449219 15.212234,23 C15.212234,23.550781 15.661453,24 16.212234,24 C16.763015,24 17.212234,23.550781 17.212234,23 C17.212234,22.449219 16.763015,22 16.212234,22 Z M20.212234,22 C19.661453,22 19.212234,22.449219 19.212234,23 C19.212234,23.550781 19.661453,24 20.212234,24 C20.763015,24 21.212234,23.550781 21.212234,23 C21.212234,22.449219 20.763015,22 20.212234,22 Z M24.212234,22 C23.661453,22 23.212234,22.449219 23.212234,23 C23.212234,23.550781 23.661453,24 24.212234,24 C24.763015,24 25.212234,23.550781 25.212234,23 C25.212234,22.449219 24.763015,22 24.212234,22 Z M28.212234,22 C27.661453,22 27.212234,22.449219 27.212234,23 C27.212234,23.550781 27.661453,24 28.212234,24 C28.763015,24 29.212234,23.550781 29.212234,23 C29.212234,22.449219 28.763015,22 28.212234,22 Z M32.212234,22 C31.661453,22 31.212234,22.449219 31.212234,23 C31.212234,23.550781 31.661453,24 32.212234,24 C32.763015,24 33.212234,23.550781 33.212234,23 C33.212234,22.449219 32.763015,22 32.212234,22 Z M36.212234,22 C35.661453,22 35.212234,22.449219 35.212234,23 C35.212234,23.550781 35.661453,24 36.212234,24 C36.763015,24 37.212234,23.550781 37.212234,23 C37.212234,22.449219 36.763015,22 36.212234,22 Z M40.212234,22 C39.661453,22 39.212234,22.449219 39.212234,23 C39.212234,23.550781 39.661453,24 40.212234,24 C40.763015,24 41.212234,23.550781 41.212234,23 C41.212234,22.449219 40.763015,22 40.212234,22 Z M44.212234,22 C43.661453,22 43.212234,22.449219 43.212234,23 C43.212234,23.550781 43.661453,24 44.212234,24 C44.763015,24 45.212234,23.550781 45.212234,23 C45.212234,22.449219 44.763015,22 44.212234,22 Z M48.212234,22 C47.661453,22 47.212234,22.449219 47.212234,23 C47.212234,23.550781 47.661453,24 48.212234,24 C48.763015,24 49.212234,23.550781 49.212234,23 C49.212234,22.449219 48.763015,22 48.212234,22 Z M52.212234,22 C51.661453,22 51.212234,22.449219 51.212234,23 C51.212234,23.550781 51.661453,24 52.212234,24 C52.763015,24 53.212234,23.550781 53.212234,23 C53.212234,22.449219 52.763015,22 52.212234,22 Z M21.462234,27.96875 C21.419265,27.976563 21.376297,27.988281 21.337234,28 C21.177078,28.027344 21.02864,28.089844 20.899734,28.1875 L15.618484,32.1875 C15.356765,32.375 15.200515,32.679688 15.200515,33 C15.200515,33.320313 15.356765,33.625 15.618484,33.8125 L20.899734,37.8125 C21.348953,38.148438 21.985672,38.058594 22.321609,37.609375 C22.657547,37.160156 22.567703,36.523438 22.118484,36.1875 L19.212234,34 L49.212234,34 L46.305984,36.1875 C45.856765,36.523438 45.766922,37.160156 46.102859,37.609375 C46.438797,38.058594 47.075515,38.148438 47.524734,37.8125 L52.805984,33.8125 C53.067703,33.625 53.223953,33.320313 53.223953,33 C53.223953,32.679688 53.067703,32.375 52.805984,32.1875 L47.524734,28.1875 C47.30989,28.027344 47.040359,27.960938 46.774734,28 C46.743484,28 46.712234,28 46.680984,28 C46.282547,28.074219 45.96614,28.382813 45.884109,28.78125 C45.802078,29.179688 45.970047,29.585938 46.305984,29.8125 L49.212234,32 L19.212234,32 L22.118484,29.8125 C22.520828,29.566406 22.696609,29.070313 22.536453,28.625 C22.380203,28.179688 21.930984,27.90625 21.462234,27.96875 Z M16.212234,42 C15.661453,42 15.212234,42.449219 15.212234,43 C15.212234,43.550781 15.661453,44 16.212234,44 C16.763015,44 17.212234,43.550781 17.212234,43 C17.212234,42.449219 16.763015,42 16.212234,42 Z M20.212234,42 C19.661453,42 19.212234,42.449219 19.212234,43 C19.212234,43.550781 19.661453,44 20.212234,44 C20.763015,44 21.212234,43.550781 21.212234,43 C21.212234,42.449219 20.763015,42 20.212234,42 Z M24.212234,42 C23.661453,42 23.212234,42.449219 23.212234,43 C23.212234,43.550781 23.661453,44 24.212234,44 C24.763015,44 25.212234,43.550781 25.212234,43 C25.212234,42.449219 24.763015,42 24.212234,42 Z M28.212234,42 C27.661453,42 27.212234,42.449219 27.212234,43 C27.212234,43.550781 27.661453,44 28.212234,44 C28.763015,44 29.212234,43.550781 29.212234,43 C29.212234,42.449219 28.763015,42 28.212234,42 Z M32.212234,42 C31.661453,42 31.212234,42.449219 31.212234,43 C31.212234,43.550781 31.661453,44 32.212234,44 C32.763015,44 33.212234,43.550781 33.212234,43 C33.212234,42.449219 32.763015,42 32.212234,42 Z M36.212234,42 C35.661453,42 35.212234,42.449219 35.212234,43 C35.212234,43.550781 35.661453,44 36.212234,44 C36.763015,44 37.212234,43.550781 37.212234,43 C37.212234,42.449219 36.763015,42 36.212234,42 Z M40.212234,42 C39.661453,42 39.212234,42.449219 39.212234,43 C39.212234,43.550781 39.661453,44 40.212234,44 C40.763015,44 41.212234,43.550781 41.212234,43 C41.212234,42.449219 40.763015,42 40.212234,42 Z M44.212234,42 C43.661453,42 43.212234,42.449219 43.212234,43 C43.212234,43.550781 43.661453,44 44.212234,44 C44.763015,44 45.212234,43.550781 45.212234,43 C45.212234,42.449219 44.763015,42 44.212234,42 Z M48.212234,42 C47.661453,42 47.212234,42.449219 47.212234,43 C47.212234,43.550781 47.661453,44 48.212234,44 C48.763015,44 49.212234,43.550781 49.212234,43 C49.212234,42.449219 48.763015,42 48.212234,42 Z M52.212234,42 C51.661453,42 51.212234,42.449219 51.212234,43 C51.212234,43.550781 51.661453,44 52.212234,44 C52.763015,44 53.212234,43.550781 53.212234,43 C53.212234,42.449219 52.763015,42 52.212234,42 Z" id="inside_range" fill="#000000" fill-rule="nonzero"></path>
        </g>
    </g>
</svg>
        </div>
        <div style="font-family: 'IBM Plex Mono', monospace, courier; color: black; font-size: 10px; display: inline-block; vertical-align: middle;">
            <div>col_vals_between()</div>
        </div>
<pre><code>    &lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;session_duration&lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;[10, 50]&lt;/td&gt;
&lt;td style=&quot;height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;&quot; class=&quot;gt_row gt_center&quot;&gt;&lt;svg width=&quot;24px&quot; height=&quot;25px&quot; viewBox=&quot;0 0 24 25&quot; version=&quot;1.1&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot; style=&quot;vertical-align: middle;&quot;&gt;
&lt;g id=&quot;modified&quot; stroke=&quot;none&quot; stroke-width=&quot;1&quot; fill=&quot;none&quot; fill-rule=&quot;evenodd&quot;&gt;
    &lt;g id=&quot;modified&quot; transform=&quot;translate(0.000000, 0.570147)&quot;&gt;
        &lt;rect id=&quot;Rectangle&quot; x=&quot;0.125132506&quot; y=&quot;0&quot; width=&quot;23.749735&quot; height=&quot;23.7894737&quot;&gt;&lt;/rect&gt;
        &lt;rect id=&quot;Rectangle&quot; fill=&quot;#000000&quot; x=&quot;15.2215626&quot; y=&quot;14.8025885&quot; width=&quot;6.34089821&quot; height=&quot;6.34089821&quot;&gt;&lt;/rect&gt;
        &lt;rect id=&quot;Rectangle&quot; fill=&quot;#9A7CB4&quot; x=&quot;16.1264309&quot; y=&quot;15.7074568&quot; width=&quot;4.53116158&quot; height=&quot;4.53116158&quot;&gt;&lt;/rect&gt;
        &lt;path d=&quot;M4.40094816,14.3498527 C2.36911602,14.3498527 0.715948163,16.0028586 0.715948163,18.0348527 C0.715948163,20.0668467 2.36911602,21.7198527 4.40094816,21.7198527 C6.43278031,21.7198527 8.08594816,20.0668467 8.08594816,18.0348527 C8.08594816,16.0028586 6.43272633,14.3498527 4.40094816,14.3498527 Z M4.40094816,20.9828203 C2.77541767,20.9828203 1.45298055,19.6603831 1.45298055,18.0348527 C1.45298055,16.4093222 2.77541767,15.086885 4.40094816,15.086885 C6.02647865,15.086885 7.34891578,16.4093222 7.34891578,18.0348527 C7.34891578,19.6603831 6.02647865,20.9828203 4.40094816,20.9828203 Z&quot; id=&quot;Shape&quot; fill=&quot;#000000&quot; fill-rule=&quot;nonzero&quot;&gt;&lt;/path&gt;
        &lt;path d=&quot;M18.4333601,-0.640287588 L18.4333601,14.5882952 L9.52131131,14.5882952 L11.3716151,15.980997 C11.6576165,16.1948765 11.7148169,16.6002518 11.5009374,16.8862532 C11.2870585,17.1722546 10.8816827,17.229455 10.5956813,17.0155755 L10.5956813,17.0155755 L7.23330126,14.4689208 C7.06667429,14.3495464 6.96719559,14.1555632 6.96719559,13.9516316 C6.96719559,13.7477006 7.06667429,13.5537168 7.23330126,13.4343424 L7.23330126,13.4343424 L10.5956813,10.8876877 C10.677751,10.8255137 10.7722561,10.7857222 10.8742216,10.7683132 C10.8990916,10.7608522 10.9264478,10.7533918 10.9538046,10.7484175 C11.2522407,10.708626 11.5382421,10.8827141 11.6377208,11.166228 C11.7396863,11.4497426 11.6277729,11.765587 11.3716151,11.9222661 L11.3716151,11.9222661 L9.52131131,13.3149679 L17.1593533,13.3147124 L17.1594577,0.633614828 L6.9283533,0.633614828 L6.9283533,-0.640287588 L18.4333601,-0.640287588 Z&quot; id=&quot;arrow&quot; fill=&quot;#000000&quot; transform=&quot;translate(12.680857, 8.252286) rotate(-90.000000) translate(-12.680857, -8.252286) &quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
&lt;/g&gt;
</code></pre>
<p></svg></td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color:#4CA64C;">✓</span></td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_right">1</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">1<br />1.00</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">0<br />0.00</td>
<td style="height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color: #AAAAAA;">○</span></td>
<td style="height: 40px; background-color: #FCFCFC;" class="gt_row gt_center"><span style="color: #EBBC14;">○</span></td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color: #FF3300;">○</span></td>
<td style="height: 40px;" class="gt_row gt_center">—</td></p>
  </tr>
  <tr>
    <td style="height: 40px; background-color: #EBBC14; color: transparent;font-size: 0px;" class="gt_row gt_left">#EBBC14</td>
    <td style="height: 40px; color: #666666;font-size: 13px;font-weight: bold;" class="gt_row gt_right">8</td>
    <td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_left">
        <div style="margin: 0; padding: 0; display: inline-block; height: 30px; vertical-align: middle; width: 16%;">
            <!--?xml version="1.0" encoding="UTF-8"?--><?xml version="1.0" encoding="UTF-8"?>
<svg width="30px" height="30px" viewBox="0 0 67 67" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <title>rows_distinct</title>
    <g id="Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="rows_distinct" transform="translate(0.000000, 0.482759)">
            <path d="M56.712234,1 C59.1975153,1 61.4475153,2.00735931 63.076195,3.63603897 C64.7048747,5.26471863 65.712234,7.51471863 65.712234,10 L65.712234,10 L65.712234,65 L10.712234,65 C8.22695259,65 5.97695259,63.9926407 4.34827294,62.363961 C2.71959328,60.7352814 1.71223397,58.4852814 1.71223397,56 L1.71223397,56 L1.71223397,10 C1.71223397,7.51471863 2.71959328,5.26471863 4.34827294,3.63603897 C5.97695259,2.00735931 8.22695259,1 10.712234,1 L10.712234,1 Z" id="rectangle" stroke="#000000" stroke-width="2" fill="#FFFFFF"></path>
            <g id="no_gemini" transform="translate(17.000000, 13.000000)">
                <path d="M3.66705619,6.62107508 C3.12510104,6.64066386 2.67455974,7.04767444 2.60273432,7.58527682 C2.52873228,8.1228792 2.85303526,8.6343627 3.37104848,8.79760239 C4.40489909,9.15455286 6.70113553,9.87063021 9.86580595,10.364702 L9.86580595,30.7369976 C6.65978137,31.2332458 4.37225104,31.964559 3.37104848,32.3215095 C2.78991555,32.5282797 2.48520173,33.1681784 2.69197196,33.7493114 C2.8987422,34.3304443 3.53864094,34.6351581 4.11977387,34.4283879 C5.54975217,33.9190808 10.2031678,32.4608072 16.5172734,32.4608072 C22.7943781,32.4608072 27.5500901,33.8907855 29.0540706,34.4109757 C29.6352036,34.6133926 30.2707495,34.304326 30.4731664,33.7231931 C30.6755833,33.1420601 30.3665167,32.5065142 29.7853838,32.3040973 C28.7493568,31.9449704 26.4313554,31.2441283 23.2383897,30.7544098 L23.2383897,10.3821143 C26.4444143,9.88804243 28.745004,9.16108259 29.7679716,8.79760239 C30.3491045,8.59083215 30.6538184,7.95093341 30.4470481,7.36980048 C30.2402779,6.78866755 29.6003791,6.48395373 29.0192462,6.69072396 C27.5587963,7.20873774 22.9162637,8.65830464 16.6391589,8.65830464 C10.3707603,8.65830464 5.61287188,7.21309051 4.10236166,6.69072396 C3.96306391,6.6384873 3.81506005,6.61454548 3.66705619,6.62107508 Z M12.0945699,10.6432975 C13.4940771,10.789125 15.0198226,10.8870686 16.6391589,10.8870686 C18.1997289,10.8870686 19.6623552,10.7978311 21.0096257,10.6607098 L21.0096257,30.4584021 C19.623178,30.316928 18.1191975,30.2320433 16.5172734,30.2320433 C14.9327615,30.2320433 13.4570763,30.3191044 12.0945699,30.4584021 L12.0945699,10.6432975 Z" id="gemini" stroke="#000000" stroke-width="2" fill="#000000" fill-rule="nonzero"></path>
                <path d="M16.6605354,-5.05929499 C16.9366778,-5.05929499 17.1605354,-4.83543737 17.1605354,-4.55929499 L17.1605354,44.5687509 C17.1605354,44.8448933 16.9366778,45.0687509 16.6605354,45.0687509 C16.384393,45.0687509 16.1605354,44.8448933 16.1605354,44.5687509 L16.1605354,-4.55929499 C16.1605354,-4.83543737 16.384393,-5.05929499 16.6605354,-5.05929499 Z" id="line_black" fill="#000000" transform="translate(16.660535, 20.004728) rotate(-320.000000) translate(-16.660535, -20.004728) "></path>
                <polygon id="line_white" fill="#FFFFFF" transform="translate(18.560032, 19.158031) rotate(-320.000000) translate(-18.560032, -19.158031) " points="18.0600316 -4.45366735 19.0600316 -4.45366735 19.0600316 42.7697299 18.0600316 42.7697299"></polygon>
            </g>
        </g>
    </g>
</svg>
        </div>
        <div style="font-family: 'IBM Plex Mono', monospace, courier; color: black; font-size: 11px; display: inline-block; vertical-align: middle;">
            <div>rows_distinct()</div>
        </div>
<pre><code>    &lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;player_id, session_id, time&lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;&amp;mdash;&lt;/td&gt;
&lt;td style=&quot;height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;&quot; class=&quot;gt_row gt_center&quot;&gt;&lt;svg width=&quot;25px&quot; height=&quot;25px&quot; viewBox=&quot;0 0 25 25&quot; version=&quot;1.1&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot; style=&quot;vertical-align: middle;&quot;&gt;
&lt;g id=&quot;unchanged&quot; stroke=&quot;none&quot; stroke-width=&quot;1&quot; fill=&quot;none&quot; fill-rule=&quot;evenodd&quot;&gt;
    &lt;g id=&quot;unchanged&quot; transform=&quot;translate(0.500000, 0.570147)&quot;&gt;
        &lt;rect id=&quot;Rectangle&quot; x=&quot;0.125132506&quot; y=&quot;0&quot; width=&quot;23.749735&quot; height=&quot;23.7894737&quot;&gt;&lt;/rect&gt;
        &lt;path d=&quot;M5.80375046,8.18194736 C3.77191832,8.18194736 2.11875046,9.83495328 2.11875046,11.8669474 C2.11875046,13.8989414 3.77191832,15.5519474 5.80375046,15.5519474 C7.8355826,15.5519474 9.48875046,13.8989414 9.48875046,11.8669474 C9.48875046,9.83495328 7.83552863,8.18194736 5.80375046,8.18194736 Z M5.80375046,14.814915 C4.17821997,14.814915 2.85578285,13.4924778 2.85578285,11.8669474 C2.85578285,10.2414169 4.17821997,8.91897975 5.80375046,8.91897975 C7.42928095,8.91897975 8.75171807,10.2414169 8.75171807,11.8669474 C8.75171807,13.4924778 7.42928095,14.814915 5.80375046,14.814915 Z&quot; id=&quot;Shape&quot; fill=&quot;#000000&quot; fill-rule=&quot;nonzero&quot;&gt;&lt;/path&gt;
        &lt;path d=&quot;M13.9638189,8.699335 C13.9364621,8.70430925 13.9091059,8.71176968 13.8842359,8.71923074 C13.7822704,8.73663967 13.6877654,8.77643115 13.6056956,8.83860518 L10.2433156,11.3852598 C10.0766886,11.5046343 9.97720993,11.6986181 9.97720993,11.9025491 C9.97720993,12.1064807 10.0766886,12.3004639 10.2433156,12.4198383 L13.6056956,14.966493 C13.891697,15.1803725 14.2970729,15.1231721 14.5109517,14.8371707 C14.7248313,14.5511692 14.6676309,14.145794 14.3816294,13.9319145 L12.5313257,12.5392127 L21.8812495,12.5392127 L21.8812495,11.2658854 L12.5313257,11.2658854 L14.3816294,9.87318364 C14.6377872,9.71650453 14.7497006,9.40066014 14.6477351,9.11714553 C14.5482564,8.83363156 14.262255,8.65954352 13.9638189,8.699335 Z&quot; id=&quot;arrow&quot; fill=&quot;#000000&quot; transform=&quot;translate(15.929230, 11.894737) rotate(-180.000000) translate(-15.929230, -11.894737) &quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
&lt;/g&gt;
</code></pre>
<p></svg></td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color:#4CA64C;">✓</span></td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_right">2000</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">1978<br />0.99</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">22<br />0.01</td>
<td style="height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color: #AAAAAA;">●</span></td>
<td style="height: 40px; background-color: #FCFCFC;" class="gt_row gt_center"><span style="color: #EBBC14;">●</span></td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color: #FF3300;">○</span></td>
<td style="height: 40px;" class="gt_row gt_center"><a href="data:text/csv;base64,X3Jvd19udW1fLHBsYXllcl9pZCxzZXNzaW9uX2lkLHRpbWUKMzUzLFBaQk5SS1NNVUxIWDIxMyxQWkJOUktTTVVMSFgyMTMtbTJuNnRrMWksMjAxNS0wMS0wOFQxNDozODowNi4wMDAwMDArMDAwMAozNTQsUFpCTlJLU01VTEhYMjEzLFBaQk5SS1NNVUxIWDIxMy1tMm42dGsxaSwyMDE1LTAxLTA4VDE0OjM4OjA2LjAwMDAwMCswMDAwCjQwMCxRRFVaSklFVENBR1c2NTQsUURVWkpJRVRDQUdXNjU0LWdtaTZib2YxLDIwMTUtMDEtMDlUMDM6MTA6MDUuMDAwMDAwKzAwMDAKNDAxLFFEVVpKSUVUQ0FHVzY1NCxRRFVaSklFVENBR1c2NTQtZ21pNmJvZjEsMjAxNS0wMS0wOVQwMzoxMDowNS4wMDAwMDArMDAwMAo1NTMsSlZCWkNQS1hIRk1VNDkxLEpWQlpDUEtYSEZNVTQ5MS1uOXdzMnRsMSwyMDE1LTAxLTEwVDE5OjA1OjE4LjAwMDAwMCswMDAwCjU1NCxKVkJaQ1BLWEhGTVU0OTEsSlZCWkNQS1hIRk1VNDkxLW45d3MydGwxLDIwMTUtMDEtMTBUMTk6MDU6MTguMDAwMDAwKzAwMDAKNjQxLEJGTkxVUklTSlhUSDY0NyxCRk5MVVJJU0pYVEg2NDctZnVjcTFlbTgsMjAxNS0wMS0xMVQxMTozNDo1MS4wMDAwMDArMDAwMAo2NDIsQkZOTFVSSVNKWFRINjQ3LEJGTkxVUklTSlhUSDY0Ny1mdWNxMWVtOCwyMDE1LTAxLTExVDExOjM0OjUxLjAwMDAwMCswMDAwCjY2MCxHQVlJQkxVQ09FREo3MzIsR0FZSUJMVUNPRURKNzMyLWdidmVtNDg1LDIwMTUtMDEtMTFUMTU6MTQ6NTYuMDAwMDAwKzAwMDAKNjYxLEdBWUlCTFVDT0VESjczMixHQVlJQkxVQ09FREo3MzItZ2J2ZW00ODUsMjAxNS0wMS0xMVQxNToxNDo1Ni4wMDAwMDArMDAwMAo3MDAsR1NRSlhJT0tZTUVBNzEyLEdTUUpYSU9LWU1FQTcxMi0ycXhudHN3YywyMDE1LTAxLTEyVDAwOjQ2OjU1LjAwMDAwMCswMDAwCjcwMSxHU1FKWElPS1lNRUE3MTIsR1NRSlhJT0tZTUVBNzEyLTJxeG50c3djLDIwMTUtMDEtMTJUMDA6NDY6NTUuMDAwMDAwKzAwMDAKODI1LE9NQ1ZVQUlLU0RUUjY1MSxPTUNWVUFJS1NEVFI2NTEtdm9rcjQ1ODIsMjAxNS0wMS0xM1QwMjozMTo1NC4wMDAwMDArMDAwMAo4MjYsT01DVlVBSUtTRFRSNjUxLE9NQ1ZVQUlLU0RUUjY1MS12b2tyNDU4MiwyMDE1LTAxLTEzVDAyOjMxOjU0LjAwMDAwMCswMDAwCjkzMCxIRFNBTVBUT0xCV0M0MzgsSERTQU1QVE9MQldDNDM4LWFpNG02amNoLDIwMTUtMDEtMTRUMDE6MzI6MDIuMDAwMDAwKzAwMDAKOTMxLEhEU0FNUFRPTEJXQzQzOCxIRFNBTVBUT0xCV0M0MzgtYWk0bTZqY2gsMjAxNS0wMS0xNFQwMTozMjowMi4wMDAwMDArMDAwMAoxMDIwLEdBWUlCTFVDT0VESjczMixHQVlJQkxVQ09FREo3MzItbHBrdXdncjQsMjAxNS0wMS0xNFQxNDo1OToyMC4wMDAwMDArMDAwMAoxMDIxLEdBWUlCTFVDT0VESjczMixHQVlJQkxVQ09FREo3MzItbHBrdXdncjQsMjAxNS0wMS0xNFQxNDo1OToyMC4wMDAwMDArMDAwMAoxMDIzLEdBWUlCTFVDT0VESjczMixHQVlJQkxVQ09FREo3MzItbHBrdXdncjQsMjAxNS0wMS0xNFQxNToxMjowMi4wMDAwMDArMDAwMAoxMDI0LEdBWUlCTFVDT0VESjczMixHQVlJQkxVQ09FREo3MzItbHBrdXdncjQsMjAxNS0wMS0xNFQxNToxMjowMi4wMDAwMDArMDAwMAoxMjkxLFpQVElITlNWRllBUTE0NixaUFRJSE5TVkZZQVExNDYtdThjNG5xNzUsMjAxNS0wMS0xNlQxMjozMToyMy4wMDAwMDArMDAwMAoxMjkyLFpQVElITlNWRllBUTE0NixaUFRJSE5TVkZZQVExNDYtdThjNG5xNzUsMjAxNS0wMS0xNlQxMjozMToyMy4wMDAwMDArMDAwMAo=" download="extract_0008.csv"><button style="background-color: #67C2DC; color: #FFFFFF; border: none; padding: 5px; font-weight: bold; cursor: pointer; border-radius: 4px;">CSV</button></a></td></p>
  </tr>
  <tr>
    <td style="height: 40px; background-color: #4CA64C; color: transparent;font-size: 0px;" class="gt_row gt_left">#4CA64C</td>
    <td style="height: 40px; color: #666666;font-size: 13px;font-weight: bold;" class="gt_row gt_right">9</td>
    <td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_left">
        <div style="margin: 0; padding: 0; display: inline-block; height: 30px; vertical-align: middle; width: 16%;">
            <!--?xml version="1.0" encoding="UTF-8"?--><?xml version="1.0" encoding="UTF-8"?>
<svg width="30px" height="30px" viewBox="0 0 67 67" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <title>row_count_match</title>
    <g id="Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="row_count_match" transform="translate(0.000000, 0.793103)">
            <path d="M56.712234,1.01466935 C59.1975153,1.01466935 61.4475153,2.02202867 63.076195,3.65070832 C64.7048747,5.27938798 65.712234,7.52938798 65.712234,10.0146694 L65.712234,10.0146694 L65.712234,65.0146694 L10.712234,65.0146694 C8.22695259,65.0146694 5.97695259,64.00731 4.34827294,62.3786304 C2.71959328,60.7499507 1.71223397,58.4999507 1.71223397,56.0146694 L1.71223397,56.0146694 L1.71223397,10.0146694 C1.71223397,7.52938798 2.71959328,5.27938798 4.34827294,3.65070832 C5.97695259,2.02202867 8.22695259,1.01466935 10.712234,1.01466935 L10.712234,1.01466935 Z" id="rectangle" stroke="#000000" stroke-width="2" fill="#FFFFFF"></path>
            <path d="M29.1646149,28.4853306 L29.1646149,69.4853306 L27.0549084,69.4850493 C26.9296179,69.4826944 26.6295085,69.4606645 26.4163708,69.2548765 C26.2882481,69.1311718 26.212234,68.9348269 26.212234,68.6519973 L26.212234,68.6519973 L26.212234,29.318664 C26.212234,29.0358344 26.2882481,28.8394895 26.4163708,28.7157848 C26.6561507,28.4842733 27.0060041,28.4853306 27.0931863,28.4853306 L29.1646149,28.4853306 Z M35.1599393,28.4853306 L35.1599393,69.4853306 L32.2645286,69.4853306 L32.2645286,28.4853306 L35.1599393,28.4853306 Z M40.3593475,28.4857507 C40.4733953,28.488728 40.76682,28.5048146 40.9853552,28.6949451 C41.1008215,28.7954034 41.1819999,28.9513684 41.2051776,29.174832 L41.2051776,29.174832 L41.212234,68.6519973 C41.212234,68.9309833 41.1385277,69.1258369 41.0132803,69.2498094 C40.7943074,69.4665535 40.478047,69.4818787 40.3594139,69.4849106 L40.3594139,69.4849106 L38.259853,69.4852498 L38.259853,28.4854114 Z" id="rows_two" stroke="#000000" fill-rule="nonzero" transform="translate(33.712234, 48.985331) rotate(-90.000000) translate(-33.712234, -48.985331) "></path>
            <g id="vertical_equal" transform="translate(30.000000, 29.380570)" stroke="#000000" stroke-linecap="square">
                <line x1="2.21223397" y1="0.514669353" x2="2.21223397" y2="7.58573716" id="Line"></line>
                <line x1="5.21223397" y1="0.514669353" x2="5.21223397" y2="7.58573716" id="Line"></line>
            </g>
            <path d="M27.0931863,-2.98533065 C26.8836625,-2.98533065 25.712234,-2.93533065 25.712234,-1.65199731 L25.712234,37.681336 C25.712234,38.9646694 26.8836625,39.0146694 27.0931863,39.0146694 L29.6646149,39.0146694 L29.6646149,-2.98533065 L27.0931863,-2.98533065 Z M35.6721771,-2.98533065 L35.6721771,39.0146694 L31.7522908,39.0146694 L31.7522908,39.0146694 L31.7522908,-2.98533065 L31.7522908,-2.98533065 L35.6721771,-2.98533065 Z M40.3656149,-2.9849096 C40.6448786,-2.97823698 41.712234,-2.87699731 41.712234,-1.65199731 L41.712234,-1.65199731 L41.712234,37.681336 C41.712234,38.9646694 40.5408054,39.0146694 40.3312816,39.0146694 L40.3312816,39.0146694 L37.759853,39.0146694 L37.759853,-2.98533065 Z" id="rows_one" fill="#000000" fill-rule="nonzero" transform="translate(33.712234, 18.014669) rotate(-90.000000) translate(-33.712234, -18.014669) "></path>
        </g>
    </g>
</svg>
        </div>
        <div style="font-family: 'IBM Plex Mono', monospace, courier; color: black; font-size: 11px; display: inline-block; vertical-align: middle;">
            <div>row_count_match()</div>
        </div>
<pre><code>    &lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;&amp;mdash;&lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;2000&lt;/td&gt;
&lt;td style=&quot;height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;&quot; class=&quot;gt_row gt_center&quot;&gt;&lt;svg width=&quot;25px&quot; height=&quot;25px&quot; viewBox=&quot;0 0 25 25&quot; version=&quot;1.1&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot; style=&quot;vertical-align: middle;&quot;&gt;
&lt;g id=&quot;unchanged&quot; stroke=&quot;none&quot; stroke-width=&quot;1&quot; fill=&quot;none&quot; fill-rule=&quot;evenodd&quot;&gt;
    &lt;g id=&quot;unchanged&quot; transform=&quot;translate(0.500000, 0.570147)&quot;&gt;
        &lt;rect id=&quot;Rectangle&quot; x=&quot;0.125132506&quot; y=&quot;0&quot; width=&quot;23.749735&quot; height=&quot;23.7894737&quot;&gt;&lt;/rect&gt;
        &lt;path d=&quot;M5.80375046,8.18194736 C3.77191832,8.18194736 2.11875046,9.83495328 2.11875046,11.8669474 C2.11875046,13.8989414 3.77191832,15.5519474 5.80375046,15.5519474 C7.8355826,15.5519474 9.48875046,13.8989414 9.48875046,11.8669474 C9.48875046,9.83495328 7.83552863,8.18194736 5.80375046,8.18194736 Z M5.80375046,14.814915 C4.17821997,14.814915 2.85578285,13.4924778 2.85578285,11.8669474 C2.85578285,10.2414169 4.17821997,8.91897975 5.80375046,8.91897975 C7.42928095,8.91897975 8.75171807,10.2414169 8.75171807,11.8669474 C8.75171807,13.4924778 7.42928095,14.814915 5.80375046,14.814915 Z&quot; id=&quot;Shape&quot; fill=&quot;#000000&quot; fill-rule=&quot;nonzero&quot;&gt;&lt;/path&gt;
        &lt;path d=&quot;M13.9638189,8.699335 C13.9364621,8.70430925 13.9091059,8.71176968 13.8842359,8.71923074 C13.7822704,8.73663967 13.6877654,8.77643115 13.6056956,8.83860518 L10.2433156,11.3852598 C10.0766886,11.5046343 9.97720993,11.6986181 9.97720993,11.9025491 C9.97720993,12.1064807 10.0766886,12.3004639 10.2433156,12.4198383 L13.6056956,14.966493 C13.891697,15.1803725 14.2970729,15.1231721 14.5109517,14.8371707 C14.7248313,14.5511692 14.6676309,14.145794 14.3816294,13.9319145 L12.5313257,12.5392127 L21.8812495,12.5392127 L21.8812495,11.2658854 L12.5313257,11.2658854 L14.3816294,9.87318364 C14.6377872,9.71650453 14.7497006,9.40066014 14.6477351,9.11714553 C14.5482564,8.83363156 14.262255,8.65954352 13.9638189,8.699335 Z&quot; id=&quot;arrow&quot; fill=&quot;#000000&quot; transform=&quot;translate(15.929230, 11.894737) rotate(-180.000000) translate(-15.929230, -11.894737) &quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
&lt;/g&gt;
</code></pre>
<p></svg></td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color:#4CA64C;">✓</span></td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_right">1</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">1<br />1.00</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">0<br />0.00</td>
<td style="height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color: #AAAAAA;">○</span></td>
<td style="height: 40px; background-color: #FCFCFC;" class="gt_row gt_center"><span style="color: #EBBC14;">○</span></td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color: #FF3300;">○</span></td>
<td style="height: 40px;" class="gt_row gt_center">—</td></p>
  </tr>
  <tr>
    <td style="height: 40px; background-color: #4CA64C; color: transparent;font-size: 0px;" class="gt_row gt_left">#4CA64C</td>
    <td style="height: 40px; color: #666666;font-size: 13px;font-weight: bold;" class="gt_row gt_right">10</td>
    <td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_left">
        <div style="margin: 0; padding: 0; display: inline-block; height: 30px; vertical-align: middle; width: 16%;">
            <!--?xml version="1.0" encoding="UTF-8"?--><?xml version="1.0" encoding="UTF-8"?>
<svg width="30px" height="30px" viewBox="0 0 67 67" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <title>col_exists</title>
    <g id="Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="col_exists" transform="translate(0.000000, 0.827586)">
            <path d="M56.712234,1.01466935 C59.1975153,1.01466935 61.4475153,2.02202867 63.076195,3.65070832 C64.7048747,5.27938798 65.712234,7.52938798 65.712234,10.0146694 L65.712234,10.0146694 L65.712234,65.0146694 L10.712234,65.0146694 C8.22695259,65.0146694 5.97695259,64.00731 4.34827294,62.3786304 C2.71959328,60.7499507 1.71223397,58.4999507 1.71223397,56.0146694 L1.71223397,56.0146694 L1.71223397,10.0146694 C1.71223397,7.52938798 2.71959328,5.27938798 4.34827294,3.65070832 C5.97695259,2.02202867 8.22695259,1.01466935 10.712234,1.01466935 L10.712234,1.01466935 Z" id="rectangle" stroke="#000000" stroke-width="2" fill="#FFFFFF"></path>
            <rect id="column" fill="#000000" x="12.2117153" y="12.0146694" width="20" height="42" rx="1"></rect>
            <path d="M44.3177114,43.0146694 L44.3177114,40.5136928 L46.818688,40.5136928 L46.818688,43.0146694 L44.3177114,43.0146694 Z M44.3177114,38.0000209 L44.3177114,37.314474 C44.3177114,35.6979295 44.9397755,34.178739 46.1839224,32.7568569 L46.9837271,31.830099 C48.3125097,30.3066539 48.9768911,29.058294 48.9768911,28.0849819 C48.9768911,27.3317229 48.6849019,26.7350492 48.1009146,26.2949428 C47.5169273,25.8548364 46.7298258,25.6347865 45.7395864,25.6347865 C44.4446581,25.6347865 43.0693463,25.9479345 41.6136099,26.5742397 L41.6136099,24.4541225 C43.1793729,23.9801618 44.643551,23.743185 46.006188,23.743185 C47.7327591,23.743185 49.1038392,24.1303881 50.1194692,24.9048061 C51.1350993,25.679224 51.6429067,26.7265768 51.6429067,28.0468959 C51.6429067,28.7916913 51.4969121,29.4327982 51.2049185,29.9702358 C50.9129248,30.5076733 50.3522208,31.1699389 49.5227896,31.9570522 L48.7356802,32.6933803 C47.9485669,33.4381757 47.432296,34.0623556 47.1868521,34.5659389 C46.9414081,35.0695221 46.818688,35.7487146 46.818688,36.6035365 L46.818688,38.0000209 L44.3177114,38.0000209 Z" id="?" fill="#000000"></path>
        </g>
    </g>
</svg>
        </div>
        <div style="font-family: 'IBM Plex Mono', monospace, courier; color: black; font-size: 11px; display: inline-block; vertical-align: middle;">
            <div>col_exists()</div>
        </div>
<pre><code>    &lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;start_day&lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;&amp;mdash;&lt;/td&gt;
&lt;td style=&quot;height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;&quot; class=&quot;gt_row gt_center&quot;&gt;&lt;svg width=&quot;25px&quot; height=&quot;25px&quot; viewBox=&quot;0 0 25 25&quot; version=&quot;1.1&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot; style=&quot;vertical-align: middle;&quot;&gt;
&lt;g id=&quot;unchanged&quot; stroke=&quot;none&quot; stroke-width=&quot;1&quot; fill=&quot;none&quot; fill-rule=&quot;evenodd&quot;&gt;
    &lt;g id=&quot;unchanged&quot; transform=&quot;translate(0.500000, 0.570147)&quot;&gt;
        &lt;rect id=&quot;Rectangle&quot; x=&quot;0.125132506&quot; y=&quot;0&quot; width=&quot;23.749735&quot; height=&quot;23.7894737&quot;&gt;&lt;/rect&gt;
        &lt;path d=&quot;M5.80375046,8.18194736 C3.77191832,8.18194736 2.11875046,9.83495328 2.11875046,11.8669474 C2.11875046,13.8989414 3.77191832,15.5519474 5.80375046,15.5519474 C7.8355826,15.5519474 9.48875046,13.8989414 9.48875046,11.8669474 C9.48875046,9.83495328 7.83552863,8.18194736 5.80375046,8.18194736 Z M5.80375046,14.814915 C4.17821997,14.814915 2.85578285,13.4924778 2.85578285,11.8669474 C2.85578285,10.2414169 4.17821997,8.91897975 5.80375046,8.91897975 C7.42928095,8.91897975 8.75171807,10.2414169 8.75171807,11.8669474 C8.75171807,13.4924778 7.42928095,14.814915 5.80375046,14.814915 Z&quot; id=&quot;Shape&quot; fill=&quot;#000000&quot; fill-rule=&quot;nonzero&quot;&gt;&lt;/path&gt;
        &lt;path d=&quot;M13.9638189,8.699335 C13.9364621,8.70430925 13.9091059,8.71176968 13.8842359,8.71923074 C13.7822704,8.73663967 13.6877654,8.77643115 13.6056956,8.83860518 L10.2433156,11.3852598 C10.0766886,11.5046343 9.97720993,11.6986181 9.97720993,11.9025491 C9.97720993,12.1064807 10.0766886,12.3004639 10.2433156,12.4198383 L13.6056956,14.966493 C13.891697,15.1803725 14.2970729,15.1231721 14.5109517,14.8371707 C14.7248313,14.5511692 14.6676309,14.145794 14.3816294,13.9319145 L12.5313257,12.5392127 L21.8812495,12.5392127 L21.8812495,11.2658854 L12.5313257,11.2658854 L14.3816294,9.87318364 C14.6377872,9.71650453 14.7497006,9.40066014 14.6477351,9.11714553 C14.5482564,8.83363156 14.262255,8.65954352 13.9638189,8.699335 Z&quot; id=&quot;arrow&quot; fill=&quot;#000000&quot; transform=&quot;translate(15.929230, 11.894737) rotate(-180.000000) translate(-15.929230, -11.894737) &quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
&lt;/g&gt;
</code></pre>
<p></svg></td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color:#4CA64C;">✓</span></td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_right">1</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">1<br />1.00</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">0<br />0.00</td>
<td style="height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color: #AAAAAA;">○</span></td>
<td style="height: 40px; background-color: #FCFCFC;" class="gt_row gt_center"><span style="color: #EBBC14;">○</span></td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color: #FF3300;">○</span></td>
<td style="height: 40px;" class="gt_row gt_center">—</td></p>
  </tr>
</tbody>
  <tfoot class="gt_sourcenotes">
  <tr>
    <td class="gt_sourcenote" colspan="14" style="text-align: left;"><div style='margin-top: 5px; margin-bottom: 5px;'><span style='background-color: #FFF; color: #444; padding: 0.5em 0.5em; position: inherit; text-transform: uppercase; margin-left: 10px; margin-right: 5px; border: solid 1px #999999; font-variant-numeric: tabular-nums; border-radius: 0; padding: 2px 10px 2px 10px;'>2026-04-02 19:07:32 UTC</span><span style='background-color: #FFF; color: #444; padding: 0.5em 0.5em; position: inherit; margin-right: 5px; border: solid 1px #999999; font-variant-numeric: tabular-nums; border-radius: 0; padding: 2px 10px 2px 10px;'>< 1 s</span><span style='background-color: #FFF; color: #444; padding: 0.5em 0.5em; position: inherit; text-transform: uppercase; margin: 5px 1px 5px -1px; border: solid 1px #999999; font-variant-numeric: tabular-nums; border-radius: 0; padding: 2px 10px 2px 10px;'>2026-04-02 19:07:32 UTC</span></div></td>
  </tr>
  <tr>
    <td class="gt_sourcenote" colspan="14" style="text-align: left;"><hr style='border: none; border-top-width: 1px; border-top-style: dotted; border-top-color: #B5B5B5; margin-top: -3px; margin-bottom: 3px;'>
<strong>Notes</strong>
<p><span style='font-variant: small-caps; font-weight: bold; font-size: smaller; text-transform: uppercase; color: #333333;'>Step 7</span> <span style='font-family: "IBM Plex Mono", monospace; font-size: smaller;'>(pre_applied)</span> Precondition applied: table dimensions <span style="font-family: monospace;">[2,000 rows, 11 columns]</span> → <span style="font-family: monospace;">[<strong>1</strong> row, <strong>1</strong> column]</span>.</td>
  </tr>
</tfoot>
</table>
</div>
<p>This data validation makes use of the many
<a href="https://posit-dev.github.io/pointblank/reference/#validation-steps" target="_blank" rel="noopener">validation methods available in the library</a>
.
Because thresholds have been set at the <code>Validate(thresholds=)</code> parameter, we can now see where
certain validation steps have greater amounts of failures. Any validation steps with green
indicators passed with flying colors, whereas: (1) gray indicates the &lsquo;warning&rsquo; condition was met
(at least one test unit failing), (2) yellow is for the &rsquo;error&rsquo; condition (20 or more test units
failing), and (3) red means &lsquo;critical&rsquo; and that&rsquo;s tripped when 10% of all test units are failing
ones.</p>
<p>Reporting tables are essential to the package and they help communicate what went wrong (or well) in
a validation workflow. Now let&rsquo;s look at some additional reporting that Pointblank can give you to
better understand <em>where</em> things might&rsquo;ve gone wrong.</p>
<h2 id="reporting-for-individual-validation-steps">Reporting for Individual Validation Steps
</h2>
<p>The second validation step of the previous data validation showed 18 failing test units. That
translates to 18 spots in a 2,000 row DataFrame where a data quality assertion failed. We often
would like to know exactly what that failing data is; it&rsquo;s usually the next step toward addressing
data quality issues.</p>
<p>Pointblank offers a method that gives you a tabular report on a specific step:
<a href="https://posit-dev.github.io/pointblank/reference/Validate.get_step_report.html" target="_blank" rel="noopener"><code>get_step_report()</code></a>
.
The previous tables you&rsquo;ve seen (the validation report table) dealt with providing a summary of all
validation steps. In contrast, a focused report on a single step can help to get to the heart of a data
quality issue. Here&rsquo;s how that looks for Step 2:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">validation_2</span><span class="o">.</span><span class="n">get_step_report</span><span class="p">(</span><span class="n">i</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div id="pb_preview_tbl" style="padding-left:0px;padding-right:0px;padding-top:10px;padding-bottom:10px;overflow-x:auto;overflow-y:auto;width:auto;height:auto;">
<style>
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono&display=swap');
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans&display=swap');
#pb_preview_tbl table {
          font-family: 'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Helvetica Neue', 'Fira Sans', 'Droid Sans', Arial, sans-serif;
          -webkit-font-smoothing: antialiased;
          -moz-osx-font-smoothing: grayscale;
        }
<p>#pb_preview_tbl thead, tbody, tfoot, tr, td, th { border-style: none; }
tr { background-color: transparent; }
#pb_preview_tbl p { margin: 0; padding: 0; }
#pb_preview_tbl .gt_table { display: table; border-collapse: collapse; line-height: normal; margin-left: auto; margin-right: auto; color: #333333; font-size: 16px; font-weight: normal; font-style: normal; background-color: #FFFFFF; width: auto; border-top-style: solid; border-top-width: 2px; border-top-color: #A8A8A8; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #A8A8A8; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; }
#pb_preview_tbl .gt_caption { padding-top: 4px; padding-bottom: 4px; }
#pb_preview_tbl .gt_title { color: #333333; font-size: 125%; font-weight: initial; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; border-bottom-color: #FFFFFF; border-bottom-width: 0; }
#pb_preview_tbl .gt_subtitle { color: #333333; font-size: 85%; font-weight: initial; padding-top: 3px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; border-top-color: #FFFFFF; border-top-width: 0; }
#pb_preview_tbl .gt_heading { background-color: #FFFFFF; text-align: left; border-bottom-color: #FFFFFF; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; }
#pb_preview_tbl .gt_bottom_border { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; }
#pb_preview_tbl .gt_col_headings { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; }
#pb_preview_tbl .gt_col_heading { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; border-left-style: solid; border-left-width: 1px; border-left-color: #F2F2F2; border-right-style: solid; border-right-width: 1px; border-right-color: #F2F2F2; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; overflow-x: hidden; }
#pb_preview_tbl .gt_column_spanner_outer { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; padding-top: 0; padding-bottom: 0; padding-left: 4px; padding-right: 4px; }
#pb_preview_tbl .gt_column_spanner_outer:first-child { padding-left: 0; }
#pb_preview_tbl .gt_column_spanner_outer:last-child { padding-right: 0; }
#pb_preview_tbl .gt_column_spanner { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; overflow-x: hidden; display: inline-block; width: 100%; }
#pb_preview_tbl .gt_spanner_row { border-bottom-style: hidden; }
#pb_preview_tbl .gt_group_heading { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; text-align: left; }
#pb_preview_tbl .gt_empty_group_heading { padding: 0.5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: middle; }
#pb_preview_tbl .gt_from_md&gt; :first-child { margin-top: 0; }
#pb_preview_tbl .gt_from_md&gt; :last-child { margin-bottom: 0; }
#pb_preview_tbl .gt_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; margin: 10px; border-top-style: solid; border-top-width: 1px; border-top-color: #D3D3D3; border-left-style: solid; border-left-width: 1px; border-left-color: #E9E9E9; border-right-style: solid; border-right-width: 1px; border-right-color: #E9E9E9; vertical-align: middle; overflow-x: hidden; }
#pb_preview_tbl .gt_stub { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; }
#pb_preview_tbl .gt_stub_row_group { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; vertical-align: top; }
#pb_preview_tbl .gt_row_group_first td { border-top-width: 2px; }
#pb_preview_tbl .gt_row_group_first th { border-top-width: 2px; }
#pb_preview_tbl .gt_striped { color: #333333; background-color: #F4F4F4; }
#pb_preview_tbl .gt_table_body { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; }
#pb_preview_tbl .gt_grand_summary_row { color: #333333; background-color: #FFFFFF; text-transform: inherit; padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; }
#pb_preview_tbl .gt_first_grand_summary_row_bottom { border-top-style: double; border-top-width: 6px; border-top-color: #D3D3D3; }
#pb_preview_tbl .gt_last_grand_summary_row_top { border-bottom-style: double; border-bottom-width: 6px; border-bottom-color: #D3D3D3; }
#pb_preview_tbl .gt_sourcenotes { color: #333333; background-color: #FFFFFF; border-bottom-style: none; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; }
#pb_preview_tbl .gt_sourcenote { font-size: 90%; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; text-align: left; }
#pb_preview_tbl .gt_left { text-align: left; }
#pb_preview_tbl .gt_center { text-align: center; }
#pb_preview_tbl .gt_right { text-align: right; font-variant-numeric: tabular-nums; }
#pb_preview_tbl .gt_font_normal { font-weight: normal; }
#pb_preview_tbl .gt_font_bold { font-weight: bold; }
#pb_preview_tbl .gt_font_italic { font-style: italic; }
#pb_preview_tbl .gt_super { font-size: 65%; }
#pb_preview_tbl .gt_footnote_marks { font-size: 75%; vertical-align: 0.4em; position: initial; }
#pb_preview_tbl .gt_asterisk { font-size: 100%; vertical-align: 0; }</p>
<p></style></p>
<table style="table-layout: fixed;; width: 0px" class="gt_table" data-quarto-disable-processing="true" data-quarto-bootstrap="false">
<colgroup>
  <col style="width:41.2px;"/>
  <col style="width:127px;"/>
  <col style="width:197px;"/>
  <col style="width:205px;"/>
  <col style="width:205px;"/>
  <col style="width:80px;"/>
  <col style="width:80px;"/>
  <col style="width:104px;"/>
  <col style="width:135px;"/>
  <col style="width:88px;"/>
  <col style="width:119px;"/>
  <col style="width:96px;"/>
</colgroup>
<thead>
  <tr class="gt_heading">
    <td colspan="12" class="gt_heading gt_title gt_font_normal">Report for Validation Step 2<div style='font-size: 13.6px; '><div style='padding-top: 7px;'>ASSERTION <span style='border-style: solid; border-width: thin; border-color: lightblue; padding-left: 2px; padding-right: 2px;'><code style='color: #303030; background-color: transparent; position: relative; bottom: 1px;'><code style='color: #303030; font-family: monospace; font-size: smaller;'>session_duration > 5</code></code></span></div><div style='padding-top: 7px;'><strong>18</strong> / <strong>2000</strong> TEST UNIT FAILURES IN COLUMN <strong>8</strong> </div><div>EXTRACT OF FIRST <strong>10</strong> ROWS (WITH <span style='color: #B22222;'>TEST UNIT FAILURES IN RED</span>):</div></div></td>
  </tr>
<tr class="gt_col_headings">
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" style="color: gray20;font-family: IBM Plex Mono;font-size: 12px;" scope="col" id="pb_preview_tbl-_row_num_"></th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" style="color: gray20;font-family: IBM Plex Mono;font-size: 12px;" scope="col" id="pb_preview_tbl-player_id"><div><div style='white-space: nowrap; text-overflow: ellipsis; overflow: hidden; padding-bottom: 2px; margin-bottom: 2px;'>player_id</div><div style='white-space: nowrap; text-overflow: ellipsis; overflow: hidden; padding-top: 2px; margin-top: 2px;'><em>String</em></div></div></th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" style="color: gray20;font-family: IBM Plex Mono;font-size: 12px;" scope="col" id="pb_preview_tbl-session_id"><div><div style='white-space: nowrap; text-overflow: ellipsis; overflow: hidden; padding-bottom: 2px; margin-bottom: 2px;'>session_id</div><div style='white-space: nowrap; text-overflow: ellipsis; overflow: hidden; padding-top: 2px; margin-top: 2px;'><em>String</em></div></div></th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" style="color: gray20;font-family: IBM Plex Mono;font-size: 12px;" scope="col" id="pb_preview_tbl-session_start"><div><div style='white-space: nowrap; text-overflow: ellipsis; overflow: hidden; padding-bottom: 2px; margin-bottom: 2px;'>session_start</div><div style='white-space: nowrap; text-overflow: ellipsis; overflow: hidden; padding-top: 2px; margin-top: 2px;'><em>Datetime</em></div></div></th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" style="color: gray20;font-family: IBM Plex Mono;font-size: 12px;" scope="col" id="pb_preview_tbl-time"><div><div style='white-space: nowrap; text-overflow: ellipsis; overflow: hidden; padding-bottom: 2px; margin-bottom: 2px;'>time</div><div style='white-space: nowrap; text-overflow: ellipsis; overflow: hidden; padding-top: 2px; margin-top: 2px;'><em>Datetime</em></div></div></th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" style="color: gray20;font-family: IBM Plex Mono;font-size: 12px;" scope="col" id="pb_preview_tbl-item_type"><div><div style='white-space: nowrap; text-overflow: ellipsis; overflow: hidden; padding-bottom: 2px; margin-bottom: 2px;'>item_type</div><div style='white-space: nowrap; text-overflow: ellipsis; overflow: hidden; padding-top: 2px; margin-top: 2px;'><em>String</em></div></div></th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" style="color: gray20;font-family: IBM Plex Mono;font-size: 12px;" scope="col" id="pb_preview_tbl-item_name"><div><div style='white-space: nowrap; text-overflow: ellipsis; overflow: hidden; padding-bottom: 2px; margin-bottom: 2px;'>item_name</div><div style='white-space: nowrap; text-overflow: ellipsis; overflow: hidden; padding-top: 2px; margin-top: 2px;'><em>String</em></div></div></th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" style="color: gray20;font-family: IBM Plex Mono;font-size: 12px;" scope="col" id="pb_preview_tbl-item_revenue"><div><div style='white-space: nowrap; text-overflow: ellipsis; overflow: hidden; padding-bottom: 2px; margin-bottom: 2px;'>item_revenue</div><div style='white-space: nowrap; text-overflow: ellipsis; overflow: hidden; padding-top: 2px; margin-top: 2px;'><em>Float64</em></div></div></th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" style="color: gray20;font-family: IBM Plex Mono;font-size: 12px; border-left: 2px solid black;border-right: 2px solid black;" scope="col" id="pb_preview_tbl-session_duration"><div><div style='white-space: nowrap; text-overflow: ellipsis; overflow: hidden; padding-bottom: 2px; margin-bottom: 2px;'>session_duration</div><div style='white-space: nowrap; text-overflow: ellipsis; overflow: hidden; padding-top: 2px; margin-top: 2px;'><em>Float64</em></div></div></th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" style="color: gray20;font-family: IBM Plex Mono;font-size: 12px;" scope="col" id="pb_preview_tbl-start_day"><div><div style='white-space: nowrap; text-overflow: ellipsis; overflow: hidden; padding-bottom: 2px; margin-bottom: 2px;'>start_day</div><div style='white-space: nowrap; text-overflow: ellipsis; overflow: hidden; padding-top: 2px; margin-top: 2px;'><em>Date</em></div></div></th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" style="color: gray20;font-family: IBM Plex Mono;font-size: 12px;" scope="col" id="pb_preview_tbl-acquisition"><div><div style='white-space: nowrap; text-overflow: ellipsis; overflow: hidden; padding-bottom: 2px; margin-bottom: 2px;'>acquisition</div><div style='white-space: nowrap; text-overflow: ellipsis; overflow: hidden; padding-top: 2px; margin-top: 2px;'><em>String</em></div></div></th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" style="color: gray20;font-family: IBM Plex Mono;font-size: 12px;" scope="col" id="pb_preview_tbl-country"><div><div style='white-space: nowrap; text-overflow: ellipsis; overflow: hidden; padding-bottom: 2px; margin-bottom: 2px;'>country</div><div style='white-space: nowrap; text-overflow: ellipsis; overflow: hidden; padding-top: 2px; margin-top: 2px;'><em>String</em></div></div></th>
</tr>
</thead>
<tbody class="gt_table_body">
  <tr>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E; color: gray;font-family: IBM Plex Mono;font-size: 10px; border-right: 2px solid #6699CC80;" class="gt_row gt_right">549</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">QNLVRDEOXFYJ892</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">QNLVRDEOXFYJ892-lz5fmr6k</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_right">2015-01-10 16:44:17+00:00</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_right">2015-01-10 16:45:29+00:00</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">iap</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">gold3</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_right">3.49</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E; color: #B22222; background-color: #FFC1C159; border-left: 2px solid black;border-right: 2px solid black;" class="gt_row gt_right">3.7</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_right">2015-01-09</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">crosspromo</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">Australia</td>
  </tr>
  <tr>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E; color: gray;font-family: IBM Plex Mono;font-size: 10px; border-right: 2px solid #6699CC80;" class="gt_row gt_right">620</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">RMOSWHJGELCI675</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">RMOSWHJGELCI675-t4y8bjcu</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_right">2015-01-11 07:24:24+00:00</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_right">2015-01-11 07:25:18+00:00</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">iap</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">offer4</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_right">17.991</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E; color: #B22222; background-color: #FFC1C159; border-left: 2px solid black;border-right: 2px solid black;" class="gt_row gt_right">5.0</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_right">2015-01-10</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">other_campaign</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">France</td>
  </tr>
  <tr>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E; color: gray;font-family: IBM Plex Mono;font-size: 10px; border-right: 2px solid #6699CC80;" class="gt_row gt_right">621</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">RMOSWHJGELCI675</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">RMOSWHJGELCI675-t4y8bjcu</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_right">2015-01-11 07:24:24+00:00</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_right">2015-01-11 07:26:24+00:00</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">iap</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">offer5</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_right">26.09</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E; color: #B22222; background-color: #FFC1C159; border-left: 2px solid black;border-right: 2px solid black;" class="gt_row gt_right">5.0</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_right">2015-01-10</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">other_campaign</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">France</td>
  </tr>
  <tr>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E; color: gray;font-family: IBM Plex Mono;font-size: 10px; border-right: 2px solid #6699CC80;" class="gt_row gt_right">622</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">RMOSWHJGELCI675</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">RMOSWHJGELCI675-t4y8bjcu</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_right">2015-01-11 07:24:24+00:00</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_right">2015-01-11 07:28:36+00:00</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">ad</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">ad_15sec</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_right">0.53</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E; color: #B22222; background-color: #FFC1C159; border-left: 2px solid black;border-right: 2px solid black;" class="gt_row gt_right">5.0</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_right">2015-01-10</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">other_campaign</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">France</td>
  </tr>
  <tr>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E; color: gray;font-family: IBM Plex Mono;font-size: 10px; border-right: 2px solid #6699CC80;" class="gt_row gt_right">663</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">GFLYJHAPMZWD631</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">GFLYJHAPMZWD631-i2v1bl7a</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_right">2015-01-11 16:13:24+00:00</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_right">2015-01-11 16:14:54+00:00</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">iap</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">gems2</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_right">3.99</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E; color: #B22222; background-color: #FFC1C159; border-left: 2px solid black;border-right: 2px solid black;" class="gt_row gt_right">3.6</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_right">2015-01-09</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">organic</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">India</td>
  </tr>
  <tr>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E; color: gray;font-family: IBM Plex Mono;font-size: 10px; border-right: 2px solid #6699CC80;" class="gt_row gt_right">772</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">BFNLURISJXTH647</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">BFNLURISJXTH647-6o5hx27z</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_right">2015-01-12 17:37:39+00:00</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_right">2015-01-12 17:39:27+00:00</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">iap</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">offer5</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_right">11.59</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E; color: #B22222; background-color: #FFC1C159; border-left: 2px solid black;border-right: 2px solid black;" class="gt_row gt_right">4.1</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_right">2015-01-10</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">organic</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">India</td>
  </tr>
  <tr>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E; color: gray;font-family: IBM Plex Mono;font-size: 10px; border-right: 2px solid #6699CC80;" class="gt_row gt_right">773</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">BFNLURISJXTH647</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">BFNLURISJXTH647-6o5hx27z</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_right">2015-01-12 17:37:39+00:00</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_right">2015-01-12 17:41:45+00:00</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">iap</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">gems3</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_right">9.99</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E; color: #B22222; background-color: #FFC1C159; border-left: 2px solid black;border-right: 2px solid black;" class="gt_row gt_right">4.1</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_right">2015-01-10</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">organic</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">India</td>
  </tr>
  <tr>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E; color: gray;font-family: IBM Plex Mono;font-size: 10px; border-right: 2px solid #6699CC80;" class="gt_row gt_right">908</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">KILWZYHRSJEG316</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">KILWZYHRSJEG316-uke7dhqj</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_right">2015-01-13 22:16:29+00:00</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_right">2015-01-13 22:17:35+00:00</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">iap</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">offer2</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_right">10.99</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E; color: #B22222; background-color: #FFC1C159; border-left: 2px solid black;border-right: 2px solid black;" class="gt_row gt_right">3.2</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_right">2015-01-04</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">organic</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">Denmark</td>
  </tr>
  <tr>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E; color: gray;font-family: IBM Plex Mono;font-size: 10px; border-right: 2px solid #6699CC80;" class="gt_row gt_right">1037</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">JUBDVFHCNQWT198</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">JUBDVFHCNQWT198-9h4xs2pb</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_right">2015-01-14 16:08:25+00:00</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_right">2015-01-14 16:08:43+00:00</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">iap</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">offer5</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_right">8.69</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E; color: #B22222; background-color: #FFC1C159; border-left: 2px solid black;border-right: 2px solid black;" class="gt_row gt_right">3.3</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_right">2015-01-14</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">organic</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E;" class="gt_row gt_left">Philippines</td>
  </tr>
  <tr>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E; border-bottom: 2px solid #6699CC80; color: gray;font-family: IBM Plex Mono;font-size: 10px; border-right: 2px solid #6699CC80;" class="gt_row gt_right">1038</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E; border-bottom: 2px solid #6699CC80;" class="gt_row gt_left">JUBDVFHCNQWT198</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E; border-bottom: 2px solid #6699CC80;" class="gt_row gt_left">JUBDVFHCNQWT198-9h4xs2pb</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E; border-bottom: 2px solid #6699CC80;" class="gt_row gt_right">2015-01-14 16:08:25+00:00</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E; border-bottom: 2px solid #6699CC80;" class="gt_row gt_right">2015-01-14 16:11:01+00:00</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E; border-bottom: 2px solid #6699CC80;" class="gt_row gt_left">iap</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E; border-bottom: 2px solid #6699CC80;" class="gt_row gt_left">offer4</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E; border-bottom: 2px solid #6699CC80;" class="gt_row gt_right">5.99</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E; border-bottom: 2px solid #6699CC80; color: #B22222; background-color: #FFC1C159; border-left: 2px solid black;border-right: 2px solid black;" class="gt_row gt_right">3.3</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E; border-bottom: 2px solid #6699CC80;" class="gt_row gt_right">2015-01-14</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E; border-bottom: 2px solid #6699CC80;" class="gt_row gt_left">organic</td>
    <td style="height: 14px; padding: 4px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; color: black;font-family: IBM Plex Mono;font-size: 12px; border-top: 1px solid #E9E9E;border-bottom: 1px solid #E9E9E; border-bottom: 2px solid #6699CC80;" class="gt_row gt_left">Philippines</td>
  </tr>
</tbody>
</table>
</div>
<p>This report provides the 18 rows where the failure occurred. If you scroll the table to the right
you&rsquo;ll see the column that underwent testing (<code>session_duration</code>) is highlighted in red. All of
these values are <code>5.0</code> or less, which is in violation of the assertion (in the header) that
<code>session_duration &gt; 5</code>.</p>
<p>These types of bespoke reports are useful for finding a needle in a haystack. Another good use for
a step report is when validating a table schema. Using the
<a href="https://posit-dev.github.io/pointblank/reference/Validate.col_schema_match.html" target="_blank" rel="noopener"><code>col_schema_match()</code></a>

validation method with a table schema prepared with the
<a href="https://posit-dev.github.io/pointblank/reference/Schema.html" target="_blank" rel="noopener"><code>Schema</code></a>
 class allows us to verify
our understanding of the table structure. Here is a validation that performs a schema validation
with the <code>small_table</code> dataset prepared as a DuckDB table:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">pointblank</span> <span class="k">as</span> <span class="nn">pb</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Create a schema for the target table (`small_table` as a DuckDB table)</span>
</span></span><span class="line"><span class="cl"><span class="n">schema</span> <span class="o">=</span> <span class="n">pb</span><span class="o">.</span><span class="n">Schema</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">columns</span><span class="o">=</span><span class="p">[</span>
</span></span><span class="line"><span class="cl">        <span class="p">(</span><span class="s2">&#34;date_time&#34;</span><span class="p">,</span> <span class="s2">&#34;timestamp(6)&#34;</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">        <span class="p">(</span><span class="s2">&#34;dates&#34;</span><span class="p">,</span> <span class="s2">&#34;date&#34;</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">        <span class="p">(</span><span class="s2">&#34;a&#34;</span><span class="p">,</span> <span class="s2">&#34;int64&#34;</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">        <span class="p">(</span><span class="s2">&#34;b&#34;</span><span class="p">,),</span>
</span></span><span class="line"><span class="cl">        <span class="p">(</span><span class="s2">&#34;c&#34;</span><span class="p">,),</span>
</span></span><span class="line"><span class="cl">        <span class="p">(</span><span class="s2">&#34;d&#34;</span><span class="p">,</span> <span class="s2">&#34;float64&#34;</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">        <span class="p">(</span><span class="s2">&#34;e&#34;</span><span class="p">,</span> <span class="p">[</span><span class="s2">&#34;bool&#34;</span><span class="p">,</span> <span class="s2">&#34;boolean&#34;</span><span class="p">]),</span>
</span></span><span class="line"><span class="cl">        <span class="p">(</span><span class="s2">&#34;f&#34;</span><span class="p">,</span> <span class="s2">&#34;str&#34;</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">    <span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Use the `col_schema_match()` validation method to perform a schema check</span>
</span></span><span class="line"><span class="cl"><span class="n">validation_3</span> <span class="o">=</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">pb</span><span class="o">.</span><span class="n">Validate</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="n">data</span><span class="o">=</span><span class="n">pb</span><span class="o">.</span><span class="n">load_dataset</span><span class="p">(</span><span class="n">dataset</span><span class="o">=</span><span class="s2">&#34;small_table&#34;</span><span class="p">,</span> <span class="n">tbl_type</span><span class="o">=</span><span class="s2">&#34;duckdb&#34;</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">        <span class="n">tbl_name</span><span class="o">=</span><span class="s2">&#34;small_table&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="n">label</span><span class="o">=</span><span class="s2">&#34;Schema check&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">col_schema_match</span><span class="p">(</span><span class="n">schema</span><span class="o">=</span><span class="n">schema</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="o">.</span><span class="n">interrogate</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">validation_3</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div id="pb_tbl" style="padding-left:0px;padding-right:0px;padding-top:10px;padding-bottom:10px;overflow-x:auto;overflow-y:auto;width:auto;height:auto;">
<style>
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono&display=swap');
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans&display=swap');
#pb_tbl table {
          font-family: 'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Helvetica Neue', 'Fira Sans', 'Droid Sans', Arial, sans-serif;
          -webkit-font-smoothing: antialiased;
          -moz-osx-font-smoothing: grayscale;
        }
<p>#pb_tbl thead, tbody, tfoot, tr, td, th { border-style: none; }
tr { background-color: transparent; }
#pb_tbl p { margin: 0; padding: 0; }
#pb_tbl .gt_table { display: table; border-collapse: collapse; line-height: normal; margin-left: auto; margin-right: auto; color: #333333; font-size: 90%; font-weight: normal; font-style: normal; background-color: #FFFFFF; width: auto; border-top-style: solid; border-top-width: 2px; border-top-color: #A8A8A8; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #A8A8A8; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; }
#pb_tbl .gt_caption { padding-top: 4px; padding-bottom: 4px; }
#pb_tbl .gt_title { color: #333333; font-size: 125%; font-weight: initial; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; border-bottom-color: #FFFFFF; border-bottom-width: 0; }
#pb_tbl .gt_subtitle { color: #333333; font-size: 85%; font-weight: initial; padding-top: 3px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; border-top-color: #FFFFFF; border-top-width: 0; }
#pb_tbl .gt_heading { background-color: #FFFFFF; text-align: left; border-bottom-color: #FFFFFF; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; }
#pb_tbl .gt_bottom_border { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; }
#pb_tbl .gt_col_headings { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; }
#pb_tbl .gt_col_heading { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; overflow-x: hidden; }
#pb_tbl .gt_column_spanner_outer { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; padding-top: 0; padding-bottom: 0; padding-left: 4px; padding-right: 4px; }
#pb_tbl .gt_column_spanner_outer:first-child { padding-left: 0; }
#pb_tbl .gt_column_spanner_outer:last-child { padding-right: 0; }
#pb_tbl .gt_column_spanner { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; overflow-x: hidden; display: inline-block; width: 100%; }
#pb_tbl .gt_spanner_row { border-bottom-style: hidden; }
#pb_tbl .gt_group_heading { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; text-align: left; }
#pb_tbl .gt_empty_group_heading { padding: 0.5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: middle; }
#pb_tbl .gt_from_md&gt; :first-child { margin-top: 0; }
#pb_tbl .gt_from_md&gt; :last-child { margin-bottom: 0; }
#pb_tbl .gt_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; margin: 10px; border-top-style: solid; border-top-width: 1px; border-top-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; overflow-x: hidden; }
#pb_tbl .gt_stub { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; }
#pb_tbl .gt_stub_row_group { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; vertical-align: top; }
#pb_tbl .gt_row_group_first td { border-top-width: 2px; }
#pb_tbl .gt_row_group_first th { border-top-width: 2px; }
#pb_tbl .gt_striped { color: #333333; background-color: #F4F4F4; }
#pb_tbl .gt_table_body { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; }
#pb_tbl .gt_grand_summary_row { color: #333333; background-color: #FFFFFF; text-transform: inherit; padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; }
#pb_tbl .gt_first_grand_summary_row_bottom { border-top-style: double; border-top-width: 6px; border-top-color: #D3D3D3; }
#pb_tbl .gt_last_grand_summary_row_top { border-bottom-style: double; border-bottom-width: 6px; border-bottom-color: #D3D3D3; }
#pb_tbl .gt_sourcenotes { color: #333333; background-color: #FFFFFF; border-bottom-style: none; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; }
#pb_tbl .gt_sourcenote { font-size: 90%; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; text-align: left; }
#pb_tbl .gt_left { text-align: left; }
#pb_tbl .gt_center { text-align: center; }
#pb_tbl .gt_right { text-align: right; font-variant-numeric: tabular-nums; }
#pb_tbl .gt_font_normal { font-weight: normal; }
#pb_tbl .gt_font_bold { font-weight: bold; }
#pb_tbl .gt_font_italic { font-style: italic; }
#pb_tbl .gt_super { font-size: 65%; }
#pb_tbl .gt_footnote_marks { font-size: 75%; vertical-align: 0.4em; position: initial; }
#pb_tbl .gt_asterisk { font-size: 100%; vertical-align: 0; }</p>
<p></style></p>
<table style="table-layout: fixed;; width: 0px" class="gt_table" data-quarto-disable-processing="true" data-quarto-bootstrap="false">
<colgroup>
  <col style="width:4px;"/>
  <col style="width:35px;"/>
  <col style="width:190px;"/>
  <col style="width:120px;"/>
  <col style="width:120px;"/>
  <col style="width:50px;"/>
  <col style="width:50px;"/>
  <col style="width:60px;"/>
  <col style="width:60px;"/>
  <col style="width:60px;"/>
  <col style="width:30px;"/>
  <col style="width:30px;"/>
  <col style="width:30px;"/>
  <col style="width:65px;"/>
</colgroup>
<thead>
  <tr class="gt_heading">
    <td colspan="14" class="gt_heading gt_title gt_font_normal" style="color: #444444;font-size: 28px;text-align: left;font-weight: bold; text-align: left;">Pointblank Validation</td>
  </tr>
  <tr class="gt_heading">
    <td colspan="14" class="gt_heading gt_subtitle gt_font_normal gt_bottom_border" style="text-align: left;"><div><span style='text-decoration-style: solid; text-decoration-color: #ADD8E6; text-decoration-line: underline; text-underline-position: under; color: #333333; font-variant-numeric: tabular-nums; padding-left: 4px; margin-right: 5px; padding-right: 2px;'>Schema check</span><div style="padding-top: 10px; padding-bottom: 5px;"><span style='background-color: #000000; color: #FFFFFF; padding: 0.5em 0.5em; position: inherit; text-transform: uppercase; margin: 5px 0px 5px 0px; border: solid 1px #000000; font-weight: bold; padding: 2px 15px 2px 15px; font-size: 10px;'>DuckDB</span><span style='background-color: none; color: #222222; padding: 0.5em 0.5em; position: inherit; margin: 5px 10px 5px -4px; border: solid 1px #000000; font-weight: bold; padding: 2px 15px 2px 15px; font-size: 10px;'>small_table</span></div></div></td>
  </tr>
<tr class="gt_col_headings">
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-status_color"></th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-i"></th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-type_upd">STEP</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-columns_upd">COLUMNS</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-values_upd">VALUES</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-tbl">TBL</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-eval">EVAL</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-test_units">UNITS</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-pass">PASS</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-fail">FAIL</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-w_upd">W</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-e_upd">E</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-c_upd">C</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_center" rowspan="1" colspan="1" style="color: #666666;font-weight: bold;" scope="col" id="pb_tbl-extract_upd">EXT</th>
</tr>
</thead>
<tbody class="gt_table_body">
  <tr>
    <td style="height: 40px; background-color: #4CA64C66; color: transparent;font-size: 0px;" class="gt_row gt_left">#4CA64C66</td>
    <td style="height: 40px; color: #666666;font-size: 13px;font-weight: bold;" class="gt_row gt_right">1</td>
    <td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_left">
        <div style="margin: 0; padding: 0; display: inline-block; height: 30px; vertical-align: middle; width: 16%;">
            <!--?xml version="1.0" encoding="UTF-8"?--><?xml version="1.0" encoding="UTF-8"?>
<svg width="30px" height="30px" viewBox="0 0 67 67" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <title>col_schema_match</title>
    <g id="Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="col_schema_match" transform="translate(0.000000, 0.310345)">
            <path d="M56.712234,1.01466935 C59.1975153,1.01466935 61.4475153,2.02202867 63.076195,3.65070832 C64.7048747,5.27938798 65.712234,7.52938798 65.712234,10.0146694 L65.712234,10.0146694 L65.712234,65.0146694 L10.712234,65.0146694 C8.22695259,65.0146694 5.97695259,64.00731 4.34827294,62.3786304 C2.71959328,60.7499507 1.71223397,58.4999507 1.71223397,56.0146694 L1.71223397,56.0146694 L1.71223397,10.0146694 C1.71223397,7.52938798 2.71959328,5.27938798 4.34827294,3.65070832 C5.97695259,2.02202867 8.22695259,1.01466935 10.712234,1.01466935 L10.712234,1.01466935 Z" id="rectangle" stroke="#000000" stroke-width="2" fill="#FFFFFF"></path>
            <path d="M53.712234,39.7885268 L54.212234,56.2885268 L42.212234,56.7885268 L42.212234,39.7885268 L53.712234,39.7885268 Z M39.712234,39.7885268 L39.712234,56.7885268 L27.712234,56.7885268 L27.712234,39.7885268 L39.712234,39.7885268 Z M25.212234,39.7885268 L25.212234,56.7885268 L13.712234,56.7885268 L13.212234,40.2885268 L25.212234,39.7885268 Z" id="columns_schema" stroke="#000000" fill-rule="nonzero"></path>
            <g id="vertical_equal" transform="translate(30.000000, 29.000000)" stroke="#000000" stroke-linecap="square">
                <line x1="2.21223397" y1="0.514669353" x2="2.21223397" y2="7.58573716" id="Line"></line>
                <line x1="5.21223397" y1="0.514669353" x2="5.21223397" y2="7.58573716" id="Line-Copy"></line>
            </g>
            <path d="M41.712234,9.01466935 L41.712234,27.0146694 L53.712234,27.0146694 C54.262234,27.0146694 54.712234,26.5646694 54.712234,26.0146694 L54.712234,10.0146694 C54.712234,9.46466935 54.262234,9.01466935 53.712234,9.01466935 L41.712234,9.01466935 Z M27.212234,9.01466935 C27.212234,9.01466935 27.212234,15.0146694 27.212234,27.0146694 L40.212234,27.0146694 L40.212234,9.01466935 C31.5455673,9.01466935 27.212234,9.01466935 27.212234,9.01466935 Z M13.712234,9.01466935 C13.162234,9.01466935 12.712234,9.46466935 12.712234,10.0146694 L12.712234,26.0146694 C12.712234,26.5646694 13.162234,27.0146694 13.712234,27.0146694 L25.712234,27.0146694 L25.712234,9.01466935 L13.712234,9.01466935 Z" id="columns_real" fill="#000000" fill-rule="nonzero"></path>
        </g>
    </g>
</svg>
        </div>
        <div style="font-family: 'IBM Plex Mono', monospace, courier; color: black; font-size: 10px; display: inline-block; vertical-align: middle;">
            <div>col_schema_match()</div>
        </div>
<pre><code>    &lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;&amp;mdash;&lt;/td&gt;
&lt;td style=&quot;height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;&quot; class=&quot;gt_row gt_left&quot;&gt;SCHEMA&lt;/td&gt;
&lt;td style=&quot;height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;&quot; class=&quot;gt_row gt_center&quot;&gt;&lt;svg width=&quot;25px&quot; height=&quot;25px&quot; viewBox=&quot;0 0 25 25&quot; version=&quot;1.1&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot; style=&quot;vertical-align: middle;&quot;&gt;
&lt;g id=&quot;unchanged&quot; stroke=&quot;none&quot; stroke-width=&quot;1&quot; fill=&quot;none&quot; fill-rule=&quot;evenodd&quot;&gt;
    &lt;g id=&quot;unchanged&quot; transform=&quot;translate(0.500000, 0.570147)&quot;&gt;
        &lt;rect id=&quot;Rectangle&quot; x=&quot;0.125132506&quot; y=&quot;0&quot; width=&quot;23.749735&quot; height=&quot;23.7894737&quot;&gt;&lt;/rect&gt;
        &lt;path d=&quot;M5.80375046,8.18194736 C3.77191832,8.18194736 2.11875046,9.83495328 2.11875046,11.8669474 C2.11875046,13.8989414 3.77191832,15.5519474 5.80375046,15.5519474 C7.8355826,15.5519474 9.48875046,13.8989414 9.48875046,11.8669474 C9.48875046,9.83495328 7.83552863,8.18194736 5.80375046,8.18194736 Z M5.80375046,14.814915 C4.17821997,14.814915 2.85578285,13.4924778 2.85578285,11.8669474 C2.85578285,10.2414169 4.17821997,8.91897975 5.80375046,8.91897975 C7.42928095,8.91897975 8.75171807,10.2414169 8.75171807,11.8669474 C8.75171807,13.4924778 7.42928095,14.814915 5.80375046,14.814915 Z&quot; id=&quot;Shape&quot; fill=&quot;#000000&quot; fill-rule=&quot;nonzero&quot;&gt;&lt;/path&gt;
        &lt;path d=&quot;M13.9638189,8.699335 C13.9364621,8.70430925 13.9091059,8.71176968 13.8842359,8.71923074 C13.7822704,8.73663967 13.6877654,8.77643115 13.6056956,8.83860518 L10.2433156,11.3852598 C10.0766886,11.5046343 9.97720993,11.6986181 9.97720993,11.9025491 C9.97720993,12.1064807 10.0766886,12.3004639 10.2433156,12.4198383 L13.6056956,14.966493 C13.891697,15.1803725 14.2970729,15.1231721 14.5109517,14.8371707 C14.7248313,14.5511692 14.6676309,14.145794 14.3816294,13.9319145 L12.5313257,12.5392127 L21.8812495,12.5392127 L21.8812495,11.2658854 L12.5313257,11.2658854 L14.3816294,9.87318364 C14.6377872,9.71650453 14.7497006,9.40066014 14.6477351,9.11714553 C14.5482564,8.83363156 14.262255,8.65954352 13.9638189,8.699335 Z&quot; id=&quot;arrow&quot; fill=&quot;#000000&quot; transform=&quot;translate(15.929230, 11.894737) rotate(-180.000000) translate(-15.929230, -11.894737) &quot;&gt;&lt;/path&gt;
    &lt;/g&gt;
&lt;/g&gt;
</code></pre>
<p></svg></td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center"><span style="color:#4CA64C;">✓</span></td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px;" class="gt_row gt_right">1</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">0<br />0.00</td>
<td style="height: 40px; color: black;font-family: IBM Plex Mono;font-size: 11px; border-left: 1px dashed #E5E5E5;" class="gt_row gt_right">1<br />1.00</td>
<td style="height: 40px; background-color: #FCFCFC; border-left: 1px solid #D3D3D3;" class="gt_row gt_center">—</td>
<td style="height: 40px; background-color: #FCFCFC;" class="gt_row gt_center">—</td>
<td style="height: 40px; background-color: #FCFCFC; border-right: 1px solid #D3D3D3;" class="gt_row gt_center">—</td>
<td style="height: 40px;" class="gt_row gt_center">—</td></p>
  </tr>
</tbody>
  <tfoot class="gt_sourcenotes">
  <tr>
    <td class="gt_sourcenote" colspan="14" style="text-align: left;"><div style='margin-top: 5px; margin-bottom: 5px;'><span style='background-color: #FFF; color: #444; padding: 0.5em 0.5em; position: inherit; text-transform: uppercase; margin-left: 10px; margin-right: 5px; border: solid 1px #999999; font-variant-numeric: tabular-nums; border-radius: 0; padding: 2px 10px 2px 10px;'>2026-04-02 19:07:33 UTC</span><span style='background-color: #FFF; color: #444; padding: 0.5em 0.5em; position: inherit; margin-right: 5px; border: solid 1px #999999; font-variant-numeric: tabular-nums; border-radius: 0; padding: 2px 10px 2px 10px;'>< 1 s</span><span style='background-color: #FFF; color: #444; padding: 0.5em 0.5em; position: inherit; text-transform: uppercase; margin: 5px 1px 5px -1px; border: solid 1px #999999; font-variant-numeric: tabular-nums; border-radius: 0; padding: 2px 10px 2px 10px;'>2026-04-02 19:07:33 UTC</span></div></td>
  </tr>
  <tr>
    <td class="gt_sourcenote" colspan="14" style="text-align: left;"><hr style='border: none; border-top-width: 1px; border-top-style: dotted; border-top-color: #B5B5B5; margin-top: -3px; margin-bottom: 3px;'>
<strong>Notes</strong>
<p><span style='font-variant: small-caps; font-weight: bold; font-size: smaller; text-transform: uppercase; color: #333333;'>Step 1</span> <span style='font-family: "IBM Plex Mono", monospace; font-size: smaller;'>(schema_check)</span> <span style="color:#FF3300;">✗</span> Schema validation <strong>failed</strong>: 1 unmatched column(s), 1 dtype mismatch(es).</p>
<details style="margin-top: 2px; margin-bottom: 8px; font-size: 12px; text-indent: 12px;">
<summary style="cursor: pointer; font-weight: bold; color: #555; margin-bottom: -5px;">Schema Comparison</summary>
<div style="margin-top: 6px; padding-left: 15px; padding-right: 15px;">
<div id="pb_step_tbl" style="padding-left:0px;padding-right:0px;padding-top:10px;padding-bottom:10px;overflow-x:auto;overflow-y:auto;width:auto;height:auto;">
<style>
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono&display=swap');
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans&display=swap');
#pb_step_tbl table {
          font-family: 'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Helvetica Neue', 'Fira Sans', 'Droid Sans', Arial, sans-serif;
          -webkit-font-smoothing: antialiased;
          -moz-osx-font-smoothing: grayscale;
        }
<p>#pb_step_tbl thead, tbody, tfoot, tr, td, th { border-style: none; }
tr { background-color: transparent; }
#pb_step_tbl p { margin: 0; padding: 0; }
#pb_step_tbl .gt_table { display: table; border-collapse: collapse; line-height: normal; margin-left: auto; margin-right: auto; color: #333333; font-size: 16px; font-weight: normal; font-style: normal; background-color: #FFFFFF; width: auto; border-top-style: solid; border-top-width: 2px; border-top-color: #A8A8A8; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #A8A8A8; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; }
#pb_step_tbl .gt_caption { padding-top: 4px; padding-bottom: 4px; }
#pb_step_tbl .gt_title { color: #333333; font-size: 125%; font-weight: initial; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; border-bottom-color: #FFFFFF; border-bottom-width: 0; }
#pb_step_tbl .gt_subtitle { color: #333333; font-size: 85%; font-weight: initial; padding-top: 3px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; border-top-color: #FFFFFF; border-top-width: 0; }
#pb_step_tbl .gt_heading { background-color: #FFFFFF; text-align: left; border-bottom-color: #FFFFFF; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; }
#pb_step_tbl .gt_bottom_border { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; }
#pb_step_tbl .gt_col_headings { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; }
#pb_step_tbl .gt_col_heading { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; overflow-x: hidden; }
#pb_step_tbl .gt_column_spanner_outer { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; padding-top: 0; padding-bottom: 0; padding-left: 4px; padding-right: 4px; }
#pb_step_tbl .gt_column_spanner_outer:first-child { padding-left: 0; }
#pb_step_tbl .gt_column_spanner_outer:last-child { padding-right: 0; }
#pb_step_tbl .gt_column_spanner { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; overflow-x: hidden; display: inline-block; width: 100%; }
#pb_step_tbl .gt_spanner_row { border-bottom-style: hidden; }
#pb_step_tbl .gt_group_heading { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; text-align: left; }
#pb_step_tbl .gt_empty_group_heading { padding: 0.5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: middle; }
#pb_step_tbl .gt_from_md&gt; :first-child { margin-top: 0; }
#pb_step_tbl .gt_from_md&gt; :last-child { margin-bottom: 0; }
#pb_step_tbl .gt_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; margin: 10px; border-top-style: solid; border-top-width: 1px; border-top-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; overflow-x: hidden; }
#pb_step_tbl .gt_stub { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; }
#pb_step_tbl .gt_stub_row_group { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; vertical-align: top; }
#pb_step_tbl .gt_row_group_first td { border-top-width: 2px; }
#pb_step_tbl .gt_row_group_first th { border-top-width: 2px; }
#pb_step_tbl .gt_striped { color: #333333; background-color: #F4F4F4; }
#pb_step_tbl .gt_table_body { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; }
#pb_step_tbl .gt_grand_summary_row { color: #333333; background-color: #FFFFFF; text-transform: inherit; padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; }
#pb_step_tbl .gt_first_grand_summary_row_bottom { border-top-style: double; border-top-width: 6px; border-top-color: #D3D3D3; }
#pb_step_tbl .gt_last_grand_summary_row_top { border-bottom-style: double; border-bottom-width: 6px; border-bottom-color: #D3D3D3; }
#pb_step_tbl .gt_sourcenotes { color: #333333; background-color: #FFFFFF; border-bottom-style: none; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; }
#pb_step_tbl .gt_sourcenote { font-size: 12px; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; text-align: left; }
#pb_step_tbl .gt_left { text-align: left; }
#pb_step_tbl .gt_center { text-align: center; }
#pb_step_tbl .gt_right { text-align: right; font-variant-numeric: tabular-nums; }
#pb_step_tbl .gt_font_normal { font-weight: normal; }
#pb_step_tbl .gt_font_bold { font-weight: bold; }
#pb_step_tbl .gt_font_italic { font-style: italic; }
#pb_step_tbl .gt_super { font-size: 65%; }
#pb_step_tbl .gt_footnote_marks { font-size: 75%; vertical-align: 0.4em; position: initial; }
#pb_step_tbl .gt_asterisk { font-size: 100%; vertical-align: 0; }</p>
</style>
<table style="table-layout: fixed;; width: 0px" class="gt_table" data-quarto-disable-processing="true" data-quarto-bootstrap="false">
<colgroup>
  <col style="width:40px;"/>
  <col style="width:190px;"/>
  <col style="width:190px;"/>
  <col style="width:40px;"/>
  <col style="width:190px;"/>
  <col style="width:30px;"/>
  <col style="width:190px;"/>
  <col style="width:30px;"/>
</colgroup>
<thead>
<tr class="gt_col_headings gt_spanner_row">
  <th class="gt_center gt_columns_top_border gt_column_spanner_outer" rowspan="1" colspan="3" scope="colgroup" id="pb_step_tbl-TARGET">
    <span class="gt_column_spanner">TARGET</span>
  </th>
  <th class="gt_center gt_columns_top_border gt_column_spanner_outer" rowspan="1" colspan="5" scope="colgroup" id="pb_step_tbl-EXPECTED">
    <span class="gt_column_spanner">EXPECTED</span>
  </th>
</tr>
<tr class="gt_col_headings">
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" scope="col" id="pb_step_tbl-index_target"></th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" scope="col" id="pb_step_tbl-col_name_target">COLUMN</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" scope="col" id="pb_step_tbl-dtype_target">DATA TYPE</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" scope="col" id="pb_step_tbl-index_exp"></th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" scope="col" id="pb_step_tbl-col_name_exp">COLUMN</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" scope="col" id="pb_step_tbl-col_name_exp_correct"></th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" scope="col" id="pb_step_tbl-dtype_exp">DATA TYPE</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" scope="col" id="pb_step_tbl-dtype_exp_correct"></th>
</tr>
</thead>
<tbody class="gt_table_body">
  <tr>
    <td style="font-size: 13px;" class="gt_row gt_right">1</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">date_time</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">timestamp(6)</td>
    <td style="font-size: 13px; border-left: 3px double #E5E5E5;" class="gt_row gt_right">1</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">date_time</td>
    <td class="gt_row gt_left"><span style='color: #4CA64C;'>✓</span></td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">timestamp(6)</td>
    <td class="gt_row gt_left"><span style='color: #4CA64C;'>✓</span></td>
  </tr>
  <tr>
    <td style="font-size: 13px;" class="gt_row gt_right">2</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">date</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">date</td>
    <td style="font-size: 13px; border-left: 3px double #E5E5E5;" class="gt_row gt_right">2</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">dates</td>
    <td class="gt_row gt_left"><span style='color: #CF142B;'>✗</span></td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">date</td>
    <td class="gt_row gt_left">—</td>
  </tr>
  <tr>
    <td style="font-size: 13px;" class="gt_row gt_right">3</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">a</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">int64</td>
    <td style="font-size: 13px; border-left: 3px double #E5E5E5;" class="gt_row gt_right">3</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">a</td>
    <td class="gt_row gt_left"><span style='color: #4CA64C;'>✓</span></td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">int64</td>
    <td class="gt_row gt_left"><span style='color: #4CA64C;'>✓</span></td>
  </tr>
  <tr>
    <td style="font-size: 13px;" class="gt_row gt_right">4</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">b</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">string</td>
    <td style="font-size: 13px; border-left: 3px double #E5E5E5;" class="gt_row gt_right">4</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">b</td>
    <td class="gt_row gt_left"><span style='color: #4CA64C;'>✓</span></td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">—</td>
    <td class="gt_row gt_left"></td>
  </tr>
  <tr>
    <td style="font-size: 13px;" class="gt_row gt_right">5</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">c</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">int64</td>
    <td style="font-size: 13px; border-left: 3px double #E5E5E5;" class="gt_row gt_right">5</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">c</td>
    <td class="gt_row gt_left"><span style='color: #4CA64C;'>✓</span></td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">—</td>
    <td class="gt_row gt_left"></td>
  </tr>
  <tr>
    <td style="font-size: 13px;" class="gt_row gt_right">6</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">d</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">float64</td>
    <td style="font-size: 13px; border-left: 3px double #E5E5E5;" class="gt_row gt_right">6</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">d</td>
    <td class="gt_row gt_left"><span style='color: #4CA64C;'>✓</span></td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">float64</td>
    <td class="gt_row gt_left"><span style='color: #4CA64C;'>✓</span></td>
  </tr>
  <tr>
    <td style="font-size: 13px;" class="gt_row gt_right">7</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">e</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">boolean</td>
    <td style="font-size: 13px; border-left: 3px double #E5E5E5;" class="gt_row gt_right">7</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">e</td>
    <td class="gt_row gt_left"><span style='color: #4CA64C;'>✓</span></td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">bool | <span style="text-decoration: underline; text-decoration-color: #4CA64C; text-underline-offset: 3px;">boolean</span></td>
    <td class="gt_row gt_left"><span style='color: #4CA64C;'>✓</span></td>
  </tr>
  <tr>
    <td style="font-size: 13px;" class="gt_row gt_right">8</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">f</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">string</td>
    <td style="font-size: 13px; border-left: 3px double #E5E5E5;" class="gt_row gt_right">8</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">f</td>
    <td class="gt_row gt_left"><span style='color: #4CA64C;'>✓</span></td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">str</td>
    <td class="gt_row gt_left"><span style='color: #CF142B;'>✗</span></td>
  </tr>
</tbody>
  <tfoot class="gt_sourcenotes">
  <tr>
    <td class="gt_sourcenote" colspan="8"><div style='padding-bottom: 2px;'>Supplied Column Schema:</div><div style='border-style: solid; border-width: thin; border-color: lightblue; padding-left: 2px; padding-right: 2px; padding-bottom: 3px;'><code style='color: #303030; font-family: monospace; font-size: 8px;'>[('date_time', 'timestamp(6)'), ('dates', 'date'), ('a', 'int64'), ('b',), ('c',), ('d', 'float64'), ('e', ['bool', 'boolean']), ('f', 'str')]</code></div></td>
  </tr>
  <tr>
    <td class="gt_sourcenote" colspan="8">
<div style='padding-bottom: 2px;'>Schema Match Settings</div>
<div style='padding-bottom: 4px;'><div style="display: flex; font-size: 13.7px; padding-top: 2px;"><div style="border-style: solid; border-width: 1px; border-color: #87CEFA; border-radius: 5px; background-color: #F0F8FF; font-size: x-small; padding-left: 4px; padding-right: 4px; margin-left: 5px; margin-right: 5px;  margin-top: 2px; ">COMPLETE</div><div style="border-style: solid; border-width: 1px; border-color: #87CEFA; border-radius: 5px; background-color: #F0F8FF; font-size: x-small; padding-left: 4px; padding-right: 4px; margin-left: 5px; margin-right: 5px;  margin-top: 2px; ">IN ORDER</div><div style="border-style: solid; border-width: 1px; border-color: #A9A9A9; border-radius: 5px; background-color: #F5F5F5; font-size: x-small; padding-left: 4px; padding-right: 4px; margin-left: 5px; margin-right: 5px;  margin-top: 2px; ">COLUMN &ne; column</div><div style="border-style: solid; border-width: 1px; border-color: #A9A9A9; border-radius: 5px; background-color: #F5F5F5; font-size: x-small; padding-left: 4px; padding-right: 4px; margin-left: 5px; margin-right: 5px;  margin-top: 2px; ">DTYPE &ne; dtype</div><div style="border-style: solid; border-width: 1px; border-color: #A9A9A9; border-radius: 5px; background-color: #F5F5F5; font-size: x-small; padding-left: 4px; padding-right: 4px; margin-left: 5px; margin-right: 5px;  margin-top: 2px; ">float &ne; float64</div></div></div>
</td>
  </tr>
</tfoot>
</table>
</div>
</div>
</details>
</td>
  </tr>
</tfoot>
</table>
</div>
<p>This step fails, but the validation report table doesn&rsquo;t tell us how (or where). Using
<a href="https://posit-dev.github.io/pointblank/reference/Validate.get_step_report.html" target="_blank" rel="noopener">`get_step_report()</a>

will show us what the underlying issues are:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">validation_3</span><span class="o">.</span><span class="n">get_step_report</span><span class="p">(</span><span class="n">i</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div id="pb_step_tbl" style="padding-left:0px;padding-right:0px;padding-top:10px;padding-bottom:10px;overflow-x:auto;overflow-y:auto;width:auto;height:auto;">
<style>
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono&display=swap');
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans&display=swap');
#pb_step_tbl table {
          font-family: 'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Helvetica Neue', 'Fira Sans', 'Droid Sans', Arial, sans-serif;
          -webkit-font-smoothing: antialiased;
          -moz-osx-font-smoothing: grayscale;
        }
<p>#pb_step_tbl thead, tbody, tfoot, tr, td, th { border-style: none; }
tr { background-color: transparent; }
#pb_step_tbl p { margin: 0; padding: 0; }
#pb_step_tbl .gt_table { display: table; border-collapse: collapse; line-height: normal; margin-left: auto; margin-right: auto; color: #333333; font-size: 16px; font-weight: normal; font-style: normal; background-color: #FFFFFF; width: auto; border-top-style: solid; border-top-width: 2px; border-top-color: #A8A8A8; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #A8A8A8; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; }
#pb_step_tbl .gt_caption { padding-top: 4px; padding-bottom: 4px; }
#pb_step_tbl .gt_title { color: #333333; font-size: 125%; font-weight: initial; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; border-bottom-color: #FFFFFF; border-bottom-width: 0; }
#pb_step_tbl .gt_subtitle { color: #333333; font-size: 85%; font-weight: initial; padding-top: 3px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; border-top-color: #FFFFFF; border-top-width: 0; }
#pb_step_tbl .gt_heading { background-color: #FFFFFF; text-align: left; border-bottom-color: #FFFFFF; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; }
#pb_step_tbl .gt_bottom_border { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; }
#pb_step_tbl .gt_col_headings { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; }
#pb_step_tbl .gt_col_heading { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; overflow-x: hidden; }
#pb_step_tbl .gt_column_spanner_outer { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: normal; text-transform: inherit; padding-top: 0; padding-bottom: 0; padding-left: 4px; padding-right: 4px; }
#pb_step_tbl .gt_column_spanner_outer:first-child { padding-left: 0; }
#pb_step_tbl .gt_column_spanner_outer:last-child { padding-right: 0; }
#pb_step_tbl .gt_column_spanner { border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: bottom; padding-top: 5px; padding-bottom: 5px; overflow-x: hidden; display: inline-block; width: 100%; }
#pb_step_tbl .gt_spanner_row { border-bottom-style: hidden; }
#pb_step_tbl .gt_group_heading { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; text-align: left; }
#pb_step_tbl .gt_empty_group_heading { padding: 0.5px; color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; vertical-align: middle; }
#pb_step_tbl .gt_from_md&gt; :first-child { margin-top: 0; }
#pb_step_tbl .gt_from_md&gt; :last-child { margin-bottom: 0; }
#pb_step_tbl .gt_row { padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; margin: 10px; border-top-style: solid; border-top-width: 1px; border-top-color: #D3D3D3; border-left-style: none; border-left-width: 1px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 1px; border-right-color: #D3D3D3; vertical-align: middle; overflow-x: hidden; }
#pb_step_tbl .gt_stub { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; }
#pb_step_tbl .gt_stub_row_group { color: #333333; background-color: #FFFFFF; font-size: 100%; font-weight: initial; text-transform: inherit; border-right-style: solid; border-right-width: 2px; border-right-color: #D3D3D3; padding-left: 5px; padding-right: 5px; vertical-align: top; }
#pb_step_tbl .gt_row_group_first td { border-top-width: 2px; }
#pb_step_tbl .gt_row_group_first th { border-top-width: 2px; }
#pb_step_tbl .gt_striped { color: #333333; background-color: #F4F4F4; }
#pb_step_tbl .gt_table_body { border-top-style: solid; border-top-width: 2px; border-top-color: #D3D3D3; border-bottom-style: solid; border-bottom-width: 2px; border-bottom-color: #D3D3D3; }
#pb_step_tbl .gt_grand_summary_row { color: #333333; background-color: #FFFFFF; text-transform: inherit; padding-top: 8px; padding-bottom: 8px; padding-left: 5px; padding-right: 5px; }
#pb_step_tbl .gt_first_grand_summary_row_bottom { border-top-style: double; border-top-width: 6px; border-top-color: #D3D3D3; }
#pb_step_tbl .gt_last_grand_summary_row_top { border-bottom-style: double; border-bottom-width: 6px; border-bottom-color: #D3D3D3; }
#pb_step_tbl .gt_sourcenotes { color: #333333; background-color: #FFFFFF; border-bottom-style: none; border-bottom-width: 2px; border-bottom-color: #D3D3D3; border-left-style: none; border-left-width: 2px; border-left-color: #D3D3D3; border-right-style: none; border-right-width: 2px; border-right-color: #D3D3D3; }
#pb_step_tbl .gt_sourcenote { font-size: 12px; padding-top: 4px; padding-bottom: 4px; padding-left: 5px; padding-right: 5px; text-align: left; }
#pb_step_tbl .gt_left { text-align: left; }
#pb_step_tbl .gt_center { text-align: center; }
#pb_step_tbl .gt_right { text-align: right; font-variant-numeric: tabular-nums; }
#pb_step_tbl .gt_font_normal { font-weight: normal; }
#pb_step_tbl .gt_font_bold { font-weight: bold; }
#pb_step_tbl .gt_font_italic { font-style: italic; }
#pb_step_tbl .gt_super { font-size: 65%; }
#pb_step_tbl .gt_footnote_marks { font-size: 75%; vertical-align: 0.4em; position: initial; }
#pb_step_tbl .gt_asterisk { font-size: 100%; vertical-align: 0; }</p>
<p></style></p>
<table style="table-layout: fixed;; width: 0px" class="gt_table" data-quarto-disable-processing="true" data-quarto-bootstrap="false">
<colgroup>
  <col style="width:40px;"/>
  <col style="width:190px;"/>
  <col style="width:190px;"/>
  <col style="width:40px;"/>
  <col style="width:190px;"/>
  <col style="width:30px;"/>
  <col style="width:190px;"/>
  <col style="width:30px;"/>
</colgroup>
<thead>
  <tr class="gt_heading">
    <td colspan="8" class="gt_heading gt_title gt_font_normal">Report for Validation Step 1 <span style='color: #CF142B;'>&cross;</span><div style="display: flex; font-size: 13.7px; padding-top: 7px;"><div style="margin-right: 5px;">COLUMN SCHEMA MATCH</div><div style="border-style: solid; border-width: 1px; border-color: #87CEFA; border-radius: 5px; background-color: #F0F8FF; font-size: x-small; padding-left: 4px; padding-right: 4px; margin-left: 5px; margin-right: 5px;  margin-top: 2px; ">COMPLETE</div><div style="border-style: solid; border-width: 1px; border-color: #87CEFA; border-radius: 5px; background-color: #F0F8FF; font-size: x-small; padding-left: 4px; padding-right: 4px; margin-left: 5px; margin-right: 5px;  margin-top: 2px; ">IN ORDER</div><div style="border-style: solid; border-width: 1px; border-color: #A9A9A9; border-radius: 5px; background-color: #F5F5F5; font-size: x-small; padding-left: 4px; padding-right: 4px; margin-left: 5px; margin-right: 5px;  margin-top: 2px; ">COLUMN &ne; column</div><div style="border-style: solid; border-width: 1px; border-color: #A9A9A9; border-radius: 5px; background-color: #F5F5F5; font-size: x-small; padding-left: 4px; padding-right: 4px; margin-left: 5px; margin-right: 5px;  margin-top: 2px; ">DTYPE &ne; dtype</div><div style="border-style: solid; border-width: 1px; border-color: #A9A9A9; border-radius: 5px; background-color: #F5F5F5; font-size: x-small; padding-left: 4px; padding-right: 4px; margin-left: 5px; margin-right: 5px;  margin-top: 2px; ">float &ne; float64</div></div></td>
  </tr>
<tr class="gt_col_headings gt_spanner_row">
  <th class="gt_center gt_columns_top_border gt_column_spanner_outer" rowspan="1" colspan="3" scope="colgroup" id="pb_step_tbl-TARGET">
    <span class="gt_column_spanner">TARGET</span>
  </th>
  <th class="gt_center gt_columns_top_border gt_column_spanner_outer" rowspan="1" colspan="5" scope="colgroup" id="pb_step_tbl-EXPECTED">
    <span class="gt_column_spanner">EXPECTED</span>
  </th>
</tr>
<tr class="gt_col_headings">
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" scope="col" id="pb_step_tbl-index_target"></th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" scope="col" id="pb_step_tbl-col_name_target">COLUMN</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" scope="col" id="pb_step_tbl-dtype_target">DATA TYPE</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_right" rowspan="1" colspan="1" scope="col" id="pb_step_tbl-index_exp"></th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" scope="col" id="pb_step_tbl-col_name_exp">COLUMN</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" scope="col" id="pb_step_tbl-col_name_exp_correct"></th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" scope="col" id="pb_step_tbl-dtype_exp">DATA TYPE</th>
  <th class="gt_col_heading gt_columns_bottom_border gt_left" rowspan="1" colspan="1" scope="col" id="pb_step_tbl-dtype_exp_correct"></th>
</tr>
</thead>
<tbody class="gt_table_body">
  <tr>
    <td style="font-size: 13px;" class="gt_row gt_right">1</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">date_time</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">timestamp(6)</td>
    <td style="font-size: 13px; border-left: 3px double #E5E5E5;" class="gt_row gt_right">1</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">date_time</td>
    <td class="gt_row gt_left"><span style='color: #4CA64C;'>✓</span></td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">timestamp(6)</td>
    <td class="gt_row gt_left"><span style='color: #4CA64C;'>✓</span></td>
  </tr>
  <tr>
    <td style="font-size: 13px;" class="gt_row gt_right">2</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">date</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">date</td>
    <td style="font-size: 13px; border-left: 3px double #E5E5E5;" class="gt_row gt_right">2</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">dates</td>
    <td class="gt_row gt_left"><span style='color: #CF142B;'>✗</span></td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">date</td>
    <td class="gt_row gt_left">—</td>
  </tr>
  <tr>
    <td style="font-size: 13px;" class="gt_row gt_right">3</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">a</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">int64</td>
    <td style="font-size: 13px; border-left: 3px double #E5E5E5;" class="gt_row gt_right">3</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">a</td>
    <td class="gt_row gt_left"><span style='color: #4CA64C;'>✓</span></td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">int64</td>
    <td class="gt_row gt_left"><span style='color: #4CA64C;'>✓</span></td>
  </tr>
  <tr>
    <td style="font-size: 13px;" class="gt_row gt_right">4</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">b</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">string</td>
    <td style="font-size: 13px; border-left: 3px double #E5E5E5;" class="gt_row gt_right">4</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">b</td>
    <td class="gt_row gt_left"><span style='color: #4CA64C;'>✓</span></td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">—</td>
    <td class="gt_row gt_left"></td>
  </tr>
  <tr>
    <td style="font-size: 13px;" class="gt_row gt_right">5</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">c</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">int64</td>
    <td style="font-size: 13px; border-left: 3px double #E5E5E5;" class="gt_row gt_right">5</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">c</td>
    <td class="gt_row gt_left"><span style='color: #4CA64C;'>✓</span></td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">—</td>
    <td class="gt_row gt_left"></td>
  </tr>
  <tr>
    <td style="font-size: 13px;" class="gt_row gt_right">6</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">d</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">float64</td>
    <td style="font-size: 13px; border-left: 3px double #E5E5E5;" class="gt_row gt_right">6</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">d</td>
    <td class="gt_row gt_left"><span style='color: #4CA64C;'>✓</span></td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">float64</td>
    <td class="gt_row gt_left"><span style='color: #4CA64C;'>✓</span></td>
  </tr>
  <tr>
    <td style="font-size: 13px;" class="gt_row gt_right">7</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">e</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">boolean</td>
    <td style="font-size: 13px; border-left: 3px double #E5E5E5;" class="gt_row gt_right">7</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">e</td>
    <td class="gt_row gt_left"><span style='color: #4CA64C;'>✓</span></td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">bool | <span style="text-decoration: underline; text-decoration-color: #4CA64C; text-underline-offset: 3px;">boolean</span></td>
    <td class="gt_row gt_left"><span style='color: #4CA64C;'>✓</span></td>
  </tr>
  <tr>
    <td style="font-size: 13px;" class="gt_row gt_right">8</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">f</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">string</td>
    <td style="font-size: 13px; border-left: 3px double #E5E5E5;" class="gt_row gt_right">8</td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">f</td>
    <td class="gt_row gt_left"><span style='color: #4CA64C;'>✓</span></td>
    <td style="color: black;font-family: IBM Plex Mono;font-size: 13px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;" class="gt_row gt_left">str</td>
    <td class="gt_row gt_left"><span style='color: #CF142B;'>✗</span></td>
  </tr>
</tbody>
  <tfoot class="gt_sourcenotes">
  <tr>
    <td class="gt_sourcenote" colspan="8"><div style='padding-bottom: 2px;'>Supplied Column Schema:</div><div style='border-style: solid; border-width: thin; border-color: lightblue; padding-left: 2px; padding-right: 2px; padding-bottom: 3px;'><code style='color: #303030; font-family: monospace; font-size: 8px;'>[('date_time', 'timestamp(6)'), ('dates', 'date'), ('a', 'int64'), ('b',), ('c',), ('d', 'float64'), ('e', ['bool', 'boolean']), ('f', 'str')]</code></div></td>
  </tr>
</tfoot>
</table>
</div>
<p>The step report here shows the target table&rsquo;s schema on the left side and the expectation of the
schema on the right side. There appears to be two problems with our supplied schema:</p>
<ol>
<li>the second column is actually <code>date</code> instead of <code>dates</code></li>
<li>the dtype of the <code>f</code> column is <code>&quot;string&quot;</code> and not <code>&quot;str&quot;</code></li>
</ol>
<p>The convenience of this step report means we only have to look at one display of information, rather
than having to collect up the individual pieces and make careful comparisons.</p>
<h2 id="much-more-in-store">Much More in Store
</h2>
<p>Pointblank tries really hard to make it easy for you to test your data. All sorts of input tables
are supported since we integrate with the brilliant
<a href="https://narwhals-dev.github.io/narwhals/" target="_blank" rel="noopener">Narwhals</a>
 and
<a href="https://ibis-project.org" target="_blank" rel="noopener">Ibis</a>
 libraries. And even through the project has only started four
months ago, we already have an extensive catalog of well-tested validation methods.</p>
<p>We care a great deal about documentation so much recent effort has been placed on getting the
<a href="https://posit-dev.github.io/pointblank/user-guide/" target="_blank" rel="noopener"><strong>User Guide</strong></a>
 written. We hope it provides
for gentle introduction to the major features of the library. If you want some quick examples to get
your imagination going, check out our
<a href="https://posit-dev.github.io/pointblank/demos/" target="_blank" rel="noopener">gallery of examples</a>
.</p>
<p>We really care about what <strong>you</strong> want in a validation package, so talk to us :) We just started a
<a href="https://discord.com/invite/YH7CybCNCQ" target="_blank" rel="noopener">Discord</a>
 so feel free to hop on and ask us anything.
Alternatively, we always like to get <a href="https://github.com/posit-dev/pointblank/issues" target="_blank" rel="noopener">issues</a>
 so
don&rsquo;t be shy in letting us know how we could improve!</p>
]]></description>
    </item>
    <item>
      <title>Air, an extremely fast R formatter</title>
      <link>https://posit-open-source.netlify.app/blog/tidyverse/air/</link>
      <pubDate>Fri, 21 Feb 2025 00:00:00 +0000</pubDate>
      <guid>https://posit-open-source.netlify.app/blog/tidyverse/air/</guid>
      <dc:creator>Davis Vaughan</dc:creator>
      <dc:creator>Lionel Henry</dc:creator><description><![CDATA[<p>We&rsquo;re thrilled to announce <a href="https://posit-dev.github.io/air/" target="_blank" rel="noopener">Air</a>
, an extremely fast R formatter. Formatters are used to automatically style code, but I find that it&rsquo;s much easier to show what Air can do rather than tell, so we&rsquo;ll start with a few examples. In the video below, we&rsquo;re inside <a href="https://positron.posit.co/" target="_blank" rel="noopener">Positron</a>
 and we&rsquo;re looking at some unformatted code. Saving the file (yep, that&rsquo;s it!) invokes Air, which automatically and instantaneously formats the code.</p>
<video controls autoplay loop muted width="80%" src="https://posit-open-source.netlify.app/blog/tidyverse/air/video/case-when.mov" style="border: 2px solid #CCC;" class="mx-auto">
</video>
<p>Next, let&rsquo;s go over to <a href="https://posit.co/products/open-source/rstudio/" target="_blank" rel="noopener">RStudio</a>
. Here we&rsquo;ve got a pipe chain that could use a little formatting. Like in Positron, just save the file:</p>
<video controls autoplay loop muted width="80%" src="https://posit-open-source.netlify.app/blog/tidyverse/air/video/ggplot.mov" style="border: 2px solid #CCC;" class="mx-auto">
</video>
<p>Lastly, we&rsquo;ll jump back into Positron. Rather than formatting a single file on save, you might want to instead format an entire project (particularly when first adopting Air). To do so, just run <code>air format .</code> in a terminal from the project root, and Air will recursively format any R files it finds along the way (smartly excluding known generated files, like <code>cpp11.R</code>). Here we&rsquo;ll run Air on dplyr for the first time ever, analyzing and reformatting over 150 files instantly:</p>
<video controls autoplay loop muted width="80%" src="https://posit-open-source.netlify.app/blog/tidyverse/air/video/project.mov" style="border: 2px solid #CCC;" class="mx-auto">
</video>
<p>Within the tidyverse, we&rsquo;re already using Air in some of our largest packages, like <a href="https://github.com/tidyverse/dplyr/pull/7662" target="_blank" rel="noopener">dplyr</a>
, <a href="https://github.com/tidyverse/tidyr/pull/1591" target="_blank" rel="noopener">tidyr</a>
, and <a href="https://github.com/tidymodels/recipes/pull/1425" target="_blank" rel="noopener">recipes</a>
.</p>
<p>Throughout the rest of this post you&rsquo;ll learn what a formatter is, why you&rsquo;d want to use one, and you&rsquo;ll learn a little about how Air decides to format your R code.</p>
<p>Note that Air is still in beta, so there may be some breaking changes over the next few releases. We also encourage you to use it in combination with a version control system, like git, so that you can clearly see the changes Air makes. That said, we still feel very confident in the current state of Air, and can&rsquo;t wait for you to try it!</p>
<h2 id="installing-air">Installing Air
</h2>
<p>If you already know how formatters work and want to jump straight in, follow one of the guides below:</p>
<ul>
<li>
<p>For Positron, Air is <a href="https://open-vsx.org/extension/posit/air-vscode" target="_blank" rel="noopener">available</a>
 on OpenVSX as an Extension. Install it from the Extensions pane within Positron, then read our <a href="https://posit-dev.github.io/air/editor-vscode.html" target="_blank" rel="noopener">Positron guide</a>
.</p>
</li>
<li>
<p>For VS Code, Air is <a href="https://marketplace.visualstudio.com/items?itemName=Posit.air-vscode" target="_blank" rel="noopener">available</a>
 on the VS Code Marketplace as an Extension. Install it from the Extensions pane within VS Code, then read our <a href="https://posit-dev.github.io/air/editor-vscode.html" target="_blank" rel="noopener">VS Code guide</a>
.</p>
</li>
<li>
<p>For RStudio, Air can be set as an external formatter, but you&rsquo;ll need to install the command line tool for Air first. Read our <a href="https://posit-dev.github.io/air/editor-rstudio.html" target="_blank" rel="noopener">RStudio guide</a>
 to get started. Note that this is an experimental feature on the RStudio side, so the exact setup may change a little until it is fully stabilized.</p>
</li>
<li>
<p>For command line users, Air binaries can be installed using our <a href="https://posit-dev.github.io/air/cli.html" target="_blank" rel="noopener">standalone installer scripts</a>
.</p>
</li>
</ul>
<p>For both Positron and VS Code, the most important thing to enable after installing the extension is format on save for R. You can do that by adding these lines to your <code>settings.json</code> file:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;[r]&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;editor.formatOnSave&#34;</span><span class="p">:</span> <span class="kc">true</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>To open your <code>settings.json</code> file, run one of the following from the Command Palette:</p>
<ul>
<li>
<p>Run <code>Preferences: Open User Settings (JSON)</code> to modify global user settings.</p>
</li>
<li>
<p>Run <code>Preferences: Open Workspace Settings (JSON)</code> to modify project specific settings. You may want to use this instead of setting the user level setting if you drop in on multiple projects, but not all of them use Air. If you work on a project with collaborators, we recommend that you check in these project specific settings to your repository to ensure that every collaborator is using the same formatting settings.</p>
</li>
</ul>
<p>If your preferred editor isn&rsquo;t listed here, but does support the <a href="https://microsoft.github.io/language-server-protocol/" target="_blank" rel="noopener">Language Server Protocol</a>
, then it is likely that we can add support for Air there as well.</p>
<p>If you have any questions or run into issues installing or using Air, feel free to open an <a href="https://github.com/posit-dev/air/issues" target="_blank" rel="noopener">issue</a>
!</p>
<h2 id="whats-a-formatter">What&rsquo;s a formatter?
</h2>
<p>A formatter is in charge of the <em>layout</em> of your R code. Formatters do not change the meaning of code; instead they ensure that whitespace, newlines, and other punctuation conform to a set of rules and standards, such as:</p>
<ul>
<li>
<p>Making sure your code is <strong>indented</strong> with the appropriate amount of leading whitespace. By default, Air uses 2 spaces for indentation. You will see this indentation in pipelines:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="n">data</span> <span class="o">|&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nf">ggplot</span><span class="p">(</span><span class="nf">aes</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">))</span> <span class="o">+</span>
</span></span><span class="line"><span class="cl">  <span class="nf">geom_point</span><span class="p">()</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>As well as in function calls:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="nf">list</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">  <span class="n">foo</span> <span class="o">=</span> <span class="m">1</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="n">bar</span> <span class="o">=</span> <span class="m">2</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>
<p>Preventing your code from overflowing a given <strong>line width</strong>. By default, Air uses a line width of 80 characters. It enforces this by splitting long lines of code over multiple lines. For instance, notice how long these expressions are, they would &ldquo;overflow&rdquo; past 80 characters:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="n">band_members</span> <span class="o">|&gt;</span> <span class="nf">select</span><span class="p">(</span><span class="n">name</span><span class="p">)</span> <span class="o">|&gt;</span> <span class="nf">full_join</span><span class="p">(</span><span class="n">band_instruments2</span><span class="p">,</span> <span class="n">by</span> <span class="o">=</span> <span class="nf">join_by</span><span class="p">(</span><span class="n">name</span> <span class="o">==</span> <span class="n">artist</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">left_join</span> <span class="o">&lt;-</span> <span class="kr">function</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">by</span> <span class="o">=</span> <span class="kc">NULL</span><span class="p">,</span> <span class="n">copy</span> <span class="o">=</span> <span class="kc">FALSE</span><span class="p">,</span> <span class="n">suffix</span> <span class="o">=</span> <span class="nf">c</span><span class="p">(</span><span class="s">&#34;.x&#34;</span><span class="p">,</span> <span class="s">&#34;.y&#34;</span><span class="p">),</span> <span class="kc">...</span><span class="p">,</span> <span class="n">keep</span> <span class="o">=</span> <span class="kc">NULL</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nf">UseMethod</span><span class="p">(</span><span class="s">&#34;left_join&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>Air reformats these expressions by switching them from a horizontal layout (called &ldquo;flat&rdquo;) to a vertical one (called &ldquo;expanded&rdquo;):</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="n">band_members</span> <span class="o">|&gt;</span> 
</span></span><span class="line"><span class="cl">  <span class="nf">select</span><span class="p">(</span><span class="n">name</span><span class="p">)</span> <span class="o">|&gt;</span> 
</span></span><span class="line"><span class="cl">  <span class="nf">full_join</span><span class="p">(</span><span class="n">band_instruments2</span><span class="p">,</span> <span class="n">by</span> <span class="o">=</span> <span class="nf">join_by</span><span class="p">(</span><span class="n">name</span> <span class="o">==</span> <span class="n">artist</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">left_join</span> <span class="o">&lt;-</span> <span class="kr">function</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">  <span class="n">x</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="n">y</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="n">by</span> <span class="o">=</span> <span class="kc">NULL</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="n">copy</span> <span class="o">=</span> <span class="kc">FALSE</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="n">suffix</span> <span class="o">=</span> <span class="nf">c</span><span class="p">(</span><span class="s">&#34;.x&#34;</span><span class="p">,</span> <span class="s">&#34;.y&#34;</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">  <span class="kc">...</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="n">keep</span> <span class="o">=</span> <span class="kc">NULL</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nf">UseMethod</span><span class="p">(</span><span class="s">&#34;left_join&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>
<p>Standardizing the whitespace around code elements. Have you ever had difficulties deciphering very dense code?</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="m">1+2</span><span class="o">:</span><span class="m">3</span><span class="o">*</span><span class="p">(</span><span class="m">4</span><span class="o">/</span><span class="m">5</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>Air reformats this expression to:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="m">1</span> <span class="o">+</span> <span class="m">2</span><span class="o">:</span><span class="m">3</span> <span class="o">*</span> <span class="p">(</span><span class="m">4</span> <span class="o">/</span> <span class="m">5</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div></li>
</ul>
<h2 id="how-does-a-formatter-improve-your-workflow">How does a formatter improve your workflow?
</h2>
<p>By using a formatter it might seem like you&rsquo;re giving up control over the layout of your code. And indeed you are! However, putting Air in charge of styling your code has substantial advantages.</p>
<p>First, it automatically forces you to write legible code that is neither too wide nor too narrow, with proper breathing room around syntactic elements. Having a formatter as a companion significantly improves the process of writing code as you no longer have to think about style - the formatter does that for you!</p>
<p>Second, it reduces friction when working in a team. By agreeing to use a formatter in a project, collaborators no longer have to discuss styling and layout issues. Code sent to you by a colleague will adhere to the standards that you&rsquo;re used to. Code review no longer has to be about style nitpicks and can focus on the substance of the changes instead.</p>
<h2 id="how-does-air-decide-how-to-format-your-code">How does Air decide how to format your code?
</h2>
<p>Air tries to strike a balance between enforcing rigid rules and allowing authors some control over the layout. Our main source of styling rules is the <a href="https://style.tidyverse.org" target="_blank" rel="noopener">Tidyverse style guide</a>
, but we occasionally deviate from these.</p>
<p>There is a trend among modern formatters of being <em>opinionated</em>. Air certainly fits this trend and provides very few <a href="https://posit-dev.github.io/air/configuration.html" target="_blank" rel="noopener">configuration options</a>
, mostly: the indent style (spaces versus tabs), the indent width, and the line width. However, Air also puts code authors in charge of certain aspects of the layout through the notion of <strong>persistent line breaks</strong>.</p>
<p>In general, Air is in control of deciding where to put vertical space (line breaks) in your code. For instance if you write:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="n">dictionary</span> <span class="o">&lt;-</span> <span class="nf">list</span><span class="p">(</span><span class="n">bob</span> <span class="o">=</span> <span class="s">&#34;apple&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="n">jill</span> <span class="o">=</span> <span class="s">&#34;juice&#34;</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>Air will figure out that this expression fits on a single line without exceeding the line width. It will discard the line break and reformat to:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="n">dictionary</span> <span class="o">&lt;-</span> <span class="nf">list</span><span class="p">(</span><span class="n">bob</span> <span class="o">=</span> <span class="s">&#34;apple&#34;</span><span class="p">,</span> <span class="n">jill</span> <span class="o">=</span> <span class="s">&#34;juice&#34;</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>However there are very specific places at which you can insert a line break that Air perceives as persistent:</p>
<ul>
<li>
<p>Before the very first argument in a function call. This:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="c1"># Persistent line break after `(` and before `bob`</span>
</span></span><span class="line"><span class="cl"><span class="n">dictionary</span> <span class="o">&lt;-</span> <span class="nf">list</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">  <span class="n">bob</span> <span class="o">=</span> <span class="s">&#34;apple&#34;</span><span class="p">,</span> <span class="n">jill</span> <span class="o">=</span> <span class="s">&#34;juice&#34;</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>gets formatted as:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="n">dictionary</span> <span class="o">&lt;-</span> <span class="nf">list</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">  <span class="n">bob</span> <span class="o">=</span> <span class="s">&#34;apple&#34;</span><span class="p">,</span> 
</span></span><span class="line"><span class="cl">  <span class="n">jill</span> <span class="o">=</span> <span class="s">&#34;juice&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>
<p>Before the very first right-hand side expression in a pipeline. This:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="c1"># Persistent line break after `|&gt;` and before `select`</span>
</span></span><span class="line"><span class="cl"><span class="n">data</span> <span class="o">|&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nf">select</span><span class="p">(</span><span class="n">foo</span><span class="p">)</span> <span class="o">|&gt;</span> <span class="nf">filter</span><span class="p">(</span><span class="o">!</span><span class="n">bar</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>gets formatted as:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="n">data</span> <span class="o">|&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nf">select</span><span class="p">(</span><span class="n">foo</span><span class="p">)</span> <span class="o">|&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nf">filter</span><span class="p">(</span><span class="o">!</span><span class="n">bar</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div></li>
</ul>
<p>A persistent line break will never be removed by Air. But you can remove it manually. Taking the last example, if you join the first lines like this:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="c1"># Removed persistent line break after `(`</span>
</span></span><span class="line"><span class="cl"><span class="n">dictionary</span> <span class="o">&lt;-</span> <span class="nf">list</span><span class="p">(</span><span class="n">bob</span> <span class="o">=</span> <span class="s">&#34;apple&#34;</span><span class="p">,</span> 
</span></span><span class="line"><span class="cl">  <span class="n">jill</span> <span class="o">=</span> <span class="s">&#34;juice&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Removed persistent line break after `|&gt;`</span>
</span></span><span class="line"><span class="cl"><span class="n">data</span> <span class="o">|&gt;</span> <span class="nf">select</span><span class="p">(</span><span class="n">foo</span><span class="p">)</span> <span class="o">|&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="nf">filter</span><span class="p">(</span><span class="o">!</span><span class="n">bar</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>Air will recognize that you&rsquo;ve removed the persistent line break, and reformat as:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="n">dictionary</span> <span class="o">&lt;-</span> <span class="nf">list</span><span class="p">(</span><span class="n">bob</span> <span class="o">=</span> <span class="s">&#34;apple&#34;</span><span class="p">,</span> <span class="n">jill</span> <span class="o">=</span> <span class="s">&#34;juice&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">data</span> <span class="o">|&gt;</span> <span class="nf">select</span><span class="p">(</span><span class="n">foo</span><span class="p">)</span> <span class="o">|&gt;</span> <span class="nf">filter</span><span class="p">(</span><span class="o">!</span><span class="n">bar</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>The goal of this feature is to strike a balance between being opinionated and recognizing that users often know when taking up more vertical space results in more readable output.</p>
<h2 id="how-can-i-disable-formatting">How can I disable formatting?
</h2>
<p>If you need to disable formatting for a single expression, you can use a <code># fmt: skip</code> comment. This is particularly useful for manual alignment.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="c1"># This skips formatting for `list()` and its arguments, retaining the manual alignment</span>
</span></span><span class="line"><span class="cl"><span class="c1"># fmt: skip</span>
</span></span><span class="line"><span class="cl"><span class="nf">list</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">  <span class="n">dollar</span> <span class="o">=</span> <span class="s">&#34;USA&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="n">yen</span>    <span class="o">=</span> <span class="s">&#34;Japan&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="n">yuan</span>   <span class="o">=</span> <span class="s">&#34;China&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># This skips formatting for `tribble()` and its arguments</span>
</span></span><span class="line"><span class="cl"><span class="c1"># fmt: skip</span>
</span></span><span class="line"><span class="cl"><span class="nf">tribble</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">  <span class="o">~</span><span class="n">x</span><span class="p">,</span> <span class="o">~</span><span class="n">y</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">   <span class="m">1</span><span class="p">,</span>  <span class="m">2</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>If there is a file that Air should skip altogether, you can use a <code># fmt: skip file</code> comment at the very top of the file.</p>
<p>To learn more about these features, see the <a href="https://posit-dev.github.io/air/formatter.html#disabling-formatting" target="_blank" rel="noopener">documentation</a>
.</p>
<h2 id="how-can-i-use-air">How can I use Air?
</h2>
<p>As we&rsquo;ve touched on above, Air can be integrated into your IDE to format code on every save. We expect that this will be the most common way to invoke Air, but there are a few other ways to use Air that we think are pretty cool:</p>
<ul>
<li>
<p>In IDEs:</p>
<ul>
<li>
<p>Format on save</p>
</li>
<li>
<p>Format selection</p>
</li>
</ul>
</li>
<li>
<p>At the command line:</p>
<ul>
<li>
<p>Format entire projects with <code>air format .</code></p>
</li>
<li>
<p>Set up a git precommit hook to invoke Air before committing</p>
</li>
</ul>
</li>
<li>
<p>In CI:</p>
<ul>
<li>
<p>Use a GitHub Action to check that each PR conforms to formatting standards with <code>air format . --check</code><sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup></p>
</li>
<li>
<p>Use a GitHub Action to automatically format each PR by pushing the results of <code>air format</code> as a commit</p>
</li>
</ul>
</li>
</ul>
<p>We don&rsquo;t have guides for all of these use cases yet, but the best place to stay up to date is the <a href="https://posit-dev.github.io/air/" target="_blank" rel="noopener">Air website</a>
.</p>
<h2 id="how-is-this-different-from-styler">How is this different from styler?
</h2>
<p>Air would not exist without the preexisting work and dedication poured into <a href="https://github.com/r-lib/styler" target="_blank" rel="noopener">styler</a>
. Created by <a href="https://github.com/lorenzwalthert" target="_blank" rel="noopener">Lorenz Walthert</a>
 and <a href="https://github.com/krlmlr" target="_blank" rel="noopener">Kirill Müller</a>
, styler proved that the R community does care about how their code is formatted, and has been the primary implementation of the <a href="https://style.tidyverse.org/" target="_blank" rel="noopener">tidyverse style guide</a>
 for many years. We&rsquo;ve spoken to Lorenz about Air, and we are all very excited about what Air can do for the future of formatting in R.</p>
<p>Air is different from styler in a few key ways:</p>
<ul>
<li>
<p>Air is much faster. So much so that it enables new ways of using a formatter that were somewhat painful before, like formatting on every save, or formatting entire projects on every pull request.</p>
</li>
<li>
<p>Air is less configurable. As mentioned above, Air provides very few <a href="https://posit-dev.github.io/air/configuration.html" target="_blank" rel="noopener">configuration options</a>
.</p>
</li>
<li>
<p>Air respects a line width, with a default of 80 characters.</p>
</li>
<li>
<p>Air does not require R to run. Unlike styler, which is an R package, Air is written in Rust and is distributed as a pre-compiled binary for many platforms. This makes Air easy to use across IDEs or on CI with very little setup required.</p>
</li>
</ul>
<h2 id="how-fast-is-extremely-fast">How fast is &ldquo;extremely fast&rdquo;?
</h2>
<p>Air is written in Rust using the formatting infrastructure provided by <a href="https://github.com/biomejs/biome" target="_blank" rel="noopener">Biome</a>
<sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup>. This is also the same infrastructure that <a href="https://github.com/astral-sh/ruff" target="_blank" rel="noopener">Ruff</a>
, the fast Python formatter, originally forked from. Both of those projects are admired for their performance, and Air is no exception.</p>
<p>One goal for Air is for &ldquo;format on save&rdquo; to be imperceptibly fast, encouraging you to keep it on at all times. Benchmarking formatters is a bit hand wavy due to some having built in caching, so bear with me, but one way to proxy this performance is by formatting a large single file, for example the 800+ line <a href="https://github.com/tidyverse/dplyr/blob/main/R/join.R" target="_blank" rel="noopener">join.R</a>
 in dplyr. Formatting this takes<sup id="fnref:3"><a href="#fn:3" class="footnote-ref" role="doc-noteref">3</a></sup>:</p>
<ul>
<li>
<p>0.01 seconds with Air</p>
</li>
<li>
<p>1 second with styler (no cache)</p>
</li>
</ul>
<p>So, ~100x faster for Air! If you make a few changes in the file after the first round of formatting and run the formatter again, then you get something like:</p>
<ul>
<li>
<p>0.01 seconds with Air</p>
</li>
<li>
<p>0.5 seconds with styler (with cache)</p>
</li>
</ul>
<p>Half a second for styler might not sound that bad (and indeed, for a formatter written in R it&rsquo;s pretty good), but it&rsquo;s slow enough that you&rsquo;ll &ldquo;feel&rdquo; it if you try and invoke styler on every save. But 0.01 seconds? You&rsquo;ll never even know its running!</p>
<p>The differences get even more drastic if you format entire projects. Formatting the ~150 R files in dplyr takes<sup id="fnref:4"><a href="#fn:4" class="footnote-ref" role="doc-noteref">4</a></sup>:</p>
<ul>
<li>
<p>0.3 seconds with Air</p>
</li>
<li>
<p>100 seconds with styler</p>
</li>
</ul>
<p>Over 300x faster!</p>
<p>Out of curiosity, we also ran Air over all ~900 R files in base R and it finished in under 2 seconds.</p>
<h2 id="wrapping-up">Wrapping up
</h2>
<p>By contributing this formatter to the R community, our objective is threefold:</p>
<ul>
<li>
<p>Vastly improve your enjoyment of writing well-styled R code by removing the chore of editing whitespace.</p>
</li>
<li>
<p>Reduce friction in collaborative projects by establishing a consistent style once and for all.</p>
</li>
<li>
<p>Improve the overall readability of R code for the community.</p>
</li>
</ul>
<p>We hope that Air will prove to be a valuable companion in your daily workflow!</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>The Shiny team already has a <a href="https://github.com/rstudio/shiny-workflows/tree/main/format-r-code" target="_blank" rel="noopener">GitHub Action</a>
 to help with this. We will likely work on refining this and incorporating it more officially into an Air or r-lib repository.&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:2">
<p>Biome is an open source project maintained by community members, please consider <a href="https://github.com/sponsors/biomejs#sponsors" target="_blank" rel="noopener">sponsoring them</a>
!&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:3">
<p>These benchmarks were run with <code>air format R/join.R</code> and <code>styler::style_file(&quot;R/join.R&quot;)</code>.&#160;<a href="#fnref:3" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:4">
<p>With <code>air format .</code> and <a href="https://styler.r-lib.org/reference/style_pkg.html" target="_blank" rel="noopener"><code>styler::style_pkg()</code></a>
&#160;<a href="#fnref:4" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></description>
      <enclosure url="https://posit-open-source.netlify.app/blog/tidyverse/air/thumbnail-wd.jpg" length="162536" type="image/jpeg" />
    </item>
    <item>
      <title>nanoparquet 0.4.0</title>
      <link>https://posit-open-source.netlify.app/blog/tidyverse/2025/nanoparquet-0-4-0/</link>
      <pubDate>Tue, 28 Jan 2025 00:00:00 +0000</pubDate>
      <guid>https://posit-open-source.netlify.app/blog/tidyverse/2025/nanoparquet-0-4-0/</guid>
      <dc:creator>Gábor Csárdi</dc:creator><description><![CDATA[<!--
TODO:
* [x] Look over / edit the post's title in the yaml
* [x] Edit (or delete) the description; note this appears in the Twitter card
* [x] Pick category and tags (see existing with [`hugodown::tidy_show_meta()`](https://rdrr.io/pkg/hugodown/man/use_tidy_post.html))
* [x] Find photo & update yaml metadata
* [x] Create `thumbnail-sq.jpg`; height and width should be equal
* [x] Create `thumbnail-wd.jpg`; width should be >5x height
* [x] [`hugodown::use_tidy_thumbnails()`](https://rdrr.io/pkg/hugodown/man/use_tidy_post.html)
* [x] Add intro sentence, e.g. the standard tagline for the package
* [x] [`usethis::use_tidy_thanks()`](https://usethis.r-lib.org/reference/use_tidy_thanks.html)
-->
<p>We&rsquo;re thrilled to announce the release of <a href="https://nanoparquet.r-lib.org/" target="_blank" rel="noopener">nanoparquet</a>
 0.4.0. nanoparquet is an R package that reads and writes Parquet files.</p>
<p>You can install it from CRAN with:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="nf">install.packages</span><span class="p">(</span><span class="s">&#34;nanoparquet&#34;</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>This blog post will show the most important new features of nanoparquet 0.4.0: You can see a full list of changes in the <a href="https://nanoparquet.r-lib.org/news/index.html#nanoparquet-040" target="_blank" rel="noopener">release notes</a>
.</p>
<h2 id="brand-new-read_parquet">Brand new <code>read_parquet()</code>
</h2>
<p>nanoparquet 0.4.0 comes with a completely rewritten Parquet reader. The new version has an architecture that is easier to embed into R, and facilitates fantastic new features, like <a href="https://nanoparquet.r-lib.org/reference/append_parquet.html" target="_blank" rel="noopener"><code>append_parquet()</code></a>
 and the new <code>col_select</code> argument. (More to come!) The new reader is also much faster, see the &ldquo;Benchmarks&rdquo; chapter.</p>
<h2 id="read-a-subset-of-columns">Read a subset of columns
</h2>
<p><a href="https://nanoparquet.r-lib.org/reference/read_parquet.html" target="_blank" rel="noopener"><code>read_parquet()</code></a>
 now has a new argument called <code>col_select</code>, that lets you read a subset of the columns from the Parquet file. Unlike for row oriented file formats like CSV, this means that the reader never needs to touch the columns that are not needed for. The time required for reading a subset of columns is independent of how many more columns the Parquet file might have!</p>
<p>You can either use column indices or column names to specify the columns to read. Here is an example.</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='kr'><a href='https://rdrr.io/r/base/library.html'>library</a></span><span class='o'>(</span><span class='nv'><a href='https://github.com/r-lib/nanoparquet'>nanoparquet</a></span><span class='o'>)</span></span>
<span><span class='kr'><a href='https://rdrr.io/r/base/library.html'>library</a></span><span class='o'>(</span><span class='nv'><a href='https://pillar.r-lib.org/'>pillar</a></span><span class='o'>)</span></span></code></pre>
</div>
<p>This is the <a href="https://rdrr.io/pkg/nycflights13/man/flights.html" target="_blank" rel="noopener"><code>nycflights13::flights</code></a>
 data set:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nf'><a href='https://nanoparquet.r-lib.org/reference/read_parquet.html'>read_parquet</a></span><span class='o'>(</span></span>
<span>  <span class='s'>"flights.parquet"</span>,</span>
<span>  col_select <span class='o'>=</span> <span class='nf'><a href='https://rdrr.io/r/base/c.html'>c</a></span><span class='o'>(</span><span class='s'>"dep_time"</span>, <span class='s'>"arr_time"</span>, <span class='s'>"carrier"</span><span class='o'>)</span></span>
<span><span class='o'>)</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># A data frame: 336,776 × 3</span></span></span>
<span><span class='c'>#&gt;    dep_time arr_time carrier</span></span>
<span><span class='c'>#&gt;       <span style='color: #555555; font-style: italic;'>&lt;int&gt;</span>    <span style='color: #555555; font-style: italic;'>&lt;int&gt;</span> <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>  </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 1</span>      517      830 UA     </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 2</span>      533      850 UA     </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 3</span>      542      923 AA     </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 4</span>      544     <span style='text-decoration: underline;'>1</span>004 B6     </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 5</span>      554      812 DL     </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 6</span>      554      740 UA     </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 7</span>      555      913 B6     </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 8</span>      557      709 EV     </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 9</span>      557      838 B6     </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>10</span>      558      753 AA     </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># ℹ 336,766 more rows</span></span></span>
<span></span></code></pre>
</div>
<p>Use <a href="https://nanoparquet.r-lib.org/reference/read_parquet_schema.html" target="_blank" rel="noopener"><code>read_parquet_schema()</code></a>
 if you want to see the structure of the Parquet file first:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nf'><a href='https://nanoparquet.r-lib.org/reference/read_parquet_schema.html'>read_parquet_schema</a></span><span class='o'>(</span><span class='s'>"flights.parquet"</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># A data frame: 20 × 12</span></span></span>
<span><span class='c'>#&gt;    file_name       name  r_type type  type_length repetition_type converted_type</span></span>
<span><span class='c'>#&gt;    <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>           <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span> <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>  <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>       <span style='color: #555555; font-style: italic;'>&lt;int&gt;</span> <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>           <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>         </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 1</span> flights.parquet sche… <span style='color: #BB0000;'>NA</span>     <span style='color: #BB0000;'>NA</span>             <span style='color: #BB0000;'>NA</span> <span style='color: #BB0000;'>NA</span>              <span style='color: #BB0000;'>NA</span>            </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 2</span> flights.parquet year  integ… INT32          <span style='color: #BB0000;'>NA</span> REQUIRED        INT_32        </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 3</span> flights.parquet month integ… INT32          <span style='color: #BB0000;'>NA</span> REQUIRED        INT_32        </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 4</span> flights.parquet day   integ… INT32          <span style='color: #BB0000;'>NA</span> REQUIRED        INT_32        </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 5</span> flights.parquet dep_… integ… INT32          <span style='color: #BB0000;'>NA</span> OPTIONAL        INT_32        </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 6</span> flights.parquet sche… integ… INT32          <span style='color: #BB0000;'>NA</span> REQUIRED        INT_32        </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 7</span> flights.parquet dep_… double DOUB…          <span style='color: #BB0000;'>NA</span> OPTIONAL        <span style='color: #BB0000;'>NA</span>            </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 8</span> flights.parquet arr_… integ… INT32          <span style='color: #BB0000;'>NA</span> OPTIONAL        INT_32        </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 9</span> flights.parquet sche… integ… INT32          <span style='color: #BB0000;'>NA</span> REQUIRED        INT_32        </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>10</span> flights.parquet arr_… double DOUB…          <span style='color: #BB0000;'>NA</span> OPTIONAL        <span style='color: #BB0000;'>NA</span>            </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>11</span> flights.parquet carr… chara… BYTE…          <span style='color: #BB0000;'>NA</span> REQUIRED        UTF8          </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>12</span> flights.parquet flig… integ… INT32          <span style='color: #BB0000;'>NA</span> REQUIRED        INT_32        </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>13</span> flights.parquet tail… chara… BYTE…          <span style='color: #BB0000;'>NA</span> OPTIONAL        UTF8          </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>14</span> flights.parquet orig… chara… BYTE…          <span style='color: #BB0000;'>NA</span> REQUIRED        UTF8          </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>15</span> flights.parquet dest  chara… BYTE…          <span style='color: #BB0000;'>NA</span> REQUIRED        UTF8          </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>16</span> flights.parquet air_… double DOUB…          <span style='color: #BB0000;'>NA</span> OPTIONAL        <span style='color: #BB0000;'>NA</span>            </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>17</span> flights.parquet dist… double DOUB…          <span style='color: #BB0000;'>NA</span> REQUIRED        <span style='color: #BB0000;'>NA</span>            </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>18</span> flights.parquet hour  double DOUB…          <span style='color: #BB0000;'>NA</span> REQUIRED        <span style='color: #BB0000;'>NA</span>            </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>19</span> flights.parquet minu… double DOUB…          <span style='color: #BB0000;'>NA</span> REQUIRED        <span style='color: #BB0000;'>NA</span>            </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>20</span> flights.parquet time… POSIX… INT64          <span style='color: #BB0000;'>NA</span> REQUIRED        TIMESTAMP_MIC…</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># ℹ 5 more variables: logical_type &lt;I&lt;list&gt;&gt;, num_children &lt;int&gt;, scale &lt;int&gt;,</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>#   precision &lt;int&gt;, field_id &lt;int&gt;</span></span></span>
<span></span></code></pre>
</div>
<p>The output of <a href="https://nanoparquet.r-lib.org/reference/read_parquet_schema.html" target="_blank" rel="noopener"><code>read_parquet_schema()</code></a>
 also shows you the R type that nanoparquet will use for each column.</p>
<h2 id="appending-to-parquet-files">Appending to Parquet files
</h2>
<p>The new <a href="https://nanoparquet.r-lib.org/reference/append_parquet.html" target="_blank" rel="noopener"><code>append_parquet()</code></a>
 function makes it easy to append new data to a Parquet file, without first reading the whole file into memory. The schema of the file and the schema new data must match of course. Lets merge <a href="https://rdrr.io/pkg/nycflights13/man/flights.html" target="_blank" rel="noopener"><code>nycflights13::flights</code></a>
 and <a href="https://moderndive.github.io/nycflights23/reference/flights.html" target="_blank" rel="noopener"><code>nycflights23::flights</code></a>
:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nf'><a href='https://rdrr.io/r/base/files.html'>file.copy</a></span><span class='o'>(</span><span class='s'>"flights.parquet"</span>, <span class='s'>"allflights.parquet"</span>, overwrite <span class='o'>=</span> <span class='kc'>TRUE</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; [1] TRUE</span></span>
<span></span><span><span class='nf'><a href='https://nanoparquet.r-lib.org/reference/append_parquet.html'>append_parquet</a></span><span class='o'>(</span><span class='nf'>nycflights23</span><span class='nf'>::</span><span class='nv'><a href='https://moderndive.github.io/nycflights23/reference/flights.html'>flights</a></span>, <span class='s'>"allflights.parquet"</span><span class='o'>)</span></span></code></pre>
</div>
<p><a href="https://nanoparquet.r-lib.org/reference/read_parquet_info.html" target="_blank" rel="noopener"><code>read_parquet_info()</code></a>
 returns the most basic information about a Parquet file:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nf'><a href='https://nanoparquet.r-lib.org/reference/read_parquet_info.html'>read_parquet_info</a></span><span class='o'>(</span><span class='s'>"flights.parquet"</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># A data frame: 1 × 7</span></span></span>
<span><span class='c'>#&gt;   file_name       num_cols num_rows num_row_groups file_size parquet_version</span></span>
<span><span class='c'>#&gt;   <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>              <span style='color: #555555; font-style: italic;'>&lt;int&gt;</span>    <span style='color: #555555; font-style: italic;'>&lt;dbl&gt;</span>          <span style='color: #555555; font-style: italic;'>&lt;int&gt;</span>     <span style='color: #555555; font-style: italic;'>&lt;dbl&gt;</span>           <span style='color: #555555; font-style: italic;'>&lt;int&gt;</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>1</span> flights.parquet       19   <span style='text-decoration: underline;'>336</span>776              1   5<span style='text-decoration: underline;'>687</span>737               1</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># ℹ 1 more variable: created_by &lt;chr&gt;</span></span></span>
<span></span><span><span class='nf'><a href='https://nanoparquet.r-lib.org/reference/read_parquet_info.html'>read_parquet_info</a></span><span class='o'>(</span><span class='s'>"allflights.parquet"</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># A data frame: 1 × 7</span></span></span>
<span><span class='c'>#&gt;   file_name          num_cols num_rows num_row_groups file_size parquet_version</span></span>
<span><span class='c'>#&gt;   <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>                 <span style='color: #555555; font-style: italic;'>&lt;int&gt;</span>    <span style='color: #555555; font-style: italic;'>&lt;dbl&gt;</span>          <span style='color: #555555; font-style: italic;'>&lt;int&gt;</span>     <span style='color: #555555; font-style: italic;'>&lt;dbl&gt;</span>           <span style='color: #555555; font-style: italic;'>&lt;int&gt;</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>1</span> allflights.parquet       19   <span style='text-decoration: underline;'>772</span>128              1  13<span style='text-decoration: underline;'>490</span>997               1</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># ℹ 1 more variable: created_by &lt;chr&gt;</span></span></span>
<span></span></code></pre>
</div>
<p>Note that you should probably still create a backup copy of the original file when using <a href="https://nanoparquet.r-lib.org/reference/append_parquet.html" target="_blank" rel="noopener"><code>append_parquet()</code></a>
. If the appending process is interrupted by a power failure, then you might end up with an incomplete and invalid Parquet file.</p>
<h2 id="schemas-and-type-conversions">Schemas and type conversions
</h2>
<p>In nanoparquet 0.4.0 <a href="https://nanoparquet.r-lib.org/reference/write_parquet.html" target="_blank" rel="noopener"><code>write_parquet()</code></a>
 takes a <code>schema</code> argument that can customize the R to Parquet type mappings. For example by default <a href="https://nanoparquet.r-lib.org/reference/write_parquet.html" target="_blank" rel="noopener"><code>write_parquet()</code></a>
 writes an R character vector as a <code>STRING</code> Parquet type. If you&rsquo;d like to write a certain character column as an <code>ENUM</code> type<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup> instead, you&rsquo;ll need to specify that in <code>schema</code>:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nf'><a href='https://nanoparquet.r-lib.org/reference/write_parquet.html'>write_parquet</a></span><span class='o'>(</span></span>
<span>  <span class='nf'>nycflights13</span><span class='nf'>::</span><span class='nv'><a href='https://rdrr.io/pkg/nycflights13/man/flights.html'>flights</a></span>,</span>
<span>  <span class='s'>"newflights.parquet"</span>,</span>
<span>  schema <span class='o'>=</span> <span class='nf'><a href='https://nanoparquet.r-lib.org/reference/parquet_schema.html'>parquet_schema</a></span><span class='o'>(</span>carrier <span class='o'>=</span> <span class='s'>"ENUM"</span><span class='o'>)</span></span>
<span><span class='o'>)</span></span>
<span><span class='nf'><a href='https://nanoparquet.r-lib.org/reference/read_parquet_schema.html'>read_parquet_schema</a></span><span class='o'>(</span><span class='s'>"newflights.parquet"</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># A data frame: 20 × 12</span></span></span>
<span><span class='c'>#&gt;    file_name       name  r_type type  type_length repetition_type converted_type</span></span>
<span><span class='c'>#&gt;    <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>           <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span> <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>  <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>       <span style='color: #555555; font-style: italic;'>&lt;int&gt;</span> <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>           <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>         </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 1</span> newflights.par… sche… <span style='color: #BB0000;'>NA</span>     <span style='color: #BB0000;'>NA</span>             <span style='color: #BB0000;'>NA</span> <span style='color: #BB0000;'>NA</span>              <span style='color: #BB0000;'>NA</span>            </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 2</span> newflights.par… year  integ… INT32          <span style='color: #BB0000;'>NA</span> REQUIRED        INT_32        </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 3</span> newflights.par… month integ… INT32          <span style='color: #BB0000;'>NA</span> REQUIRED        INT_32        </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 4</span> newflights.par… day   integ… INT32          <span style='color: #BB0000;'>NA</span> REQUIRED        INT_32        </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 5</span> newflights.par… dep_… integ… INT32          <span style='color: #BB0000;'>NA</span> OPTIONAL        INT_32        </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 6</span> newflights.par… sche… integ… INT32          <span style='color: #BB0000;'>NA</span> REQUIRED        INT_32        </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 7</span> newflights.par… dep_… double DOUB…          <span style='color: #BB0000;'>NA</span> OPTIONAL        <span style='color: #BB0000;'>NA</span>            </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 8</span> newflights.par… arr_… integ… INT32          <span style='color: #BB0000;'>NA</span> OPTIONAL        INT_32        </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 9</span> newflights.par… sche… integ… INT32          <span style='color: #BB0000;'>NA</span> REQUIRED        INT_32        </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>10</span> newflights.par… arr_… double DOUB…          <span style='color: #BB0000;'>NA</span> OPTIONAL        <span style='color: #BB0000;'>NA</span>            </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>11</span> newflights.par… carr… chara… BYTE…          <span style='color: #BB0000;'>NA</span> REQUIRED        ENUM          </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>12</span> newflights.par… flig… integ… INT32          <span style='color: #BB0000;'>NA</span> REQUIRED        INT_32        </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>13</span> newflights.par… tail… chara… BYTE…          <span style='color: #BB0000;'>NA</span> OPTIONAL        UTF8          </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>14</span> newflights.par… orig… chara… BYTE…          <span style='color: #BB0000;'>NA</span> REQUIRED        UTF8          </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>15</span> newflights.par… dest  chara… BYTE…          <span style='color: #BB0000;'>NA</span> REQUIRED        UTF8          </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>16</span> newflights.par… air_… double DOUB…          <span style='color: #BB0000;'>NA</span> OPTIONAL        <span style='color: #BB0000;'>NA</span>            </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>17</span> newflights.par… dist… double DOUB…          <span style='color: #BB0000;'>NA</span> REQUIRED        <span style='color: #BB0000;'>NA</span>            </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>18</span> newflights.par… hour  double DOUB…          <span style='color: #BB0000;'>NA</span> REQUIRED        <span style='color: #BB0000;'>NA</span>            </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>19</span> newflights.par… minu… double DOUB…          <span style='color: #BB0000;'>NA</span> REQUIRED        <span style='color: #BB0000;'>NA</span>            </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>20</span> newflights.par… time… POSIX… INT64          <span style='color: #BB0000;'>NA</span> REQUIRED        TIMESTAMP_MIC…</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># ℹ 5 more variables: logical_type &lt;I&lt;list&gt;&gt;, num_children &lt;int&gt;, scale &lt;int&gt;,</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>#   precision &lt;int&gt;, field_id &lt;int&gt;</span></span></span>
<span></span></code></pre>
</div>
<p>Here we wrote the <code>carrier</code> column as <code>ENUM</code>, and left the other other columns to use the default type mappings.</p>
<p>See the <a href="https://nanoparquet.r-lib.org/reference/nanoparquet-types.html#r-s-data-types" target="_blank" rel="noopener"><code>?nanoparquet-types</code></a>
 manual page for the possible type mappings (lots of new ones!) and also for the default ones.</p>
<h2 id="encodings">Encodings
</h2>
<p>It is now also possible to customize the encoding of each column in <a href="https://nanoparquet.r-lib.org/reference/write_parquet.html" target="_blank" rel="noopener"><code>write_parquet()</code></a>
, via the <code>encoding</code> argument. By default <a href="https://nanoparquet.r-lib.org/reference/write_parquet.html" target="_blank" rel="noopener"><code>write_parquet()</code></a>
 tries to choose a good encoding based on the type and the values of a column. E.g. it checks a small sample for repeated values to decide if it is worth using a dictionary encoding (<code>RLE_DICTIONARY</code>).</p>
<p>If <a href="https://nanoparquet.r-lib.org/reference/write_parquet.html" target="_blank" rel="noopener"><code>write_parquet()</code></a>
 gets it wrong, use the <code>encoding</code> argument to force an encoding. The following forces the <code>PLAIN</code> encoding for all columns. This encoding is very fast to write, but creates a larger file. You can also specify different encodings for different columns, see the <a href="https://nanoparquet.r-lib.org/reference/write_parquet.html" target="_blank" rel="noopener"><code>write_parquet()</code> manual page</a>
.</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nf'><a href='https://nanoparquet.r-lib.org/reference/write_parquet.html'>write_parquet</a></span><span class='o'>(</span></span>
<span>  <span class='nf'>nycflights13</span><span class='nf'>::</span><span class='nv'><a href='https://rdrr.io/pkg/nycflights13/man/flights.html'>flights</a></span>,</span>
<span>  <span class='s'>"plainflights.parquet"</span>,</span>
<span>  encoding <span class='o'>=</span> <span class='s'>"PLAIN"</span></span>
<span><span class='o'>)</span></span>
<span><span class='nf'><a href='https://rdrr.io/r/base/file.info.html'>file.size</a></span><span class='o'>(</span><span class='s'>"flights.parquet"</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; [1] 5687737</span></span>
<span></span><span><span class='nf'><a href='https://rdrr.io/r/base/file.info.html'>file.size</a></span><span class='o'>(</span><span class='s'>"plainflights.parquet"</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; [1] 11954574</span></span>
<span></span></code></pre>
</div>
<p>See more about the implemented encodings and how the defaults are selected in the <a href="https://nanoparquet.r-lib.org/reference/parquet-encodings.html" target="_blank" rel="noopener"><code>parquet-encodings</code> manual page</a>
.</p>
<h2 id="api-changes">API changes
</h2>
<p>Some nanoparquet functions have new, better names in nanoparquet 0.4.0. In particular, all functions that read from a Parquet file have a <code>read_parquet</code> prefix now. The old functions still work, with a warning.</p>
<p>Also, the <a href="https://nanoparquet.r-lib.org/reference/parquet_schema.html" target="_blank" rel="noopener"><code>parquet_schema()</code></a>
 function is now for creating a new Parquet schema from scratch, and not for inferring a schema from a data frame (use <a href="https://nanoparquet.r-lib.org/reference/infer_parquet_schema.html" target="_blank" rel="noopener"><code>infer_parquet_schema()</code></a>
) or for reading the schema from a Parquet file (use <a href="https://nanoparquet.r-lib.org/reference/read_parquet_schema.html" target="_blank" rel="noopener"><code>read_parquet_schema()</code></a>
). <a href="https://nanoparquet.r-lib.org/reference/parquet_schema.html" target="_blank" rel="noopener"><code>parquet_schema()</code></a>
 falls back to the old behaviour when called with a file name, with a warning, so this is not a breaking change (yet), and old code still works.</p>
<p>See the complete list of API changes in the <a href="https://nanoparquet.r-lib.org/news/index.html" target="_blank" rel="noopener">Changelog</a>
.</p>
<h2 id="benchmarks">Benchmarks
</h2>
<p>We are very excited about the performance of the new Parquet reader, and the Parquet writer was always quite speedy, so we ran a simple benchmark.</p>
<p>We compared nanoparquet to the Parquet implementations in Apache Arrow and DuckDB, and also to CSV readers and writers, on a real data set, for samples of 330k, 6.7 million and 67.4 million rows (40MB, 800MB and 8GB in memory). For these data nanoparquet is indeed very competitive with both Arrow and DuckDB.</p>
<p>You can see the full results <a href="https://nanoparquet.r-lib.org/articles/benchmarks.html" target="_blank" rel="noopener">on the website</a>
.</p>
<h2 id="other-changes">Other changes
</h2>
<p>Other important changes in nanoparquet 0.4.0 include:</p>
<ul>
<li>
<p><a href="https://nanoparquet.r-lib.org/reference/write_parquet.html" target="_blank" rel="noopener"><code>write_parquet()</code></a>
 can now write multiple row groups. By default it puts at most 10 million rows in a single row group. (This is subject to <a href="https://nanoparquet.r-lib.org/references/parquet_options.html" target="_blank" rel="noopener">https://nanoparquet.r-lib.org/references/parquet_options.html</a>
 ) on how to change the default.</p>
</li>
<li>
<p><a href="https://nanoparquet.r-lib.org/reference/write_parquet.html" target="_blank" rel="noopener"><code>write_parquet()</code></a>
 now writes minimum and maximum statistics (by default) for most Parquet types. See the <a href="https://nanoparquet.r-lib.org/reference/parquet_options.html" target="_blank" rel="noopener"><code>parquet_options()</code> manual page</a>
 on how to turn this off, which will probably make the writer faster.</p>
</li>
<li>
<p><a href="https://nanoparquet.r-lib.org/reference/write_parquet.html" target="_blank" rel="noopener"><code>write_parquet()</code></a>
 can now write version 2 data pages. The default is still version 1, but it might change in the future.</p>
</li>
<li>
<p>New <code>compression_level</code> option to select the compression level manually.</p>
</li>
<li>
<p><a href="https://nanoparquet.r-lib.org/reference/read_parquet.html" target="_blank" rel="noopener"><code>read_parquet()</code></a>
 can now read from an R connection.</p>
</li>
</ul>
<h2 id="acknowledgements">Acknowledgements
</h2>
<p><a href="https://github.com/alvarocombo" target="_blank" rel="noopener">@alvarocombo</a>
, <a href="https://github.com/D3SL" target="_blank" rel="noopener">@D3SL</a>
, <a href="https://github.com/gaborcsardi" target="_blank" rel="noopener">@gaborcsardi</a>
, and <a href="https://github.com/RealTYPICAL" target="_blank" rel="noopener">@RealTYPICAL</a>
.</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>A Parquet <code>ENUM</code> type is very similar to a factor in R.&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></description>
      <enclosure url="https://posit-open-source.netlify.app/blog/tidyverse/2025/nanoparquet-0-4-0/thumbnail-wd.jpg" length="41011" type="image/jpeg" />
    </item>
    <item>
      <title>httr2 1.1.0</title>
      <link>https://posit-open-source.netlify.app/blog/tidyverse/2025/httr2-1-1-0/</link>
      <pubDate>Mon, 20 Jan 2025 00:00:00 +0000</pubDate>
      <guid>https://posit-open-source.netlify.app/blog/tidyverse/2025/httr2-1-1-0/</guid>
      <dc:creator>Hadley Wickham</dc:creator><description><![CDATA[<!--
TODO:
* [x] Look over / edit the post's title in the yaml
* [x] Edit (or delete) the description; note this appears in the Twitter card
* [x] Pick category and tags (see existing with [`hugodown::tidy_show_meta()`](https://rdrr.io/pkg/hugodown/man/use_tidy_post.html))
* [x] Find photo & update yaml metadata
* [x] Create `thumbnail-sq.jpg`; height and width should be equal
* [x] Create `thumbnail-wd.jpg`; width should be >5x height
* [x] [`hugodown::use_tidy_thumbnails()`](https://rdrr.io/pkg/hugodown/man/use_tidy_post.html)
* [x] Add intro sentence, e.g. the standard tagline for the package
* [x] [`usethis::use_tidy_thanks()`](https://usethis.r-lib.org/reference/use_tidy_thanks.html)
-->
<p>We&rsquo;re chuffed to announce the release of <a href="https://httr2.r-lib.org" target="_blank" rel="noopener">httr2 1.1.0</a>
. httr2 (pronounced &ldquo;hitter2&rdquo;) is a comprehensive HTTP client that provides a modern, pipeable API for working with web APIs. It builds on top of <a href="https://jeroen.r-universe.dev/curl" target="_blank" rel="noopener">{curl}</a>
 to provide features like explicit request objects, built-in rate limiting &amp; retry tooling, comprehensive OAuth support, and secure handling of secrets and credentials.</p>
<p>In this blog post, we&rsquo;ll dive into the new streaming interface built around <a href="https://httr2.r-lib.org/reference/req_perform_connection.html" target="_blank" rel="noopener"><code>req_perform_connection()</code></a>
, explore the new suite of URL manipulation tools, and highlight a few of the other biggest changes (including better support for AWS and enhancements to the caching system), and update you on the lifecycle changes.</p>
<p>This blog post includes the most important enhacenments in versions 1.0.1 through 1.0.7, where we&rsquo;ve been iterating on various features and fixing <em>numerous</em> bugs. For a complete list of changes, you can check the <a href="https://github.com/r-lib/httr2/releases" target="_blank" rel="noopener">GitHub release notes</a>
 or the <a href="https://httr2.r-lib.org/news/index.html" target="_blank" rel="noopener">NEWS file</a>
.</p>
<h2 id="installation">Installation
</h2>
<p>Install httr2 from CRAN with:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nf'><a href='https://rdrr.io/r/utils/install.packages.html'>install.packages</a></span><span class='o'>(</span><span class='s'>"httr2"</span><span class='o'>)</span></span></code></pre>
</div>
<h2 id="streaming-data">Streaming data
</h2>
<p>The headline feature of this release is a better API for streaming responses, where the body is not available immediately but is streamed back over time. This is particularly important for interacting with LLMs, where it&rsquo;s needed to make chat responses feel snappy. You can try it out in <a href="https://ellmer.tidyverse.org" target="_blank" rel="noopener">ellmer</a>
, our new package for chatting with LLMs from a variety of providers.</p>
<p>The most important new function is <a href="https://httr2.r-lib.org/reference/req_perform_connection.html" target="_blank" rel="noopener"><code>req_perform_connection()</code></a>
, which supersedes the older callback-based <a href="https://httr2.r-lib.org/reference/req_perform_stream.html" target="_blank" rel="noopener"><code>req_perform_stream()</code></a>
. Unlike its predecessor, <a href="https://httr2.r-lib.org/reference/req_perform_connection.html" target="_blank" rel="noopener"><code>req_perform_connection()</code></a>
 returns a regular response object with a connection object for the body:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='kr'><a href='https://rdrr.io/r/base/library.html'>library</a></span><span class='o'>(</span><span class='nv'><a href='https://httr2.r-lib.org'>httr2</a></span><span class='o'>)</span></span>
<span></span>
<span><span class='nv'>req</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://httr2.r-lib.org/reference/request.html'>request</a></span><span class='o'>(</span><span class='nf'><a href='https://httr2.r-lib.org/reference/example_url.html'>example_url</a></span><span class='o'>(</span><span class='o'>)</span><span class='o'>)</span> <span class='o'>|&gt;</span> <span class='nf'><a href='https://httr2.r-lib.org/reference/req_template.html'>req_template</a></span><span class='o'>(</span><span class='s'>"/stream-bytes/:n"</span>, n <span class='o'>=</span> <span class='m'>10240</span><span class='o'>)</span></span>
<span><span class='nv'>resp</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://httr2.r-lib.org/reference/req_perform_connection.html'>req_perform_connection</a></span><span class='o'>(</span><span class='nv'>req</span><span class='o'>)</span></span>
<span><span class='nv'>resp</span></span>
<span><span class='c'>#&gt; <span style='color: #0000BB;'>&lt;httr2_response&gt;</span></span></span>
<span></span><span><span class='c'>#&gt; <span style='font-weight: bold;'>GET</span> http://127.0.0.1:49283/stream-bytes/10240</span></span>
<span></span><span><span class='c'>#&gt; <span style='color: #00BB00;'>Status</span>: 200 OK</span></span>
<span></span><span><span class='c'>#&gt; <span style='color: #00BB00;'>Content-Type</span>: application/octet-stream</span></span>
<span></span><span><span class='c'>#&gt; <span style='color: #00BB00;'>Body</span>: Streaming connection</span></span>
<span></span></code></pre>
</div>
<p>Once you have a streaming connection you can repeatedly call a <code>resp_stream_*()</code> function to pull down data in chunks, using <a href="https://httr2.r-lib.org/reference/resp_stream_raw.html" target="_blank" rel="noopener"><code>resp_stream_is_complete()</code></a>
 to figure out when to stop.</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='kr'>while</span> <span class='o'>(</span><span class='o'>!</span><span class='nf'><a href='https://httr2.r-lib.org/reference/resp_stream_raw.html'>resp_stream_is_complete</a></span><span class='o'>(</span><span class='nv'>resp</span><span class='o'>)</span><span class='o'>)</span> <span class='o'>&#123;</span></span>
<span>  <span class='nv'>bytes</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://httr2.r-lib.org/reference/resp_stream_raw.html'>resp_stream_raw</a></span><span class='o'>(</span><span class='nv'>resp</span>, kb <span class='o'>=</span> <span class='m'>2</span><span class='o'>)</span></span>
<span>  <span class='nf'><a href='https://rdrr.io/r/base/cat.html'>cat</a></span><span class='o'>(</span><span class='s'>"Downloaded "</span>, <span class='nf'><a href='https://rdrr.io/r/base/length.html'>length</a></span><span class='o'>(</span><span class='nv'>bytes</span><span class='o'>)</span>, <span class='s'>" bytes\n"</span>, sep <span class='o'>=</span> <span class='s'>""</span><span class='o'>)</span></span>
<span><span class='o'>&#125;</span></span>
<span><span class='c'>#&gt; Downloaded 2048 bytes</span></span>
<span><span class='c'>#&gt; Downloaded 2048 bytes</span></span>
<span><span class='c'>#&gt; Downloaded 2048 bytes</span></span>
<span><span class='c'>#&gt; Downloaded 2048 bytes</span></span>
<span><span class='c'>#&gt; Downloaded 2048 bytes</span></span>
<span><span class='c'>#&gt; Downloaded 0 bytes</span></span>
<span></span></code></pre>
</div>
<p>As well as <a href="https://httr2.r-lib.org/reference/resp_stream_raw.html" target="_blank" rel="noopener"><code>resp_stream_raw()</code></a>
, which returns a raw vector, you can use <a href="https://httr2.r-lib.org/reference/resp_stream_raw.html" target="_blank" rel="noopener"><code>resp_stream_lines()</code></a>
 to stream lines and <a href="https://httr2.r-lib.org/reference/resp_stream_raw.html" target="_blank" rel="noopener"><code>resp_stream_sse()</code></a>
 to stream <a href="https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events" target="_blank" rel="noopener">server-sent events</a>
.</p>
<h2 id="url-manipulation-tools">URL manipulation tools
</h2>
<p>Working with URLs got easier with three new functions: <a href="https://httr2.r-lib.org/reference/url_modify.html" target="_blank" rel="noopener"><code>url_modify()</code></a>
, <a href="https://httr2.r-lib.org/reference/url_modify.html" target="_blank" rel="noopener"><code>url_modify_query()</code></a>
, and <a href="https://httr2.r-lib.org/reference/url_modify.html" target="_blank" rel="noopener"><code>url_modify_relative()</code></a>
. You can see how they work in the examples below:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='c'># url_modify() modifies components of a URL</span></span>
<span><span class='nf'><a href='https://httr2.r-lib.org/reference/url_modify.html'>url_modify</a></span><span class='o'>(</span><span class='s'>"https://example.com"</span>, hostname <span class='o'>=</span> <span class='s'>"github.com"</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; [1] "https://github.com/"</span></span>
<span></span><span><span class='nf'><a href='https://httr2.r-lib.org/reference/url_modify.html'>url_modify</a></span><span class='o'>(</span><span class='s'>"https://example.com"</span>, scheme <span class='o'>=</span> <span class='s'>"http"</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; [1] "http://example.com/"</span></span>
<span></span><span><span class='nf'><a href='https://httr2.r-lib.org/reference/url_modify.html'>url_modify</a></span><span class='o'>(</span><span class='s'>"https://example.com"</span>, path <span class='o'>=</span> <span class='s'>"abc"</span>, query <span class='o'>=</span> <span class='nf'><a href='https://rdrr.io/r/base/list.html'>list</a></span><span class='o'>(</span>foo <span class='o'>=</span> <span class='s'>"bar"</span><span class='o'>)</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; [1] "https://example.com/abc?foo=bar"</span></span>
<span></span><span></span>
<span><span class='c'># url_modify_query() lets you modify individual query parameters</span></span>
<span><span class='c'># modifying an existing parameter:</span></span>
<span><span class='nf'><a href='https://httr2.r-lib.org/reference/url_modify.html'>url_modify_query</a></span><span class='o'>(</span><span class='s'>"http://example.com?a=1&amp;b=2"</span>, a <span class='o'>=</span> <span class='m'>10</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; [1] "http://example.com/?b=2&amp;a=10"</span></span>
<span></span><span><span class='c'># delete a parameter:</span></span>
<span><span class='nf'><a href='https://httr2.r-lib.org/reference/url_modify.html'>url_modify_query</a></span><span class='o'>(</span><span class='s'>"http://example.com?a=1&amp;b=2"</span>, b <span class='o'>=</span> <span class='kc'>NULL</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; [1] "http://example.com/?a=1"</span></span>
<span></span><span><span class='c'># add a new parameter:</span></span>
<span><span class='nf'><a href='https://httr2.r-lib.org/reference/url_modify.html'>url_modify_query</a></span><span class='o'>(</span><span class='s'>"http://example.com?a=1&amp;b=2"</span>, c <span class='o'>=</span> <span class='m'>3</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; [1] "http://example.com/?a=1&amp;b=2&amp;c=3"</span></span>
<span></span><span></span>
<span><span class='c'># url_modify_relative() navigates to a relative URL</span></span>
<span><span class='nf'><a href='https://httr2.r-lib.org/reference/url_modify.html'>url_modify_relative</a></span><span class='o'>(</span><span class='s'>"https://example.com/a/b/c.html"</span>, <span class='s'>"/d/e/f.html"</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; [1] "https://example.com/d/e/f.html"</span></span>
<span></span><span><span class='nf'><a href='https://httr2.r-lib.org/reference/url_modify.html'>url_modify_relative</a></span><span class='o'>(</span><span class='s'>"https://example.com/a/b/c.html"</span>, <span class='s'>"C.html"</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; [1] "https://example.com/a/b/C.html"</span></span>
<span></span><span><span class='nf'><a href='https://httr2.r-lib.org/reference/url_modify.html'>url_modify_relative</a></span><span class='o'>(</span><span class='s'>"https://example.com/a/b/c.html"</span>, <span class='s'>"../B.html"</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; [1] "https://example.com/a/B.html"</span></span>
<span></span></code></pre>
</div>
<p>We also added <a href="https://httr2.r-lib.org/reference/req_url.html" target="_blank" rel="noopener"><code>req_url_relative()</code></a>
 to make it easier to navigate to a relative URL for an existing request.</p>
<h2 id="other-improvements">Other improvements
</h2>
<p>There are a handful of other improvements that are worth highlighting:</p>
<ul>
<li>
<p>We&rsquo;ve made it easier to talk to AWS web services with <a href="https://httr2.r-lib.org/reference/req_auth_aws_v4.html" target="_blank" rel="noopener"><code>req_auth_aws_v4()</code></a>
 for signing requests and <a href="https://httr2.r-lib.org/reference/resp_stream_raw.html" target="_blank" rel="noopener"><code>resp_stream_aws()</code></a>
 for streaming responses. Special thanks goes to the <a href="https://github.com/lifion/lifion-aws-event-stream/" target="_blank" rel="noopener">lifion-aws-event-stream</a>
 project for providing a clear reference implementation.</p>
</li>
<li>
<p>We&rsquo;ve run-down a long list of bugs that made <a href="https://httr2.r-lib.org/reference/req_cache.html" target="_blank" rel="noopener"><code>req_cache()</code></a>
 unreliable. This includes improving the handling of header-only changes, better cache pruning, and new debugging options. If you&rsquo;re working with a web API that supports caching, we highly recommend that you try it out. The next release of {<a href="https://github.com/r-lib/gh" target="_blank" rel="noopener">gh</a>
} will use a cache by default, and my use of the dev version suggests that it gives a pretty nice performance improvment.</p>
</li>
<li>
<p><a href="https://httr2.r-lib.org/reference/is_online.html" target="_blank" rel="noopener"><code>is_online()</code></a>
 provides an easy way to check internet connectivity.</p>
</li>
<li>
<p><a href="https://httr2.r-lib.org/reference/req_perform_promise.html" target="_blank" rel="noopener"><code>req_perform_promise()</code></a>
 allows you to execute requests in the background (thanks to <a href="https://github.com/gergness" target="_blank" rel="noopener">@gergness</a>
) using an efficient approach that waits on curl socket activity (thanks to <a href="https://github.com/shikokuchuo" target="_blank" rel="noopener">@shikokuchuo</a>
).</p>
</li>
</ul>
<h2 id="breaking-changes">Breaking changes
</h2>
<p>As httr2 continues to mature, we&rsquo;ve made some lifecycle changes:</p>
<ul>
<li><a href="https://httr2.r-lib.org/reference/req_perform_iterative.html" target="_blank" rel="noopener"><code>req_perform_iterative()</code></a>
 is now stable and no longer experimental.</li>
<li><a href="https://httr2.r-lib.org/reference/req_perform_stream.html" target="_blank" rel="noopener"><code>req_perform_stream()</code></a>
 is superseded by <a href="https://httr2.r-lib.org/reference/req_perform_connection.html" target="_blank" rel="noopener"><code>req_perform_connection()</code></a>
, as mentioned above.</li>
<li><a href="https://httr2.r-lib.org/reference/with_mocked_responses.html" target="_blank" rel="noopener"><code>with_mock()</code></a>
 and <a href="https://httr2.r-lib.org/reference/with_mocked_responses.html" target="_blank" rel="noopener"><code>local_mock()</code></a>
 are defunct and will be rmeoved in the next release. Use <a href="https://httr2.r-lib.org/reference/with_mocked_responses.html" target="_blank" rel="noopener"><code>with_mocked_responses()</code></a>
 and <a href="https://httr2.r-lib.org/reference/with_mocked_responses.html" target="_blank" rel="noopener"><code>local_mocked_responses()</code></a>
 instead.</li>
</ul>
<h2 id="acknowledgements">Acknowledgements
</h2>
<p>A big thanks to all 76 folks who filed issues, created PRs and generally helped to make httr2 better! <a href="https://github.com/Aariq" target="_blank" rel="noopener">@Aariq</a>
, <a href="https://github.com/AGeographer" target="_blank" rel="noopener">@AGeographer</a>
, <a href="https://github.com/amael-ls" target="_blank" rel="noopener">@amael-ls</a>
, <a href="https://github.com/anishjoni" target="_blank" rel="noopener">@anishjoni</a>
, <a href="https://github.com/asadow" target="_blank" rel="noopener">@asadow</a>
, <a href="https://github.com/atheriel" target="_blank" rel="noopener">@atheriel</a>
, <a href="https://github.com/awpsoras" target="_blank" rel="noopener">@awpsoras</a>
, <a href="https://github.com/billsanto" target="_blank" rel="noopener">@billsanto</a>
, <a href="https://github.com/bonushenricus" target="_blank" rel="noopener">@bonushenricus</a>
, <a href="https://github.com/botan" target="_blank" rel="noopener">@botan</a>
, <a href="https://github.com/burgerga" target="_blank" rel="noopener">@burgerga</a>
, <a href="https://github.com/CareCT" target="_blank" rel="noopener">@CareCT</a>
, <a href="https://github.com/cderv" target="_blank" rel="noopener">@cderv</a>
, <a href="https://github.com/cole-brokamp" target="_blank" rel="noopener">@cole-brokamp</a>
, <a href="https://github.com/covid19ec" target="_blank" rel="noopener">@covid19ec</a>
, <a href="https://github.com/datapumpernickel" target="_blank" rel="noopener">@datapumpernickel</a>
, <a href="https://github.com/denskh" target="_blank" rel="noopener">@denskh</a>
, <a href="https://github.com/deschen1" target="_blank" rel="noopener">@deschen1</a>
, <a href="https://github.com/DyfanJones" target="_blank" rel="noopener">@DyfanJones</a>
, <a href="https://github.com/erydit" target="_blank" rel="noopener">@erydit</a>
, <a href="https://github.com/exetico" target="_blank" rel="noopener">@exetico</a>
, <a href="https://github.com/fh-mthomson" target="_blank" rel="noopener">@fh-mthomson</a>
, <a href="https://github.com/frzambra" target="_blank" rel="noopener">@frzambra</a>
, <a href="https://github.com/gergness" target="_blank" rel="noopener">@gergness</a>
, <a href="https://github.com/GreenGrassBlueOcean" target="_blank" rel="noopener">@GreenGrassBlueOcean</a>
, <a href="https://github.com/guslipkin" target="_blank" rel="noopener">@guslipkin</a>
, <a href="https://github.com/hadley" target="_blank" rel="noopener">@hadley</a>
, <a href="https://github.com/i2z1" target="_blank" rel="noopener">@i2z1</a>
, <a href="https://github.com/isachng93" target="_blank" rel="noopener">@isachng93</a>
, <a href="https://github.com/IshuaWang" target="_blank" rel="noopener">@IshuaWang</a>
, <a href="https://github.com/JamesHWade" target="_blank" rel="noopener">@JamesHWade</a>
, <a href="https://github.com/jameslairdsmith" target="_blank" rel="noopener">@jameslairdsmith</a>
, <a href="https://github.com/JBGruber" target="_blank" rel="noopener">@JBGruber</a>
, <a href="https://github.com/jcheng5" target="_blank" rel="noopener">@jcheng5</a>
, <a href="https://github.com/jeroen" target="_blank" rel="noopener">@jeroen</a>
, <a href="https://github.com/jimbrig" target="_blank" rel="noopener">@jimbrig</a>
, <a href="https://github.com/jjesusfilho" target="_blank" rel="noopener">@jjesusfilho</a>
, <a href="https://github.com/jl5000" target="_blank" rel="noopener">@jl5000</a>
, <a href="https://github.com/jmuhlenkamp" target="_blank" rel="noopener">@jmuhlenkamp</a>
, <a href="https://github.com/jonthegeek" target="_blank" rel="noopener">@jonthegeek</a>
, <a href="https://github.com/JosiahParry" target="_blank" rel="noopener">@JosiahParry</a>
, <a href="https://github.com/jwimberl" target="_blank" rel="noopener">@jwimberl</a>
, <a href="https://github.com/krjaworski" target="_blank" rel="noopener">@krjaworski</a>
, <a href="https://github.com/m-muecke" target="_blank" rel="noopener">@m-muecke</a>
, <a href="https://github.com/maarten-vermeyen" target="_blank" rel="noopener">@maarten-vermeyen</a>
, <a href="https://github.com/MarekGierlinski" target="_blank" rel="noopener">@MarekGierlinski</a>
, <a href="https://github.com/maxsutton" target="_blank" rel="noopener">@maxsutton</a>
, <a href="https://github.com/mgirlich" target="_blank" rel="noopener">@mgirlich</a>
, <a href="https://github.com/MichaelChirico" target="_blank" rel="noopener">@MichaelChirico</a>
, <a href="https://github.com/mkoohafkan" target="_blank" rel="noopener">@mkoohafkan</a>
, <a href="https://github.com/MSHelm" target="_blank" rel="noopener">@MSHelm</a>
, <a href="https://github.com/mstei4176" target="_blank" rel="noopener">@mstei4176</a>
, <a href="https://github.com/mthomas-ketchbrook" target="_blank" rel="noopener">@mthomas-ketchbrook</a>
, <a href="https://github.com/NateNohling" target="_blank" rel="noopener">@NateNohling</a>
, <a href="https://github.com/nick-youngblut" target="_blank" rel="noopener">@nick-youngblut</a>
, <a href="https://github.com/pbulsink" target="_blank" rel="noopener">@pbulsink</a>
, <a href="https://github.com/PietrH" target="_blank" rel="noopener">@PietrH</a>
, <a href="https://github.com/pkautio" target="_blank" rel="noopener">@pkautio</a>
, <a href="https://github.com/plietar" target="_blank" rel="noopener">@plietar</a>
, <a href="https://github.com/pmlefeuvre-met" target="_blank" rel="noopener">@pmlefeuvre-met</a>
, <a href="https://github.com/rkrug" target="_blank" rel="noopener">@rkrug</a>
, <a href="https://github.com/romainfrancois" target="_blank" rel="noopener">@romainfrancois</a>
, <a href="https://github.com/salim-b" target="_blank" rel="noopener">@salim-b</a>
, <a href="https://github.com/shikokuchuo" target="_blank" rel="noopener">@shikokuchuo</a>
, <a href="https://github.com/simplyalexander" target="_blank" rel="noopener">@simplyalexander</a>
, <a href="https://github.com/sluga" target="_blank" rel="noopener">@sluga</a>
, <a href="https://github.com/stefanedwards" target="_blank" rel="noopener">@stefanedwards</a>
, <a href="https://github.com/steveputman" target="_blank" rel="noopener">@steveputman</a>
, <a href="https://github.com/tebancr" target="_blank" rel="noopener">@tebancr</a>
, <a href="https://github.com/thohan88" target="_blank" rel="noopener">@thohan88</a>
, <a href="https://github.com/tony2015116" target="_blank" rel="noopener">@tony2015116</a>
, <a href="https://github.com/toobiwankenobi" target="_blank" rel="noopener">@toobiwankenobi</a>
, <a href="https://github.com/verhovsky" target="_blank" rel="noopener">@verhovsky</a>
, <a href="https://github.com/walinchus" target="_blank" rel="noopener">@walinchus</a>
, <a href="https://github.com/werkstattcodes" target="_blank" rel="noopener">@werkstattcodes</a>
, and <a href="https://github.com/zacdav-db" target="_blank" rel="noopener">@zacdav-db</a>
.</p>
]]></description>
      <enclosure url="https://posit-open-source.netlify.app/blog/tidyverse/2025/httr2-1-1-0/thumbnail-wd.jpg" length="220473" type="image/jpeg" />
    </item>
    <item>
      <title>nanoparquet 0.3.0</title>
      <link>https://posit-open-source.netlify.app/blog/tidyverse/2024/nanoparquet-0-3-0/</link>
      <pubDate>Thu, 20 Jun 2024 00:00:00 +0000</pubDate>
      <guid>https://posit-open-source.netlify.app/blog/tidyverse/2024/nanoparquet-0-3-0/</guid>
      <dc:creator>Gábor Csárdi</dc:creator><description><![CDATA[<!--
TODO:
* [x] Look over / edit the post's title in the yaml
* [x] Edit (or delete) the description; note this appears in the Twitter card
* [x] Pick category and tags (see existing with [`hugodown::tidy_show_meta()`](https://rdrr.io/pkg/hugodown/man/use_tidy_post.html))
* [x] Find photo & update yaml metadata
* [x] Create `thumbnail-sq.jpg`; height and width should be equal
* [x] Create `thumbnail-wd.jpg`; width should be >5x height
* [x] [`hugodown::use_tidy_thumbnails()`](https://rdrr.io/pkg/hugodown/man/use_tidy_post.html)
* [x] Add intro sentence, e.g. the standard tagline for the package
* [x] ~~[`usethis::use_tidy_thanks()`](https://usethis.r-lib.org/reference/use_tidy_thanks.html)~~
-->
<p>We&rsquo;re extremely pleased to announce the release of <a href="https://r-lib.github.io/nanoparquet/" target="_blank" rel="noopener">nanoparquet</a>
 0.3.0. nanoparquet is a new R package that reads Parquet files into data frames, and writes data frames to Parquet files.</p>
<p>You can install it from CRAN with:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nf'><a href='https://rdrr.io/r/utils/install.packages.html'>install.packages</a></span><span class='o'>(</span><span class='s'>"nanoparquet"</span><span class='o'>)</span></span></code></pre>
</div>
<p>This blog post will cover the features and limitations of nanoparquet, and also our future plans.</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='kr'><a href='https://rdrr.io/r/base/library.html'>library</a></span><span class='o'>(</span><span class='nv'><a href='https://github.com/r-lib/nanoparquet'>nanoparquet</a></span><span class='o'>)</span></span></code></pre>
</div>
<h2 id="what-is-parquet">What is Parquet?
</h2>
<p>Parquet is a file format for storing data on disk. It is specifically designed for large data sets, read-heavy workloads and data analysis. The most important features of Parquet are:</p>
<ul>
<li>
<p><strong>Columnar</strong>. Data is stored column-wise, so whole columns (or large chunks of columns) are easy to read quickly. Columnar storage allows better compression, fast operations on a subset of columns, and easy ways of removing columns or adding new columns to a data file.</p>
</li>
<li>
<p><strong>Binary</strong>. A Parquet file is not a text file. Each Parquet data type is stored in a well-defined binary storage format, leaving no ambiguity about how fields are persed.</p>
</li>
<li>
<p><strong>Rich types</strong>. Parquet supports a small set of <em>low level</em> data types with well specified storage formats and encodings. On top of the low level types, it implemented several higher level logical types, like UTF-8 strings, time stamps, JSON strings, ENUM types (factors), etc.</p>
</li>
<li>
<p><strong>Well supported</strong>. At this point Parquet is well supported across modern languages like R, Python, Rust, Java, Go, etc. In particular, Apache Arrow handles Parquet files very well, and has bindings to many languages. DuckDB is a very portable tool that reads and writes Parquet files, or even opens a set of Parquet files as a database.</p>
</li>
<li>
<p><strong>Performant</strong>. Parquet columns may use various encodings and compression to ensure that the data files are kept as small as possible. When running an analytical query on the subset of the data, the Parquet format makes it easy to skip the columns and/or rows that are irrelevant.</p>
</li>
<li>
<p><strong>Concurrency built in</strong>. A Parquet file can be divided into row groups. Parquet readers can read, uncompress and decode row groups in parallel. Parquet writes can encode and compress row groups in parallel. Even a single column may be divided into multiple pages, that can be (un)compressed, encode and decode in parallel.</p>
</li>
<li>
<p><strong>Missing values</strong>. Support for missing values is built into the Parquet format.</p>
</li>
</ul>
<h2 id="why-we-created-nanoparquet">Why we created nanoparquet?
</h2>
<p>Although Parquet is well supported by modern languages, today the complexity of the Parquet format often outweighs its benefits for smaller data sets. Many tools that support Parquet are typically used for larger, out of memory data sets, so there is a perception that Parquet is only for big data. These tools typically take longer to compile or install, and often seem too heavy for in-memory data analysis.</p>
<p>With nanoparquet, we wanted to have a smaller tool that has no dependencies and is easy to install. Our goal is to facilitate the adoption of Parquet for smaller data sets, especially for teams that share data between multiple environments, e.g. R, Python, Java, etc.</p>
<h2 id="nanoparquet-features">nanoparquet Features
</h2>
<p>These are some of the nanoparquet features that we are most excited about.</p>
<ul>
<li>
<p><strong>Lightweight</strong>. nanoparquet has no package or system dependencies other than a C++-11 compiler. It compiles in about 30 seconds into an R package that is less than a megabyte in size.</p>
</li>
<li>
<p><strong>Reads many Parquet files</strong>. <a href="https://r-lib.github.io/nanoparquet/reference/read_parquet.html" target="_blank" rel="noopener"><code>nanoparquet::read_parquet()</code></a>
 supports reading most Parquet files. In particular, in supports all Parquet encodings and at the time of writing it supports three compression codecs: Snappy, Gzip and Zstd. Make sure you read &ldquo;Limitations&rdquo; below.</p>
</li>
<li>
<p><strong>Writes many R data types</strong>. <a href="https://r-lib.github.io/nanoparquet/reference/write_parquet.html" target="_blank" rel="noopener"><code>nanoparquet::write_parquet()</code></a>
 supports writing most R data frames. In particular, missing values are handled properly, factor columns are kept as factors, and temporal types are encoded correctly. Make sure you read &ldquo;Limitations&rdquo; below.</p>
</li>
<li>
<p><strong>Type mappings</strong>. nanoparquet has a well defined set of <a href="https://r-lib.github.io/nanoparquet/reference/nanoparquet-types.html" target="_blank" rel="noopener">type mapping rules</a>
. Use the <a href="https://r-lib.github.io/nanoparquet/dev/reference/parquet_column_types.html" target="_blank" rel="noopener"><code>parquet_column_types()</code></a>
 function to see how <a href="https://r-lib.github.io/nanoparquet/reference/read_parquet.html" target="_blank" rel="noopener"><code>read_parquet()</code></a>
 and <a href="https://r-lib.github.io/nanoparquet/reference/write_parquet.html" target="_blank" rel="noopener"><code>write_parquet()</code></a>
 maps Parquet and R types for a file or a data frame.</p>
</li>
<li>
<p><strong>Metadata queries</strong>. nanoparquet has a <a href="https://r-lib.github.io/nanoparquet/dev/reference/index.html#extract-parquet-metadata" target="_blank" rel="noopener">number of functions</a>
 that allow you to query the metadata and schema without reading in the full dataset.</p>
</li>
</ul>
<h2 id="examples">Examples
</h2>
<h3 id="reading-a-parquet-file">Reading a Parquet file
</h3>
<p>The nanoparquet R package contains an example Parquet file. We are going to use it to demonstrate how the package works.</p>
<p>If the pillar package is loaded, then nanoparquet data frames are pretty-printed.</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='kr'><a href='https://rdrr.io/r/base/library.html'>library</a></span><span class='o'>(</span><span class='nv'><a href='https://github.com/r-lib/nanoparquet'>nanoparquet</a></span><span class='o'>)</span></span>
<span><span class='kr'><a href='https://rdrr.io/r/base/library.html'>library</a></span><span class='o'>(</span><span class='nv'><a href='https://pillar.r-lib.org/'>pillar</a></span><span class='o'>)</span></span>
<span><span class='nv'>udf</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://rdrr.io/r/base/system.file.html'>system.file</a></span><span class='o'>(</span><span class='s'>"extdata/userdata1.parquet"</span>, package <span class='o'>=</span> <span class='s'>"nanoparquet"</span><span class='o'>)</span></span></code></pre>
</div>
<p>Before actually reading the file, let&rsquo;s look up some metadata about it, and also how its columns will be mapped to R types:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nf'><a href='https://r-lib.github.io/nanoparquet/reference/parquet_info.html'>parquet_info</a></span><span class='o'>(</span><span class='nv'>udf</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># A data frame: 1 × 7</span></span></span>
<span><span class='c'>#&gt;   file_name           num_cols num_rows num_row_groups file_size parquet_version</span></span>
<span><span class='c'>#&gt;   <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>                  <span style='color: #555555; font-style: italic;'>&lt;int&gt;</span>    <span style='color: #555555; font-style: italic;'>&lt;dbl&gt;</span>          <span style='color: #555555; font-style: italic;'>&lt;int&gt;</span>     <span style='color: #555555; font-style: italic;'>&lt;dbl&gt;</span>           <span style='color: #555555; font-style: italic;'>&lt;int&gt;</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>1</span> /Users/gaborcsardi…       13     <span style='text-decoration: underline;'>1</span>000              1     <span style='text-decoration: underline;'>73</span>217               1</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># ℹ 1 more variable: created_by &lt;chr&gt;</span></span></span>
<span></span></code></pre>
</div>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nf'><a href='https://r-lib.github.io/nanoparquet/reference/parquet_column_types.html'>parquet_column_types</a></span><span class='o'>(</span><span class='nv'>udf</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># A data frame: 13 × 6</span></span></span>
<span><span class='c'>#&gt;    file_name        name  type  r_type repetition_type logical_type             </span></span>
<span><span class='c'>#&gt;  <span style='color: #555555;'>*</span> <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>            <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span> <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span> <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>  <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>           <span style='color: #555555; font-style: italic;'>&lt;I&lt;list&gt;&gt;</span>                </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 1</span> /Users/gaborcsa… regi… INT64 POSIX… REQUIRED        <span style='color: #555555;'>&lt;TIMESTAMP(TRUE, micros)&gt;</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 2</span> /Users/gaborcsa… id    INT32 integ… REQUIRED        <span style='color: #555555;'>&lt;INT(32, TRUE)&gt;</span>          </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 3</span> /Users/gaborcsa… firs… BYTE… chara… OPTIONAL        <span style='color: #555555;'>&lt;STRING&gt;</span>                 </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 4</span> /Users/gaborcsa… last… BYTE… chara… REQUIRED        <span style='color: #555555;'>&lt;STRING&gt;</span>                 </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 5</span> /Users/gaborcsa… email BYTE… chara… OPTIONAL        <span style='color: #555555;'>&lt;STRING&gt;</span>                 </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 6</span> /Users/gaborcsa… gend… BYTE… factor OPTIONAL        <span style='color: #555555;'>&lt;STRING&gt;</span>                 </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 7</span> /Users/gaborcsa… ip_a… BYTE… chara… REQUIRED        <span style='color: #555555;'>&lt;STRING&gt;</span>                 </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 8</span> /Users/gaborcsa… cc    BYTE… chara… OPTIONAL        <span style='color: #555555;'>&lt;STRING&gt;</span>                 </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 9</span> /Users/gaborcsa… coun… BYTE… chara… REQUIRED        <span style='color: #555555;'>&lt;STRING&gt;</span>                 </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>10</span> /Users/gaborcsa… birt… INT32 Date   OPTIONAL        <span style='color: #555555;'>&lt;DATE&gt;</span>                   </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>11</span> /Users/gaborcsa… sala… DOUB… double OPTIONAL        <span style='color: #555555;'>&lt;NULL&gt;</span>                   </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>12</span> /Users/gaborcsa… title BYTE… chara… OPTIONAL        <span style='color: #555555;'>&lt;STRING&gt;</span>                 </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>13</span> /Users/gaborcsa… comm… BYTE… chara… OPTIONAL        <span style='color: #555555;'>&lt;STRING&gt;</span></span></span>
<span></span></code></pre>
</div>
<p>For every Parquet column we see its low level Parquet data type in <code>type</code>, e.g. <code>INT64</code> or <code>BYTE_ARRAY</code>. <code>r_type</code> the R type that <a href="https://r-lib.github.io/nanoparquet/reference/read_parquet.html" target="_blank" rel="noopener"><code>read_parquet()</code></a>
 will create for that column. If <code>repetition_type</code> is <code>REQUIRED</code>, then that column cannot contain missing values. <code>OPTIONAL</code> columns may have missing values. <code>logical_type</code> is the higher level Parquet data type.</p>
<p>E.g. the first column is an UTC (because of the <code>TRUE</code>) timestamp, in microseconds. It is stored as a 64 bit integer in the file, and it will be converted to a <code>POSIXct</code> object by <a href="https://r-lib.github.io/nanoparquet/reference/read_parquet.html" target="_blank" rel="noopener"><code>read_parquet()</code></a>
.</p>
<p>To actually read the file into a data frame, call <a href="https://r-lib.github.io/nanoparquet/reference/read_parquet.html" target="_blank" rel="noopener"><code>read_parquet()</code></a>
:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>ud1</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://r-lib.github.io/nanoparquet/reference/read_parquet.html'>read_parquet</a></span><span class='o'>(</span><span class='nv'>udf</span><span class='o'>)</span></span>
<span><span class='nv'>ud1</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># A data frame: 1,000 × 13</span></span></span>
<span><span class='c'>#&gt;    registration           id first_name last_name email  gender ip_address cc   </span></span>
<span><span class='c'>#&gt;    <span style='color: #555555; font-style: italic;'>&lt;dttm&gt;</span>              <span style='color: #555555; font-style: italic;'>&lt;int&gt;</span> <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>      <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>     <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>  <span style='color: #555555; font-style: italic;'>&lt;fct&gt;</span>  <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>      <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 1</span> 2016-02-03 <span style='color: #555555;'>07:55:29</span>     1 Amanda     Jordan    ajord… Female 1.197.201… 6759…</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 2</span> 2016-02-03 <span style='color: #555555;'>17:04:03</span>     2 Albert     Freeman   afree… Male   218.111.1… <span style='color: #BB0000;'>NA</span>   </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 3</span> 2016-02-03 <span style='color: #555555;'>01:09:31</span>     3 Evelyn     Morgan    emorg… Female 7.161.136… 6767…</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 4</span> 2016-02-03 <span style='color: #555555;'>00:36:21</span>     4 Denise     Riley     drile… Female 140.35.10… 3576…</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 5</span> 2016-02-03 <span style='color: #555555;'>05:05:31</span>     5 Carlos     Burns     cburn… <span style='color: #BB0000;'>NA</span>     169.113.2… 5602…</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 6</span> 2016-02-03 <span style='color: #555555;'>07:22:34</span>     6 Kathryn    White     kwhit… Female 195.131.8… 3583…</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 7</span> 2016-02-03 <span style='color: #555555;'>08:33:08</span>     7 Samuel     Holmes    sholm… Male   232.234.8… 3582…</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 8</span> 2016-02-03 <span style='color: #555555;'>06:47:06</span>     8 Harry      Howell    hhowe… Male   91.235.51… <span style='color: #BB0000;'>NA</span>   </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 9</span> 2016-02-03 <span style='color: #555555;'>03:52:53</span>     9 Jose       Foster    jfost… Male   132.31.53… <span style='color: #BB0000;'>NA</span>   </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>10</span> 2016-02-03 <span style='color: #555555;'>18:29:47</span>    10 Emily      Stewart   estew… Female 143.28.25… 3574…</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># ℹ 990 more rows</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># ℹ 5 more variables: country &lt;chr&gt;, birthdate &lt;date&gt;, salary &lt;dbl&gt;,</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>#   title &lt;chr&gt;, comments &lt;chr&gt;</span></span></span>
<span></span></code></pre>
</div>
<h3 id="writing-a-parquet-file">Writing a Parquet file
</h3>
<p>To show <a href="https://r-lib.github.io/nanoparquet/reference/write_parquet.html" target="_blank" rel="noopener"><code>write_parquet()</code></a>
, we&rsquo;ll use the <code>flights</code> data in the nycflights13 package:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='kr'><a href='https://rdrr.io/r/base/library.html'>library</a></span><span class='o'>(</span><span class='nv'><a href='https://github.com/hadley/nycflights13'>nycflights13</a></span><span class='o'>)</span></span>
<span><span class='nv'>flights</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># A tibble: 336,776 × 19</span></span></span>
<span><span class='c'>#&gt;     year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time</span></span>
<span><span class='c'>#&gt;    <span style='color: #555555; font-style: italic;'>&lt;int&gt;</span> <span style='color: #555555; font-style: italic;'>&lt;int&gt;</span> <span style='color: #555555; font-style: italic;'>&lt;int&gt;</span>    <span style='color: #555555; font-style: italic;'>&lt;int&gt;</span>          <span style='color: #555555; font-style: italic;'>&lt;int&gt;</span>     <span style='color: #555555; font-style: italic;'>&lt;dbl&gt;</span>    <span style='color: #555555; font-style: italic;'>&lt;int&gt;</span>          <span style='color: #555555; font-style: italic;'>&lt;int&gt;</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 1</span>  <span style='text-decoration: underline;'>2</span>013     1     1      517            515         2      830            819</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 2</span>  <span style='text-decoration: underline;'>2</span>013     1     1      533            529         4      850            830</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 3</span>  <span style='text-decoration: underline;'>2</span>013     1     1      542            540         2      923            850</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 4</span>  <span style='text-decoration: underline;'>2</span>013     1     1      544            545        -<span style='color: #BB0000;'>1</span>     <span style='text-decoration: underline;'>1</span>004           <span style='text-decoration: underline;'>1</span>022</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 5</span>  <span style='text-decoration: underline;'>2</span>013     1     1      554            600        -<span style='color: #BB0000;'>6</span>      812            837</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 6</span>  <span style='text-decoration: underline;'>2</span>013     1     1      554            558        -<span style='color: #BB0000;'>4</span>      740            728</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 7</span>  <span style='text-decoration: underline;'>2</span>013     1     1      555            600        -<span style='color: #BB0000;'>5</span>      913            854</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 8</span>  <span style='text-decoration: underline;'>2</span>013     1     1      557            600        -<span style='color: #BB0000;'>3</span>      709            723</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 9</span>  <span style='text-decoration: underline;'>2</span>013     1     1      557            600        -<span style='color: #BB0000;'>3</span>      838            846</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>10</span>  <span style='text-decoration: underline;'>2</span>013     1     1      558            600        -<span style='color: #BB0000;'>2</span>      753            745</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># ℹ 336,766 more rows</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># ℹ 11 more variables: arr_delay &lt;dbl&gt;, carrier &lt;chr&gt;, flight &lt;int&gt;,</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>#   tailnum &lt;chr&gt;, origin &lt;chr&gt;, dest &lt;chr&gt;, air_time &lt;dbl&gt;, distance &lt;dbl&gt;,</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>#   hour &lt;dbl&gt;, minute &lt;dbl&gt;, time_hour &lt;dttm&gt;</span></span></span>
<span></span></code></pre>
</div>
<p>First we check how columns of <code>flights</code> will be mapped to Parquet types:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nf'><a href='https://r-lib.github.io/nanoparquet/reference/parquet_column_types.html'>parquet_column_types</a></span><span class='o'>(</span><span class='nv'>flights</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># A data frame: 19 × 6</span></span></span>
<span><span class='c'>#&gt;    file_name name         type  r_type repetition_type logical_type             </span></span>
<span><span class='c'>#&gt;    <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>     <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>        <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span> <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>  <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>           <span style='color: #555555; font-style: italic;'>&lt;I&lt;list&gt;&gt;</span>                </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 1</span> <span style='color: #BB0000;'>NA</span>        year         INT32 integ… REQUIRED        <span style='color: #555555;'>&lt;INT(32, TRUE)&gt;</span>          </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 2</span> <span style='color: #BB0000;'>NA</span>        month        INT32 integ… REQUIRED        <span style='color: #555555;'>&lt;INT(32, TRUE)&gt;</span>          </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 3</span> <span style='color: #BB0000;'>NA</span>        day          INT32 integ… REQUIRED        <span style='color: #555555;'>&lt;INT(32, TRUE)&gt;</span>          </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 4</span> <span style='color: #BB0000;'>NA</span>        dep_time     INT32 integ… OPTIONAL        <span style='color: #555555;'>&lt;INT(32, TRUE)&gt;</span>          </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 5</span> <span style='color: #BB0000;'>NA</span>        sched_dep_t… INT32 integ… REQUIRED        <span style='color: #555555;'>&lt;INT(32, TRUE)&gt;</span>          </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 6</span> <span style='color: #BB0000;'>NA</span>        dep_delay    DOUB… double OPTIONAL        <span style='color: #555555;'>&lt;NULL&gt;</span>                   </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 7</span> <span style='color: #BB0000;'>NA</span>        arr_time     INT32 integ… OPTIONAL        <span style='color: #555555;'>&lt;INT(32, TRUE)&gt;</span>          </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 8</span> <span style='color: #BB0000;'>NA</span>        sched_arr_t… INT32 integ… REQUIRED        <span style='color: #555555;'>&lt;INT(32, TRUE)&gt;</span>          </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 9</span> <span style='color: #BB0000;'>NA</span>        arr_delay    DOUB… double OPTIONAL        <span style='color: #555555;'>&lt;NULL&gt;</span>                   </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>10</span> <span style='color: #BB0000;'>NA</span>        carrier      BYTE… chara… REQUIRED        <span style='color: #555555;'>&lt;STRING&gt;</span>                 </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>11</span> <span style='color: #BB0000;'>NA</span>        flight       INT32 integ… REQUIRED        <span style='color: #555555;'>&lt;INT(32, TRUE)&gt;</span>          </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>12</span> <span style='color: #BB0000;'>NA</span>        tailnum      BYTE… chara… OPTIONAL        <span style='color: #555555;'>&lt;STRING&gt;</span>                 </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>13</span> <span style='color: #BB0000;'>NA</span>        origin       BYTE… chara… REQUIRED        <span style='color: #555555;'>&lt;STRING&gt;</span>                 </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>14</span> <span style='color: #BB0000;'>NA</span>        dest         BYTE… chara… REQUIRED        <span style='color: #555555;'>&lt;STRING&gt;</span>                 </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>15</span> <span style='color: #BB0000;'>NA</span>        air_time     DOUB… double OPTIONAL        <span style='color: #555555;'>&lt;NULL&gt;</span>                   </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>16</span> <span style='color: #BB0000;'>NA</span>        distance     DOUB… double REQUIRED        <span style='color: #555555;'>&lt;NULL&gt;</span>                   </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>17</span> <span style='color: #BB0000;'>NA</span>        hour         DOUB… double REQUIRED        <span style='color: #555555;'>&lt;NULL&gt;</span>                   </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>18</span> <span style='color: #BB0000;'>NA</span>        minute       DOUB… double REQUIRED        <span style='color: #555555;'>&lt;NULL&gt;</span>                   </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>19</span> <span style='color: #BB0000;'>NA</span>        time_hour    INT64 POSIX… REQUIRED        <span style='color: #555555;'>&lt;TIMESTAMP(TRUE, micros)&gt;</span></span></span>
<span></span></code></pre>
</div>
<p>This looks fine, so we go ahead and write out the file. By default it will be Snappy-compressed, and many columns will be dictionary encoded.</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nf'><a href='https://r-lib.github.io/nanoparquet/reference/write_parquet.html'>write_parquet</a></span><span class='o'>(</span><span class='nv'>flights</span>, <span class='s'>"flights.parquet"</span><span class='o'>)</span></span></code></pre>
</div>
<h3 id="parquet-metadata">Parquet metadata
</h3>
<p>Use <a href="https://r-lib.github.io/nanoparquet/reference/parquet_schema.html" target="_blank" rel="noopener"><code>parquet_schema()</code></a>
 to see the schema of a Parquet file. The schema also includes &ldquo;internal&rdquo; parquet columns. Every Parquet file is a tree where columns may be part of an &ldquo;internal&rdquo; column. nanoparquet currently only supports flat files, that consist of a single internal root column and all other columns are leaf columns and are children of the root:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nf'><a href='https://r-lib.github.io/nanoparquet/reference/parquet_schema.html'>parquet_schema</a></span><span class='o'>(</span><span class='s'>"flights.parquet"</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># A data frame: 20 × 11</span></span></span>
<span><span class='c'>#&gt;    file_name       name         type  type_length repetition_type converted_type</span></span>
<span><span class='c'>#&gt;    <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>           <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>        <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>       <span style='color: #555555; font-style: italic;'>&lt;int&gt;</span> <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>           <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>         </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 1</span> flights.parquet schema       <span style='color: #BB0000;'>NA</span>             <span style='color: #BB0000;'>NA</span> <span style='color: #BB0000;'>NA</span>              <span style='color: #BB0000;'>NA</span>            </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 2</span> flights.parquet year         INT32          <span style='color: #BB0000;'>NA</span> REQUIRED        INT_32        </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 3</span> flights.parquet month        INT32          <span style='color: #BB0000;'>NA</span> REQUIRED        INT_32        </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 4</span> flights.parquet day          INT32          <span style='color: #BB0000;'>NA</span> REQUIRED        INT_32        </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 5</span> flights.parquet dep_time     INT32          <span style='color: #BB0000;'>NA</span> OPTIONAL        INT_32        </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 6</span> flights.parquet sched_dep_t… INT32          <span style='color: #BB0000;'>NA</span> REQUIRED        INT_32        </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 7</span> flights.parquet dep_delay    DOUB…          <span style='color: #BB0000;'>NA</span> OPTIONAL        <span style='color: #BB0000;'>NA</span>            </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 8</span> flights.parquet arr_time     INT32          <span style='color: #BB0000;'>NA</span> OPTIONAL        INT_32        </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 9</span> flights.parquet sched_arr_t… INT32          <span style='color: #BB0000;'>NA</span> REQUIRED        INT_32        </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>10</span> flights.parquet arr_delay    DOUB…          <span style='color: #BB0000;'>NA</span> OPTIONAL        <span style='color: #BB0000;'>NA</span>            </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>11</span> flights.parquet carrier      BYTE…          <span style='color: #BB0000;'>NA</span> REQUIRED        UTF8          </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>12</span> flights.parquet flight       INT32          <span style='color: #BB0000;'>NA</span> REQUIRED        INT_32        </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>13</span> flights.parquet tailnum      BYTE…          <span style='color: #BB0000;'>NA</span> OPTIONAL        UTF8          </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>14</span> flights.parquet origin       BYTE…          <span style='color: #BB0000;'>NA</span> REQUIRED        UTF8          </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>15</span> flights.parquet dest         BYTE…          <span style='color: #BB0000;'>NA</span> REQUIRED        UTF8          </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>16</span> flights.parquet air_time     DOUB…          <span style='color: #BB0000;'>NA</span> OPTIONAL        <span style='color: #BB0000;'>NA</span>            </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>17</span> flights.parquet distance     DOUB…          <span style='color: #BB0000;'>NA</span> REQUIRED        <span style='color: #BB0000;'>NA</span>            </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>18</span> flights.parquet hour         DOUB…          <span style='color: #BB0000;'>NA</span> REQUIRED        <span style='color: #BB0000;'>NA</span>            </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>19</span> flights.parquet minute       DOUB…          <span style='color: #BB0000;'>NA</span> REQUIRED        <span style='color: #BB0000;'>NA</span>            </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>20</span> flights.parquet time_hour    INT64          <span style='color: #BB0000;'>NA</span> REQUIRED        TIMESTAMP_MIC…</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># ℹ 5 more variables: logical_type &lt;I&lt;list&gt;&gt;, num_children &lt;int&gt;, scale &lt;int&gt;,</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>#   precision &lt;int&gt;, field_id &lt;int&gt;</span></span></span>
<span></span></code></pre>
</div>
<p>To see more information about a Parquet file, use <a href="https://r-lib.github.io/nanoparquet/reference/parquet_metadata.html" target="_blank" rel="noopener"><code>parquet_metadata()</code></a>
:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nf'><a href='https://r-lib.github.io/nanoparquet/reference/parquet_metadata.html'>parquet_metadata</a></span><span class='o'>(</span><span class='s'>"flights.parquet"</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; $file_meta_data</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># A data frame: 1 × 5</span></span></span>
<span><span class='c'>#&gt;   file_name       version num_rows key_value_metadata created_by                </span></span>
<span><span class='c'>#&gt;   <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>             <span style='color: #555555; font-style: italic;'>&lt;int&gt;</span>    <span style='color: #555555; font-style: italic;'>&lt;dbl&gt;</span> <span style='color: #555555; font-style: italic;'>&lt;I&lt;list&gt;&gt;</span>          <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>                     </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>1</span> flights.parquet       1   <span style='text-decoration: underline;'>336</span>776 <span style='color: #555555;'>&lt;tbl [1 × 2]&gt;</span>      https://github.com/gaborc…</span></span>
<span><span class='c'>#&gt; </span></span>
<span><span class='c'>#&gt; $schema</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># A data frame: 20 × 11</span></span></span>
<span><span class='c'>#&gt;    file_name       name         type  type_length repetition_type converted_type</span></span>
<span><span class='c'>#&gt;    <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>           <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>        <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>       <span style='color: #555555; font-style: italic;'>&lt;int&gt;</span> <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>           <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>         </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 1</span> flights.parquet schema       <span style='color: #BB0000;'>NA</span>             <span style='color: #BB0000;'>NA</span> <span style='color: #BB0000;'>NA</span>              <span style='color: #BB0000;'>NA</span>            </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 2</span> flights.parquet year         INT32          <span style='color: #BB0000;'>NA</span> REQUIRED        INT_32        </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 3</span> flights.parquet month        INT32          <span style='color: #BB0000;'>NA</span> REQUIRED        INT_32        </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 4</span> flights.parquet day          INT32          <span style='color: #BB0000;'>NA</span> REQUIRED        INT_32        </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 5</span> flights.parquet dep_time     INT32          <span style='color: #BB0000;'>NA</span> OPTIONAL        INT_32        </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 6</span> flights.parquet sched_dep_t… INT32          <span style='color: #BB0000;'>NA</span> REQUIRED        INT_32        </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 7</span> flights.parquet dep_delay    DOUB…          <span style='color: #BB0000;'>NA</span> OPTIONAL        <span style='color: #BB0000;'>NA</span>            </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 8</span> flights.parquet arr_time     INT32          <span style='color: #BB0000;'>NA</span> OPTIONAL        INT_32        </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 9</span> flights.parquet sched_arr_t… INT32          <span style='color: #BB0000;'>NA</span> REQUIRED        INT_32        </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>10</span> flights.parquet arr_delay    DOUB…          <span style='color: #BB0000;'>NA</span> OPTIONAL        <span style='color: #BB0000;'>NA</span>            </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>11</span> flights.parquet carrier      BYTE…          <span style='color: #BB0000;'>NA</span> REQUIRED        UTF8          </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>12</span> flights.parquet flight       INT32          <span style='color: #BB0000;'>NA</span> REQUIRED        INT_32        </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>13</span> flights.parquet tailnum      BYTE…          <span style='color: #BB0000;'>NA</span> OPTIONAL        UTF8          </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>14</span> flights.parquet origin       BYTE…          <span style='color: #BB0000;'>NA</span> REQUIRED        UTF8          </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>15</span> flights.parquet dest         BYTE…          <span style='color: #BB0000;'>NA</span> REQUIRED        UTF8          </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>16</span> flights.parquet air_time     DOUB…          <span style='color: #BB0000;'>NA</span> OPTIONAL        <span style='color: #BB0000;'>NA</span>            </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>17</span> flights.parquet distance     DOUB…          <span style='color: #BB0000;'>NA</span> REQUIRED        <span style='color: #BB0000;'>NA</span>            </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>18</span> flights.parquet hour         DOUB…          <span style='color: #BB0000;'>NA</span> REQUIRED        <span style='color: #BB0000;'>NA</span>            </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>19</span> flights.parquet minute       DOUB…          <span style='color: #BB0000;'>NA</span> REQUIRED        <span style='color: #BB0000;'>NA</span>            </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>20</span> flights.parquet time_hour    INT64          <span style='color: #BB0000;'>NA</span> REQUIRED        TIMESTAMP_MIC…</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># ℹ 5 more variables: logical_type &lt;I&lt;list&gt;&gt;, num_children &lt;int&gt;, scale &lt;int&gt;,</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>#   precision &lt;int&gt;, field_id &lt;int&gt;</span></span></span>
<span><span class='c'>#&gt; </span></span>
<span><span class='c'>#&gt; $row_groups</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># A data frame: 1 × 7</span></span></span>
<span><span class='c'>#&gt;   file_name        id total_byte_size num_rows file_offset total_compressed_size</span></span>
<span><span class='c'>#&gt;   <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>         <span style='color: #555555; font-style: italic;'>&lt;int&gt;</span>           <span style='color: #555555; font-style: italic;'>&lt;dbl&gt;</span>    <span style='color: #555555; font-style: italic;'>&lt;dbl&gt;</span>       <span style='color: #555555; font-style: italic;'>&lt;dbl&gt;</span>                 <span style='color: #555555; font-style: italic;'>&lt;dbl&gt;</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>1</span> flights.parq…     0         5<span style='text-decoration: underline;'>732</span>430   <span style='text-decoration: underline;'>336</span>776          <span style='color: #BB0000;'>NA</span>                    <span style='color: #BB0000;'>NA</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># ℹ 1 more variable: ordinal &lt;int&gt;</span></span></span>
<span><span class='c'>#&gt; </span></span>
<span><span class='c'>#&gt; $column_chunks</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># A data frame: 19 × 19</span></span></span>
<span><span class='c'>#&gt;    file_name       row_group column file_path file_offset offset_index_offset</span></span>
<span><span class='c'>#&gt;    <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>               <span style='color: #555555; font-style: italic;'>&lt;int&gt;</span>  <span style='color: #555555; font-style: italic;'>&lt;int&gt;</span> <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>           <span style='color: #555555; font-style: italic;'>&lt;dbl&gt;</span>               <span style='color: #555555; font-style: italic;'>&lt;dbl&gt;</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 1</span> flights.parquet         0      0 <span style='color: #BB0000;'>NA</span>                 23                  <span style='color: #BB0000;'>NA</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 2</span> flights.parquet         0      1 <span style='color: #BB0000;'>NA</span>                111                  <span style='color: #BB0000;'>NA</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 3</span> flights.parquet         0      2 <span style='color: #BB0000;'>NA</span>                323                  <span style='color: #BB0000;'>NA</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 4</span> flights.parquet         0      3 <span style='color: #BB0000;'>NA</span>               <span style='text-decoration: underline;'>6</span>738                  <span style='color: #BB0000;'>NA</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 5</span> flights.parquet         0      4 <span style='color: #BB0000;'>NA</span>             <span style='text-decoration: underline;'>468</span>008                  <span style='color: #BB0000;'>NA</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 6</span> flights.parquet         0      5 <span style='color: #BB0000;'>NA</span>             <span style='text-decoration: underline;'>893</span>557                  <span style='color: #BB0000;'>NA</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 7</span> flights.parquet         0      6 <span style='color: #BB0000;'>NA</span>            1<span style='text-decoration: underline;'>312</span>660                  <span style='color: #BB0000;'>NA</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 8</span> flights.parquet         0      7 <span style='color: #BB0000;'>NA</span>            1<span style='text-decoration: underline;'>771</span>896                  <span style='color: #BB0000;'>NA</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 9</span> flights.parquet         0      8 <span style='color: #BB0000;'>NA</span>            2<span style='text-decoration: underline;'>237</span>931                  <span style='color: #BB0000;'>NA</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>10</span> flights.parquet         0      9 <span style='color: #BB0000;'>NA</span>            2<span style='text-decoration: underline;'>653</span>250                  <span style='color: #BB0000;'>NA</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>11</span> flights.parquet         0     10 <span style='color: #BB0000;'>NA</span>            2<span style='text-decoration: underline;'>847</span>249                  <span style='color: #BB0000;'>NA</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>12</span> flights.parquet         0     11 <span style='color: #BB0000;'>NA</span>            3<span style='text-decoration: underline;'>374</span>563                  <span style='color: #BB0000;'>NA</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>13</span> flights.parquet         0     12 <span style='color: #BB0000;'>NA</span>            3<span style='text-decoration: underline;'>877</span>832                  <span style='color: #BB0000;'>NA</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>14</span> flights.parquet         0     13 <span style='color: #BB0000;'>NA</span>            3<span style='text-decoration: underline;'>966</span>418                  <span style='color: #BB0000;'>NA</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>15</span> flights.parquet         0     14 <span style='color: #BB0000;'>NA</span>            4<span style='text-decoration: underline;'>264</span>662                  <span style='color: #BB0000;'>NA</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>16</span> flights.parquet         0     15 <span style='color: #BB0000;'>NA</span>            4<span style='text-decoration: underline;'>639</span>410                  <span style='color: #BB0000;'>NA</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>17</span> flights.parquet         0     16 <span style='color: #BB0000;'>NA</span>            4<span style='text-decoration: underline;'>976</span>781                  <span style='color: #BB0000;'>NA</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>18</span> flights.parquet         0     17 <span style='color: #BB0000;'>NA</span>            5<span style='text-decoration: underline;'>120</span>936                  <span style='color: #BB0000;'>NA</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>19</span> flights.parquet         0     18 <span style='color: #BB0000;'>NA</span>            5<span style='text-decoration: underline;'>427</span>022                  <span style='color: #BB0000;'>NA</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># ℹ 13 more variables: offset_index_length &lt;int&gt;, column_index_offset &lt;dbl&gt;,</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>#   column_index_length &lt;int&gt;, type &lt;chr&gt;, encodings &lt;I&lt;list&gt;&gt;,</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>#   path_in_schema &lt;I&lt;list&gt;&gt;, codec &lt;chr&gt;, num_values &lt;dbl&gt;,</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>#   total_uncompressed_size &lt;dbl&gt;, total_compressed_size &lt;dbl&gt;,</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>#   data_page_offset &lt;dbl&gt;, index_page_offset &lt;dbl&gt;,</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>#   dictionary_page_offset &lt;dbl&gt;</span></span></span>
<span></span></code></pre>
</div>
<p>The output will include the schema, as above, but also data about the row groups (<a href="https://r-lib.github.io/nanoparquet/reference/write_parquet.html" target="_blank" rel="noopener"><code>write_parquet()</code></a>
 always writes a single row group currently), and column chunks. There is one column chunk per column in each row group.</p>
<p>The columns chunk information also tells you whether a column chunk is dictionary encoded, its encoding, its size, etc.</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>cc</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://r-lib.github.io/nanoparquet/reference/parquet_metadata.html'>parquet_metadata</a></span><span class='o'>(</span><span class='s'>"flights.parquet"</span><span class='o'>)</span><span class='o'>$</span><span class='nv'>column_chunks</span></span>
<span><span class='nv'>cc</span><span class='o'>[</span>, <span class='nf'><a href='https://rdrr.io/r/base/c.html'>c</a></span><span class='o'>(</span><span class='s'>"column"</span>, <span class='s'>"encodings"</span>, <span class='s'>"dictionary_page_offset"</span><span class='o'>)</span><span class='o'>]</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># A data frame: 19 × 3</span></span></span>
<span><span class='c'>#&gt;    column encodings dictionary_page_offset</span></span>
<span><span class='c'>#&gt;     <span style='color: #555555; font-style: italic;'>&lt;int&gt;</span> <span style='color: #555555; font-style: italic;'>&lt;I&lt;list&gt;&gt;</span>                  <span style='color: #555555; font-style: italic;'>&lt;dbl&gt;</span></span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 1</span>      0 <span style='color: #555555;'>&lt;chr [3]&gt;</span>                      4</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 2</span>      1 <span style='color: #555555;'>&lt;chr [3]&gt;</span>                     48</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 3</span>      2 <span style='color: #555555;'>&lt;chr [3]&gt;</span>                    181</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 4</span>      3 <span style='color: #555555;'>&lt;chr [3]&gt;</span>                   <span style='text-decoration: underline;'>1</span>445</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 5</span>      4 <span style='color: #555555;'>&lt;chr [3]&gt;</span>                 <span style='text-decoration: underline;'>463</span>903</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 6</span>      5 <span style='color: #555555;'>&lt;chr [3]&gt;</span>                 <span style='text-decoration: underline;'>891</span>412</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 7</span>      6 <span style='color: #555555;'>&lt;chr [3]&gt;</span>                1<span style='text-decoration: underline;'>306</span>995</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 8</span>      7 <span style='color: #555555;'>&lt;chr [3]&gt;</span>                1<span style='text-decoration: underline;'>767</span>223</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 9</span>      8 <span style='color: #555555;'>&lt;chr [3]&gt;</span>                2<span style='text-decoration: underline;'>235</span>594</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>10</span>      9 <span style='color: #555555;'>&lt;chr [3]&gt;</span>                2<span style='text-decoration: underline;'>653</span>154</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>11</span>     10 <span style='color: #555555;'>&lt;chr [3]&gt;</span>                2<span style='text-decoration: underline;'>831</span>850</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>12</span>     11 <span style='color: #555555;'>&lt;chr [3]&gt;</span>                3<span style='text-decoration: underline;'>352</span>496</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>13</span>     12 <span style='color: #555555;'>&lt;chr [3]&gt;</span>                3<span style='text-decoration: underline;'>877</span>796</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>14</span>     13 <span style='color: #555555;'>&lt;chr [3]&gt;</span>                3<span style='text-decoration: underline;'>965</span>856</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>15</span>     14 <span style='color: #555555;'>&lt;chr [3]&gt;</span>                4<span style='text-decoration: underline;'>262</span>597</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>16</span>     15 <span style='color: #555555;'>&lt;chr [3]&gt;</span>                4<span style='text-decoration: underline;'>638</span>461</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>17</span>     16 <span style='color: #555555;'>&lt;chr [3]&gt;</span>                4<span style='text-decoration: underline;'>976</span>675</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>18</span>     17 <span style='color: #555555;'>&lt;chr [3]&gt;</span>                5<span style='text-decoration: underline;'>120</span>660</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>19</span>     18 <span style='color: #555555;'>&lt;chr [3]&gt;</span>                5<span style='text-decoration: underline;'>379</span>476</span></span>
<span></span></code></pre>
</div>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>cc</span><span class='o'>[[</span><span class='s'>"encodings"</span><span class='o'>]</span><span class='o'>]</span><span class='o'>[</span><span class='m'>1</span><span class='o'>:</span><span class='m'>3</span><span class='o'>]</span></span>
<span><span class='c'>#&gt; [[1]]</span></span>
<span><span class='c'>#&gt; [1] "PLAIN"          "RLE"            "RLE_DICTIONARY"</span></span>
<span><span class='c'>#&gt; </span></span>
<span><span class='c'>#&gt; [[2]]</span></span>
<span><span class='c'>#&gt; [1] "PLAIN"          "RLE"            "RLE_DICTIONARY"</span></span>
<span><span class='c'>#&gt; </span></span>
<span><span class='c'>#&gt; [[3]]</span></span>
<span><span class='c'>#&gt; [1] "PLAIN"          "RLE"            "RLE_DICTIONARY"</span></span>
<span></span></code></pre>
</div>
<h2 id="limitations">Limitations
</h2>
<p>nanoparquet 0.3.0 has a number of limitations.</p>
<ul>
<li>
<p><strong>Only flat tables</strong>. <a href="https://r-lib.github.io/nanoparquet/reference/read_parquet.html" target="_blank" rel="noopener"><code>read_parquet()</code></a>
 can only read flat tables, i.e. Parquet files without nested columns. (Technically all Parquet files are nested, and nanoparquet supports exactly one level of nesting: a single meta column that contains all other columns.) Similarly, <a href="https://r-lib.github.io/nanoparquet/reference/write_parquet.html" target="_blank" rel="noopener"><code>write_parquet()</code></a>
 will not write list columns.</p>
</li>
<li>
<p><strong>Unsupported Parquet types</strong>. <a href="https://r-lib.github.io/nanoparquet/reference/read_parquet.html" target="_blank" rel="noopener"><code>read_parquet()</code></a>
 reads some Parquet types as raw vectors of a list column currently, e.g. <code>FLOAT16</code>, <code>INTERVAL</code>. See <a href="https://r-lib.github.io/nanoparquet/reference/nanoparquet-types.html" target="_blank" rel="noopener">the manual</a>
 for details.</p>
</li>
<li>
<p><strong>No encryption</strong>. Encrypted Parquet files are not supported.</p>
</li>
<li>
<p><strong>Missing compression codecs</strong>. <code>LZO</code>, <code>BROTLI</code> and <code>LZ4</code> compression is not yet supported.</p>
</li>
<li>
<p><strong>No statistics</strong>. nanoparquet does not read or write statistics, e.g. minimum and maximum values from and to Parquet files.</p>
</li>
<li>
<p><strong>No checksums</strong>. nanoparquet does not check or write checksums currently.</p>
</li>
<li>
<p><strong>No Bloom filters</strong>. nanoparquet does not currently support reading or writing Bloom filters from or to Parquet files.</p>
</li>
<li>
<p><strong>May be slow for large files</strong>. Being single-threaded and not fully optimized, nanoparquet is probably not suited well for large data sets. It should be fine for a couple of gigabytes. It may be fine if all the data fits into memory comfortably.</p>
</li>
<li>
<p><strong>Single row group</strong>. <a href="https://r-lib.github.io/nanoparquet/reference/write_parquet.html" target="_blank" rel="noopener"><code>write_parquet()</code></a>
 always creates a single row group, which is not optimal for large files.</p>
</li>
<li>
<p><strong>Automatic encoding</strong>. It is currently not possible to choose encodings in <a href="https://r-lib.github.io/nanoparquet/reference/write_parquet.html" target="_blank" rel="noopener"><code>write_parquet()</code></a>
 manually.</p>
</li>
</ul>
<p>We are planning on solving these limitations, while keeping nanoparquet as lean as possible. In particular, if you find a Parquet file that nanoparquet cannot read, please report an issue in our <a href="https://github.com/r-lib/nanoparquet/issues" target="_blank" rel="noopener">issue tracker</a>
!</p>
<h2 id="other-tools-for-parquet-files">Other tools for Parquet files
</h2>
<p>If you run into some of these limitations, chances are you are dealing with a larget data set, and you will probably benefit from using tools geared towards larger Parquet files. Luckily you have several options.</p>
<h3 id="in-r">In R
</h3>
<h4 id="apache-arrow">Apache Arrow
</h4>
<p>You can usually install the <code>arrow</code> package from CRAN. Note, however, that some CRAN builds are suboptimal at the time of writing, e.g. the macOS builds lack Parquet support and it is best to install arrow from <a href="https://apache.r-universe.dev/arrow" target="_blank" rel="noopener">R-universe</a>
 on these platforms.</p>
<p>Call <a href="https://arrow.apache.org/docs/r/reference/read_parquet.html" target="_blank" rel="noopener"><code>arrow::read_parquet()</code></a>
 to read Parquet files, and <a href="https://arrow.apache.org/docs/r/reference/write_parquet.html" target="_blank" rel="noopener"><code>arrow::write_parquet()</code></a>
 to write them. You can also use <a href="https://arrow.apache.org/docs/r/reference/open_dataset.html" target="_blank" rel="noopener"><code>arrow::open_dataset()</code></a>
 to open (one or more) Parquet files and perform queries on them without loading all data into memory.</p>
<h4 id="duckdb">DuckDB
</h4>
<p>DuckDB is an excellent tool that handles Parquet files seemlessly. You can install the duckdb R package from CRAN.</p>
<p>To read a Parquet file into an R data frame with DuckDB, call</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="n">df</span> <span class="o">&lt;-</span> <span class="n">duckdb</span><span class="o">:::</span><span class="nf">sql</span><span class="p">(</span><span class="s">&#34;FROM &#39;file.parquet&#39;&#34;</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>Alternatively, you can open (one or more) Parquet files and query them as a DuckDB database, potentially without reading all data into memory at once.</p>
<p>Here is an example that shows how to put an R data frame into a (temporary) DuckDB database, and how to export it to Parquet:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span><span class="lnt">9
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="n">drv</span> <span class="o">&lt;-</span> <span class="n">duckdb</span><span class="o">::</span><span class="nf">duckdb</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="n">con</span> <span class="o">&lt;-</span> <span class="n">DBI</span><span class="o">::</span><span class="nf">dbConnect</span><span class="p">(</span><span class="n">drv</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nf">on.exit</span><span class="p">(</span><span class="n">DBI</span><span class="o">::</span><span class="nf">dbDisconnect</span><span class="p">(</span><span class="n">con</span><span class="p">),</span> <span class="n">add</span> <span class="o">=</span> <span class="kc">TRUE</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">DBI</span><span class="o">::</span><span class="nf">dbWriteTable</span><span class="p">(</span><span class="n">con</span><span class="p">,</span> <span class="s">&#34;mtcars&#34;</span><span class="p">,</span> <span class="n">mtcars</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">DBI</span><span class="o">::</span><span class="nf">dbExecute</span><span class="p">(</span><span class="n">con</span><span class="p">,</span> <span class="n">DBI</span><span class="o">::</span><span class="nf">sqlInterpolate</span><span class="p">(</span><span class="n">con</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="s">&#34;COPY mtcars TO ?filename (FORMAT &#39;parquet&#39;, COMPRESSION &#39;snappy&#39;)&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="n">filename</span> <span class="o">=</span> <span class="s">&#39;mtcars.parquet&#39;</span>
</span></span><span class="line"><span class="cl"><span class="p">))</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="in-python">In Python
</h3>
<p>There are at least three good options to handle Parquet files in Python. Just like for R, the first two are <a href="https://arrow.apache.org/docs/python/index.html" target="_blank" rel="noopener">Apache Arrow</a>
 and <a href="https://duckdb.org/docs/api/python/overview.html" target="_blank" rel="noopener">DuckDB</a>
. You can also try the <a href="https://pypi.org/project/fastparquet/" target="_blank" rel="noopener">fastparquet</a>
 Python package for a potentially lighter solution.</p>
<h2 id="acknowledgements">Acknowledgements
</h2>
<p>nanoparquet would not exist without the work of Hannes Mühleisen on <a href="https://github.com/hannes/miniparquet" target="_blank" rel="noopener">miniparquet</a>
, which had similar goals, but it is discontinued now. nanoparquet is a fork of miniparquet.</p>
<p>nanoparquet also contains code and test Parquet files from DuckDB, Apache Parquet, Apache Arrow, Apache Thrift, it contains libraries from Google, Facebook, etc. see the <a href="https://github.com/r-lib/nanoparquet/blob/main/inst/COPYRIGHTS" target="_blank" rel="noopener">COPYRIGHTS file</a>
 in the repository for the full details.</p>
]]></description>
      <enclosure url="https://posit-open-source.netlify.app/blog/tidyverse/2024/nanoparquet-0-3-0/thumbnail-wd.jpg" length="72101" type="image/jpeg" />
    </item>
    <item>
      <title>News from the sparkly-verse</title>
      <link>https://posit-open-source.netlify.app/blog/ai/sparklyr-updates-q1-2024/</link>
      <pubDate>Mon, 22 Apr 2024 00:00:00 +0000</pubDate>
      <guid>https://posit-open-source.netlify.app/blog/ai/sparklyr-updates-q1-2024/</guid>
      <dc:creator>Edgar Ruiz</dc:creator><description><![CDATA[<h2 id="highlights">Highlights
</h2>
<p><code>sparklyr</code> and friends have been getting some important updates in the past few
months, here are some highlights:</p>
<ul>
<li>
<p><code>spark_apply()</code> now works on Databricks Connect v2</p>
</li>
<li>
<p><code>sparkxgb</code> is coming back to life</p>
</li>
<li>
<p>Support for Spark 2.3 and below has ended</p>
</li>
</ul>
<h2 id="pysparklyr-014">pysparklyr 0.1.4
</h2>
<p><code>spark_apply()</code> now works on Databricks Connect v2. The latest <code>pysparklyr</code>
release uses the <code>rpy2</code> Python library as the backbone of the integration.</p>
<p>Databricks Connect v2, is based on Spark Connect. At this time, it supports
Python user-defined functions (UDFs), but not R user-defined functions.
Using <code>rpy2</code> circumvents this limitation. As shown in the diagram, <code>sparklyr</code>
sends the the R code to the locally installed <code>rpy2</code>, which in turn sends it
to Spark. Then the <code>rpy2</code> installed in the remote Databricks cluster will run
the R code.</p>
<figure>
<img src="https://posit-open-source.netlify.app/blog/ai/sparklyr-updates-q1-2024/images/r-udfs.png" data-fig-alt="Diagram that shows how sparklyr transmits the R code via the rpy2 python package, and how Spark uses it to run the R code" width="600" alt="R code via rpy2" />
<figcaption aria-hidden="true">R code via rpy2</figcaption>
</figure>
<p>A big advantage of this approach, is that <code>rpy2</code> supports Arrow. In fact it
is the recommended Python library to use when integrating <a href="https://arrow.apache.org/docs/python/integration/python_r.html" target="_blank" rel="noopener">Spark, Arrow and
R</a>
.
This means that the data exchange between the three environments will be much
faster!</p>
<p>As in its original implementation, schema inferring works, and as with the
original implementation, it has a performance cost. But unlike the original,
this implementation will return a &lsquo;columns&rsquo; specification that you can use
for the next time you run the call.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="nf">spark_apply</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">  <span class="n">tbl_mtcars</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="n">nrow</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="n">group_by</span> <span class="o">=</span> <span class="s">&#34;am&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; To increase performance, use the following schema:</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; columns = &#34;am double, x long&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; # Source:   table&lt;`sparklyr_tmp_table_b84460ea_b1d3_471b_9cef_b13f339819b6`&gt; [2 x 2]</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; # Database: spark_connection</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt;      am     x</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt;   &lt;dbl&gt; &lt;dbl&gt;</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; 1     0    19</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; 2     1    13</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>A full article about this new capability is available here:
<a href="https://spark.posit.co/deployment/databricks-connect-udfs.html" target="_blank" rel="noopener">Run R inside Databricks Connect</a>
</p>
<h2 id="sparkxgb">sparkxgb
</h2>
<p>The <code>sparkxgb</code> is an extension of <code>sparklyr</code>. It enables integration with
<a href="https://xgboost.readthedocs.io/en/stable/" target="_blank" rel="noopener">XGBoost</a>
. The current CRAN release
does not support the latest versions of XGBoost. This limitation has recently
prompted a full refresh of <code>sparkxgb</code>. Here is a summary of the improvements,
which are currently in the <a href="https://github.com/rstudio/sparkxgb" target="_blank" rel="noopener">development version of the package</a>
:</p>
<ul>
<li>
<p>The <code>xgboost_classifier()</code> and <code>xgboost_regressor()</code> functions no longer
pass values of two arguments. These were deprecated by XGBoost and
cause an error if used. In the R function, the arguments will remain for
backwards compatibility, but will generate an informative error if not left <code>NULL</code>:</p>
<ul>
<li><code>sketch_eps</code> - As of <a href="https://github.com/dmlc/xgboost/blob/59d7b8dc72df7ed942885676964ea0a681d09590/NEWS.md?plain=1#L494" target="_blank" rel="noopener">XGBoost version 1.6.0</a>

<code>sketch_eps</code> was replaced by <code>max_bins</code></li>
<li><code>timeout_request_workers</code> - Removed in <a href="https://github.com/dmlc/xgboost/blob/59d7b8dc72df7ed942885676964ea0a681d09590/NEWS.md?plain=1#L398" target="_blank" rel="noopener">XGBoost version 1.7.0</a>

because it was no longer needed when XGBoost added barrier support</li>
</ul>
</li>
<li>
<p>Updates the JVM version used during the Spark session. It now uses <a href="https://central.sonatype.com/artifact/ml.dmlc/xgboost4j-spark_2.12" target="_blank" rel="noopener">xgboost4j-spark
version 2.0.3</a>
,
instead of 0.8.1. This gives us access to XGboost&rsquo;s most recent Spark code.</p>
</li>
<li>
<p>Updates code that used deprecated functions from upstream R dependencies. It
also stops using an un-maintained package as a dependency (<code>forge</code>). This
eliminated all of the warnings that were happening when fitting a model.</p>
</li>
<li>
<p>Major improvements to package testing. Unit tests were updated and expanded,
the way <code>sparkxgb</code> automatically starts and stops the Spark session for testing
was modernized, and the continuous integration tests were restored. This will
ensure the package&rsquo;s health going forward.</p>
</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="n">remotes</span><span class="o">::</span><span class="nf">install_github</span><span class="p">(</span><span class="s">&#34;rstudio/sparkxgb&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nf">library</span><span class="p">(</span><span class="n">sparkxgb</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nf">library</span><span class="p">(</span><span class="n">sparklyr</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">sc</span> <span class="o">&lt;-</span> <span class="nf">spark_connect</span><span class="p">(</span><span class="n">master</span> <span class="o">=</span> <span class="s">&#34;local&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">iris_tbl</span> <span class="o">&lt;-</span> <span class="nf">copy_to</span><span class="p">(</span><span class="n">sc</span><span class="p">,</span> <span class="n">iris</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">xgb_model</span> <span class="o">&lt;-</span> <span class="nf">xgboost_classifier</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">  <span class="n">iris_tbl</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="n">Species</span> <span class="o">~</span> <span class="n">.,</span>
</span></span><span class="line"><span class="cl">  <span class="n">num_class</span> <span class="o">=</span> <span class="m">3</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="n">num_round</span> <span class="o">=</span> <span class="m">50</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="n">max_depth</span> <span class="o">=</span> <span class="m">4</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">xgb_model</span> <span class="o">%&gt;%</span> 
</span></span><span class="line"><span class="cl">  <span class="nf">ml_predict</span><span class="p">(</span><span class="n">iris_tbl</span><span class="p">)</span> <span class="o">%&gt;%</span> 
</span></span><span class="line"><span class="cl">  <span class="nf">select</span><span class="p">(</span><span class="n">Species</span><span class="p">,</span> <span class="n">predicted_label</span><span class="p">,</span> <span class="nf">starts_with</span><span class="p">(</span><span class="s">&#34;probability_&#34;</span><span class="p">))</span> <span class="o">%&gt;%</span> 
</span></span><span class="line"><span class="cl">  <span class="n">dplyr</span><span class="o">::</span><span class="nf">glimpse</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; Rows: ??</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; Columns: 5</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; Database: spark_connection</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; $ Species                &lt;chr&gt; &#34;setosa&#34;, &#34;setosa&#34;, &#34;setosa&#34;, &#34;setosa&#34;, &#34;setosa…</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; $ predicted_label        &lt;chr&gt; &#34;setosa&#34;, &#34;setosa&#34;, &#34;setosa&#34;, &#34;setosa&#34;, &#34;setosa…</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; $ probability_setosa     &lt;dbl&gt; 0.9971547, 0.9948581, 0.9968392, 0.9968392, 0.9…</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; $ probability_versicolor &lt;dbl&gt; 0.002097376, 0.003301427, 0.002284616, 0.002284…</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&gt; $ probability_virginica  &lt;dbl&gt; 0.0007479066, 0.0018403779, 0.0008762418, 0.000…</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="sparklyr-185">sparklyr 1.8.5
</h2>
<p>The new version of <code>sparklyr</code> does not have user facing improvements. But
internally, it has crossed an important milestone. Support for Spark version 2.3
and below has effectively ended. The Scala
code needed to do so is no longer part of the package. As per Spark&rsquo;s versioning
policy, <a href="https://spark.apache.org/versioning-policy.html" target="_blank" rel="noopener">found here</a>
,
Spark 2.3 was &rsquo;end-of-life&rsquo; in 2018.</p>
<p>This is part of a larger, and ongoing effort to make the immense code-base of
<code>sparklyr</code> a little easier to maintain, and hence reduce the risk of failures.
As part of the same effort, the number of upstream packages that <code>sparklyr</code>
depends on have been reduced. This has been happening across multiple CRAN
releases, and in this latest release <code>tibble</code>, and <code>rappdirs</code> are no longer
imported by <code>sparklyr</code>.</p>
]]></description>
      <enclosure url="https://posit-open-source.netlify.app/blog/ai/sparklyr-updates-q1-2024/thumbnail.png" length="314789" type="image/png" />
    </item>
    <item>
      <title>dbplyr 2.5.0</title>
      <link>https://posit-open-source.netlify.app/blog/tidyverse/2024/dbplyr-2-5-0/</link>
      <pubDate>Mon, 08 Apr 2024 00:00:00 +0000</pubDate>
      <guid>https://posit-open-source.netlify.app/blog/tidyverse/2024/dbplyr-2-5-0/</guid>
      <dc:creator>Hadley Wickham</dc:creator><description><![CDATA[<!--
TODO:
* [x] Look over / edit the post's title in the yaml
* [x] Edit (or delete) the description; note this appears in the Twitter card
* [x] Pick category and tags (see existing with [`hugodown::tidy_show_meta()`](https://rdrr.io/pkg/hugodown/man/use_tidy_post.html))
* [x] Find photo & update yaml metadata
* [x] Create `thumbnail-sq.jpg`; height and width should be equal
* [x] Create `thumbnail-wd.jpg`; width should be >5x height
* [x] [`hugodown::use_tidy_thumbnails()`](https://rdrr.io/pkg/hugodown/man/use_tidy_post.html)
* [x] Add intro sentence, e.g. the standard tagline for the package
* [x] [`usethis::use_tidy_thanks()`](https://usethis.r-lib.org/reference/use_tidy_thanks.html)
-->
<p>We&rsquo;re most pleased to announce the release of <a href="http://dbplyr.tidyverse.org/" target="_blank" rel="noopener">dbplyr</a>
 2.5.0. dbplyr is a database backend for dplyr that allows you to use a remote database as if it was a collection of local data frames: you write ordinary dplyr code and dbplyr translates it to SQL for you.</p>
<p>You can install it from CRAN with:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nf'><a href='https://rdrr.io/r/utils/install.packages.html'>install.packages</a></span><span class='o'>(</span><span class='s'>"dbplyr"</span><span class='o'>)</span></span></code></pre>
</div>
<p>This post focuses on the biggest change in dbplyr 2.5.0: improved syntax for tables nested inside schema and catalogs. As usual, this release also contains a ton of minor improvements to SQL generation, and I&rsquo;d highly recommend skimming the <a href="https://github.com/tidyverse/dbplyr/releases/tag/v2.5.0" target="_blank" rel="noopener">release notes</a>
 to learn the details.</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='kr'><a href='https://rdrr.io/r/base/library.html'>library</a></span><span class='o'>(</span><span class='nv'><a href='https://dbplyr.tidyverse.org/'>dbplyr</a></span><span class='o'>)</span></span></code></pre>
</div>
<h2 id="referring-to-tables-in-a-schema">Referring to tables in a schema
</h2>
<p>Historically, dbplyr has provided a bewildering array of options to specify a table inside a schema inside a catalog:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>con</span> <span class='o'>|&gt;</span> <span class='nf'>tbl</span><span class='o'>(</span><span class='nf'><a href='https://dbplyr.tidyverse.org/reference/ident_q.html'>ident_q</a></span><span class='o'>(</span><span class='s'>"catalog_name.schema_name.table_name"</span><span class='o'>)</span><span class='o'>)</span></span>
<span><span class='nv'>con</span> <span class='o'>|&gt;</span> <span class='nf'>tbl</span><span class='o'>(</span><span class='nf'><a href='https://dbplyr.tidyverse.org/reference/sql.html'>sql</a></span><span class='o'>(</span><span class='s'>"SELECT * FROM catalog_name.schema_name.table_name"</span><span class='o'>)</span><span class='o'>)</span></span>
<span><span class='nv'>con</span> <span class='o'>|&gt;</span> <span class='nf'>tbl</span><span class='o'>(</span><span class='nf'><a href='https://dbplyr.tidyverse.org/reference/in_schema.html'>in_catalog</a></span><span class='o'>(</span><span class='s'>"catalog_name"</span>, <span class='s'>"schema_name"</span>, <span class='s'>"table_name"</span><span class='o'>)</span><span class='o'>)</span></span>
<span><span class='nv'>con</span> <span class='o'>|&gt;</span> <span class='nf'>tbl</span><span class='o'>(</span><span class='nf'><a href='https://dbplyr.tidyverse.org/reference/ident_q.html'>ident_q</a></span><span class='o'>(</span><span class='s'>"catalog_name.schema_name"</span><span class='o'>)</span>, <span class='s'>"table_name"</span><span class='o'>)</span></span>
<span><span class='nv'>con</span> <span class='o'>|&gt;</span> <span class='nf'>tbl</span><span class='o'>(</span><span class='nf'><a href='https://dbplyr.tidyverse.org/reference/sql.html'>sql</a></span><span class='o'>(</span><span class='s'>"catalog_name.schema_name"</span><span class='o'>)</span>, <span class='s'>"table_name"</span><span class='o'>)</span></span></code></pre>
</div>
<p>You can also use <a href="https://dbi.r-dbi.org/reference/Id.html" target="_blank" rel="noopener"><code>DBI::Id()</code></a>
, whose syntax has also evolved over time:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>con</span> <span class='o'>|&gt;</span> <span class='nf'>tbl</span><span class='o'>(</span><span class='nf'>DBI</span><span class='nf'>::</span><span class='nf'><a href='https://dbi.r-dbi.org/reference/Id.html'>Id</a></span><span class='o'>(</span>database <span class='o'>=</span> <span class='s'>"catalog_name"</span>, schema <span class='o'>=</span> <span class='s'>"schema_name"</span>, table <span class='o'>=</span> <span class='s'>"table_name"</span><span class='o'>)</span><span class='o'>)</span></span>
<span><span class='nv'>con</span> <span class='o'>|&gt;</span> <span class='nf'>tbl</span><span class='o'>(</span><span class='nf'>DBI</span><span class='nf'>::</span><span class='nf'><a href='https://dbi.r-dbi.org/reference/Id.html'>Id</a></span><span class='o'>(</span>catalog <span class='o'>=</span> <span class='s'>"catalog_name"</span>, schema <span class='o'>=</span> <span class='s'>"schema_name"</span>, table <span class='o'>=</span> <span class='s'>"table_name"</span><span class='o'>)</span><span class='o'>)</span></span>
<span><span class='nv'>con</span> <span class='o'>|&gt;</span> <span class='nf'>tbl</span><span class='o'>(</span><span class='nf'>DBI</span><span class='nf'>::</span><span class='nf'><a href='https://dbi.r-dbi.org/reference/Id.html'>Id</a></span><span class='o'>(</span><span class='s'>"catalog_name"</span>, <span class='s'>"schema_name"</span>, <span class='s'>"table_name"</span><span class='o'>)</span><span class='o'>)</span></span></code></pre>
</div>
<p>Many of these options were poorly supported (i.e. we would accidentally break them from time-to-time) and suffered from the lack of a holistic vision. This release aims to bring order to the chaos by providing a succinct new syntax for literal table identifiers: <a href="https://rdrr.io/r/base/AsIs.html" target="_blank" rel="noopener"><code>I()</code></a>
. This allows you to succinctly identify a table nested inside a schema or catalog:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>con</span> <span class='o'>|&gt;</span> <span class='nf'>tbl</span><span class='o'>(</span><span class='nf'><a href='https://rdrr.io/r/base/AsIs.html'>I</a></span><span class='o'>(</span><span class='s'>"catalog_name.schema_name.table_name"</span><span class='o'>)</span><span class='o'>)</span></span>
<span><span class='nv'>con</span> <span class='o'>|&gt;</span> <span class='nf'>tbl</span><span class='o'>(</span><span class='nf'><a href='https://rdrr.io/r/base/AsIs.html'>I</a></span><span class='o'>(</span><span class='s'>"schema_name.table_name"</span><span class='o'>)</span><span class='o'>)</span></span></code></pre>
</div>
<p><a href="https://rdrr.io/r/base/AsIs.html" target="_blank" rel="noopener"><code>I()</code></a>
 is a base function, and you may be familiar with it from modelling, e.g. <code>lm(y ~ x + I(y * z))</code>. It performs a similar role for both dbplyr and modelling function: it tells the function to treat the argument as is, rather than quoting it in the case of dbplyr, or interpreting as an interaction in the case of <a href="https://rdrr.io/r/stats/lm.html" target="_blank" rel="noopener"><code>lm()</code></a>
.</p>
<p><a href="https://rdrr.io/r/base/AsIs.html" target="_blank" rel="noopener"><code>I()</code></a>
 is dbplyr&rsquo;s preferred way of specifying nested table identifiers and we will eventually formally supersede and then one day deprecate the other options. However, because their usage is widespread, this process will be slow and gradual, and play out over multiple years; there&rsquo;s no need to make changes now.</p>
<p>(If you&rsquo;re the author of a dbplyr backend, you&rsquo;ll can take advantage of this new syntax by using the <code>dbplyr_table_path</code> class. dbplyr now provides a <a href="https://dbplyr.tidyverse.org/reference/is_table_path.html" target="_blank" rel="noopener">few helper functions</a>
 to make this easier.)</p>
<h2 id="acknowledgements">Acknowledgements
</h2>
<p>A big thanks to all 46 folks who helped to make this release possible with their thoughtful comments and code contributions! <a href="https://github.com/aarizvi" target="_blank" rel="noopener">@aarizvi</a>
, <a href="https://github.com/abalter" target="_blank" rel="noopener">@abalter</a>
, <a href="https://github.com/andreassoteriadesmoj" target="_blank" rel="noopener">@andreassoteriadesmoj</a>
, <a href="https://github.com/andrew-schulman" target="_blank" rel="noopener">@andrew-schulman</a>
, <a href="https://github.com/apalacio9502" target="_blank" rel="noopener">@apalacio9502</a>
, <a href="https://github.com/carlinstarrs" target="_blank" rel="noopener">@carlinstarrs</a>
, <a href="https://github.com/catalamarti" target="_blank" rel="noopener">@catalamarti</a>
, <a href="https://github.com/chicotobi" target="_blank" rel="noopener">@chicotobi</a>
, <a href="https://github.com/DavisVaughan" target="_blank" rel="noopener">@DavisVaughan</a>
, <a href="https://github.com/dmenne" target="_blank" rel="noopener">@dmenne</a>
, <a href="https://github.com/edgararuiz" target="_blank" rel="noopener">@edgararuiz</a>
, <a href="https://github.com/edonnachie" target="_blank" rel="noopener">@edonnachie</a>
, <a href="https://github.com/eitsupi" target="_blank" rel="noopener">@eitsupi</a>
, <a href="https://github.com/ejneer" target="_blank" rel="noopener">@ejneer</a>
, <a href="https://github.com/erydit" target="_blank" rel="noopener">@erydit</a>
, <a href="https://github.com/espinielli" target="_blank" rel="noopener">@espinielli</a>
, <a href="https://github.com/fh-afrachioni" target="_blank" rel="noopener">@fh-afrachioni</a>
, <a href="https://github.com/ghost" target="_blank" rel="noopener">@ghost</a>
, <a href="https://github.com/godislobster" target="_blank" rel="noopener">@godislobster</a>
, <a href="https://github.com/gorcha" target="_blank" rel="noopener">@gorcha</a>
, <a href="https://github.com/hadley" target="_blank" rel="noopener">@hadley</a>
, <a href="https://github.com/hild0146" target="_blank" rel="noopener">@hild0146</a>
, <a href="https://github.com/JakeHurlbut" target="_blank" rel="noopener">@JakeHurlbut</a>
, <a href="https://github.com/jarodmeng" target="_blank" rel="noopener">@jarodmeng</a>
, <a href="https://github.com/Jiefei-Wang" target="_blank" rel="noopener">@Jiefei-Wang</a>
, <a href="https://github.com/joshbal" target="_blank" rel="noopener">@joshbal</a>
, <a href="https://github.com/kelseyroberts" target="_blank" rel="noopener">@kelseyroberts</a>
, <a href="https://github.com/kmishra9" target="_blank" rel="noopener">@kmishra9</a>
, <a href="https://github.com/krlmlr" target="_blank" rel="noopener">@krlmlr</a>
, <a href="https://github.com/m-muecke" target="_blank" rel="noopener">@m-muecke</a>
, <a href="https://github.com/maciekbanas" target="_blank" rel="noopener">@maciekbanas</a>
, <a href="https://github.com/marcusmunch" target="_blank" rel="noopener">@marcusmunch</a>
, <a href="https://github.com/mgarbuzov" target="_blank" rel="noopener">@mgarbuzov</a>
, <a href="https://github.com/mgirlich" target="_blank" rel="noopener">@mgirlich</a>
, <a href="https://github.com/misea" target="_blank" rel="noopener">@misea</a>
, <a href="https://github.com/MKatz-DHSC" target="_blank" rel="noopener">@MKatz-DHSC</a>
, <a href="https://github.com/Mkranj" target="_blank" rel="noopener">@Mkranj</a>
, <a href="https://github.com/multimeric" target="_blank" rel="noopener">@multimeric</a>
, <a href="https://github.com/nathanhaigh" target="_blank" rel="noopener">@nathanhaigh</a>
, <a href="https://github.com/nilescbn" target="_blank" rel="noopener">@nilescbn</a>
, <a href="https://github.com/talegari" target="_blank" rel="noopener">@talegari</a>
, <a href="https://github.com/Tazinho" target="_blank" rel="noopener">@Tazinho</a>
, <a href="https://github.com/thomashulst" target="_blank" rel="noopener">@thomashulst</a>
, <a href="https://github.com/Thranholm" target="_blank" rel="noopener">@Thranholm</a>
, <a href="https://github.com/tomshafer" target="_blank" rel="noopener">@tomshafer</a>
, and <a href="https://github.com/wstvcg" target="_blank" rel="noopener">@wstvcg</a>
.</p>
]]></description>
      <enclosure url="https://posit-open-source.netlify.app/blog/tidyverse/2024/dbplyr-2-5-0/thumbnail-wd.jpg" length="576303" type="image/jpeg" />
    </item>
    <item>
      <title>bigrquery 1.5.0</title>
      <link>https://posit-open-source.netlify.app/blog/tidyverse/2024/bigrquery-1-5-0/</link>
      <pubDate>Mon, 22 Jan 2024 00:00:00 +0000</pubDate>
      <guid>https://posit-open-source.netlify.app/blog/tidyverse/2024/bigrquery-1-5-0/</guid>
      <dc:creator>Hadley Wickham</dc:creator><description><![CDATA[<!--
TODO:
* [x] Look over / edit the post's title in the yaml
* [x] Edit (or delete) the description; note this appears in the Twitter card
* [x] Pick category and tags (see existing with [`hugodown::tidy_show_meta()`](https://rdrr.io/pkg/hugodown/man/use_tidy_post.html))
* [x] Find photo & update yaml metadata
* [x] Create `thumbnail-sq.jpg`; height and width should be equal
* [x] Create `thumbnail-wd.jpg`; width should be >5x height
* [x] [`hugodown::use_tidy_thumbnails()`](https://rdrr.io/pkg/hugodown/man/use_tidy_post.html)
* [x] Add intro sentence, e.g. the standard tagline for the package
* [x] [`usethis::use_tidy_thanks()`](https://usethis.r-lib.org/reference/use_tidy_thanks.html)
-->
<p>We&rsquo;re stoked to announce the release of <a href="http://bigrquery.r-dbi.org/" target="_blank" rel="noopener">bigrquery</a>
 1.5.0. bigrquery makes it easy to work with data stored in <a href="https://developers.google.com/bigquery/" target="_blank" rel="noopener">Google BigQuery</a>
, a hosted database for big data.</p>
<p>You can install it from CRAN with:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nf'><a href='https://rdrr.io/r/utils/install.packages.html'>install.packages</a></span><span class='o'>(</span><span class='s'>"bigrquery"</span><span class='o'>)</span></span></code></pre>
</div>
<p>This has been the first major update to bigrquery for a while, and is mostly about catching up with innovations elsewhere as well as squashing a bunch of smaller annoyances.</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='kr'><a href='https://rdrr.io/r/base/library.html'>library</a></span><span class='o'>(</span><span class='nv'><a href='https://bigrquery.r-dbi.org'>bigrquery</a></span><span class='o'>)</span></span></code></pre>
</div>
<p>Here&rsquo;s a summary of the biggest changes:</p>
<ul>
<li>
<p>bigrquery is now <a href="https://www.tidyverse.org/blog/2021/12/relicensing-packages/" target="_blank" rel="noopener">MIT licensed</a>
.</p>
</li>
<li>
<p>Deprecated functions (i.e. those not starting with <code>bq_</code>) have been removed. These have been superseded for a long time and were formally deprecated in bigrquery 1.3.0 (2020).</p>
</li>
<li>
<p><a href="https://bigrquery.r-dbi.org/reference/bq_table_download.html" target="_blank" rel="noopener"><code>bq_table_download()</code></a>
 now returns unknown fields as character vectors. In particular, this means that <code>BIGNUMERIC</code> and <code>JSON</code> columns are downloaded into R for you to process as you wish. <a href="https://bigrquery.r-dbi.org/reference/bq_table_download.html" target="_blank" rel="noopener"><code>bq_table_download()</code></a>
 now uses the <a href="https://clock.r-lib.org" target="_blank" rel="noopener">clock package</a>
 to parse dates, leading to a considerable performance improvement and correct parsing for dates prior to 1970-01-01.</p>
</li>
<li>
<p>bigquery datasets and tables will now appear in the <a href="https://docs.posit.co/ide/user/ide/guide/data/data-connections.html" target="_blank" rel="noopener">RStudio connections pane</a>
 when connecting with <a href="https://dbi.r-dbi.org/reference/dbConnect.html" target="_blank" rel="noopener"><code>DBI::dbConnect()</code></a>
.</p>
</li>
<li>
<p><code>DBI::dbAppendTable(),</code> <a href="https://dbi.r-dbi.org/reference/dbCreateTable.html" target="_blank" rel="noopener"><code>DBI::dbCreateTable()</code></a>
, and <a href="https://dbi.r-dbi.org/reference/dbExecute.html" target="_blank" rel="noopener"><code>DBI::dbExecute()</code></a>
 are now supported, and <a href="https://dbi.r-dbi.org/reference/dbGetQuery.html" target="_blank" rel="noopener"><code>DBI::dbGetQuery()</code></a>
/<a href="https://dbi.r-dbi.org/reference/dbSendQuery.html" target="_blank" rel="noopener"><code>DBI::dbSendQuery()</code></a>
 support parameterised queries via the <code>params</code> argument. <a href="https://dbi.r-dbi.org/reference/dbReadTable.html" target="_blank" rel="noopener"><code>DBI::dbReadTable()</code></a>
, <a href="https://dbi.r-dbi.org/reference/dbWriteTable.html" target="_blank" rel="noopener"><code>DBI::dbWriteTable()</code></a>
, <a href="https://dbi.r-dbi.org/reference/dbExistsTable.html" target="_blank" rel="noopener"><code>DBI::dbExistsTable()</code></a>
, <a href="https://dbi.r-dbi.org/reference/dbRemoveTable.html" target="_blank" rel="noopener"><code>DBI::dbRemoveTable()</code></a>
, and <a href="https://dbi.r-dbi.org/reference/dbListFields.html" target="_blank" rel="noopener"><code>DBI::dbListFields()</code></a>
 now all work with <a href="https://dbi.r-dbi.org/reference/Id.html" target="_blank" rel="noopener"><code>DBI::Id()</code></a>
.</p>
</li>
<li>
<p>bigrquery now uses 2nd edition of dbplyr interface and is compatible with dbplyr 2.4.0.</p>
</li>
</ul>
<p>See the <a href="https://github.com/r-dbi/bigrquery/releases/tag/v1.5.0" target="_blank" rel="noopener">release notes</a>
 for a full list of changes.</p>
<h2 id="acknowledgements">Acknowledgements
</h2>
<p>A big thanks to all 14 folks who helped make this release happen with questions, comments, and code: <a href="https://github.com/abalter" target="_blank" rel="noopener">@abalter</a>
, <a href="https://github.com/ablack3" target="_blank" rel="noopener">@ablack3</a>
, <a href="https://github.com/evanrollinsdrumline" target="_blank" rel="noopener">@evanrollinsdrumline</a>
, <a href="https://github.com/hadley" target="_blank" rel="noopener">@hadley</a>
, <a href="https://github.com/husseyd" target="_blank" rel="noopener">@husseyd</a>
, <a href="https://github.com/jacobmpeters" target="_blank" rel="noopener">@jacobmpeters</a>
, <a href="https://github.com/jennybc" target="_blank" rel="noopener">@jennybc</a>
, <a href="https://github.com/Kvit" target="_blank" rel="noopener">@Kvit</a>
, <a href="https://github.com/meztez" target="_blank" rel="noopener">@meztez</a>
, <a href="https://github.com/mgirlich" target="_blank" rel="noopener">@mgirlich</a>
, <a href="https://github.com/MichaelChirico" target="_blank" rel="noopener">@MichaelChirico</a>
, <a href="https://github.com/mjbroerman" target="_blank" rel="noopener">@mjbroerman</a>
, <a href="https://github.com/ncuriale" target="_blank" rel="noopener">@ncuriale</a>
, and <a href="https://github.com/rdavis120" target="_blank" rel="noopener">@rdavis120</a>
.</p>
]]></description>
      <enclosure url="https://posit-open-source.netlify.app/blog/tidyverse/2024/bigrquery-1-5-0/thumbnail-wd.jpg" length="743641" type="image/jpeg" />
    </item>
    <item>
      <title>httr2 1.0.0</title>
      <link>https://posit-open-source.netlify.app/blog/tidyverse/2023/httr2-1-0-0/</link>
      <pubDate>Tue, 14 Nov 2023 00:00:00 +0000</pubDate>
      <guid>https://posit-open-source.netlify.app/blog/tidyverse/2023/httr2-1-0-0/</guid>
      <dc:creator>Hadley Wickham</dc:creator><description><![CDATA[<!--
TODO:
* [x] Look over / edit the post's title in the yaml
* [x] Edit (or delete) the description; note this appears in the Twitter card
* [x] Pick category and tags (see existing with [`hugodown::tidy_show_meta()`](https://rdrr.io/pkg/hugodown/man/use_tidy_post.html))
* [x] Find photo & update yaml metadata
* [x] Create `thumbnail-sq.jpg`; height and width should be equal
* [x] Create `thumbnail-wd.jpg`; width should be >5x height
* [x] [`hugodown::use_tidy_thumbnails()`](https://rdrr.io/pkg/hugodown/man/use_tidy_post.html)
* [x] Add intro sentence, e.g. the standard tagline for the package
* [x] [`usethis::use_tidy_thanks()`](https://usethis.r-lib.org/reference/use_tidy_thanks.html)
-->
<p>We&rsquo;re delighted to announce the release of <a href="https://httr2.r-lib.org" target="_blank" rel="noopener">httr2</a>
<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup> 1.0.0. httr2 is the second generation of httr: it helps you generate HTTP requests and process the responses, designed with an eye towards modern web APIs and potentially putting your code in a package.</p>
<p>You can install it from CRAN with:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nf'><a href='https://rdrr.io/r/utils/install.packages.html'>install.packages</a></span><span class='o'>(</span><span class='s'>"httr2"</span><span class='o'>)</span></span></code></pre>
</div>
<p>httr2 has been under development for the last two years, but this is the first time we&rsquo;ve blogged about it because we&rsquo;ve been waiting until the user interface felt stable. It now does, and we&rsquo;re ready to encourage you to use httr2 whenever you need to talk to a web server. Most importantly httr2 is now a &ldquo;real&rdquo; package because it has a wonderful new logo, thanks to a collaborative effort involving Julie Jung, Greg Swineheart, and DALL•E 3.</p>
<div class="highlight">
<img src="https://posit-open-source.netlify.app/blog/tidyverse/2023/httr2-1-0-0/httr2.png" alt="The new httr2 logo is a dark blue hexagon with httr2 written in bright white at the top of logo. Underneath the text is a vibrant magenta baseball player hitting a ball emblazoned with the letters &quot;www&quot;." width="200px" style="display: block; margin: auto;" />
</div>
<p>httr2 is the successor to httr. The biggest difference is that it has an explicit request object which you can build up over multiple function calls. This makes the interface fit more naturally with the pipe, and generally makes life easier because you can iteratively build up a complex request. httr2 also builds on the 10 years of package development experience we&rsquo;ve accrued since creating httr, so it should all around be more enjoyable to use. If you&rsquo;re a current httr user, there&rsquo;s no need to switch, as we&rsquo;ll continue to maintain the package for many years to come, but if you start on a new project, I&rsquo;d recommend that you give httr2 a shot.</p>
<p>If you&rsquo;ve been following httr2 development for a while, you might want to jump to the <a href="https://github.com/r-lib/httr2/releases/tag/v1.0.0" target="_blank" rel="noopener">release notes</a>
 to see what&rsquo;s new (a lot!). The most important change in this release is that <a href="https://github.com/mgirlich" target="_blank" rel="noopener">Maximilian Girlich</a>
 is now a httr2 author, in recognition of his many contributions to the package. This release also features improved tools for performing multiple requests (more on that below) and a bunch of bug fixes and minor improvements for OAuth.</p>
<p>For the rest of this blog post, I&rsquo;ll assume that you&rsquo;re familiar with the basics of HTTP. If you&rsquo;re not, you might want to start with <code>vignette(&quot;httr2&quot;)</code> which introduces you to HTTP using httr2.</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='kr'><a href='https://rdrr.io/r/base/library.html'>library</a></span><span class='o'>(</span><span class='nv'><a href='https://httr2.r-lib.org'>httr2</a></span><span class='o'>)</span></span></code></pre>
</div>
<h2 id="making-a-request">Making a request
</h2>
<p>httr2 is designed around the two big pieces of HTTP: requests and responses. First you&rsquo;ll create a request, with a URL:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>req</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://httr2.r-lib.org/reference/request.html'>request</a></span><span class='o'>(</span><span class='nf'><a href='https://httr2.r-lib.org/reference/example_url.html'>example_url</a></span><span class='o'>(</span><span class='o'>)</span><span class='o'>)</span></span>
<span><span class='nv'>req</span></span>
<span><span class='c'>#&gt; <span style='color: #0000BB;'>&lt;httr2_request&gt;</span></span></span>
<span></span><span><span class='c'>#&gt; <span style='font-weight: bold;'>GET</span> http://127.0.0.1:51981/</span></span>
<span></span><span><span class='c'>#&gt; <span style='font-weight: bold;'>Body</span>: empty</span></span>
<span></span></code></pre>
</div>
<p>Instead of using an external website, here we&rsquo;re using a test server that&rsquo;s built in to httr2. This ensures that this blog post, and many httr2 examples, work independently from the rest of the internet.</p>
<p>You can see the HTTP request that httr2 will send, without actually sending it<sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup>, by doing a dry run:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>req</span> <span class='o'>|&gt;</span> <span class='nf'><a href='https://httr2.r-lib.org/reference/req_dry_run.html'>req_dry_run</a></span><span class='o'>(</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; GET / HTTP/1.1</span></span>
<span><span class='c'>#&gt; <span style='font-weight: bold;'>Host</span>: 127.0.0.1:51981</span></span>
<span><span class='c'>#&gt; <span style='font-weight: bold;'>User-Agent</span>: httr2/0.2.3.9000 r-curl/5.1.0 libcurl/8.1.2</span></span>
<span><span class='c'>#&gt; <span style='font-weight: bold;'>Accept</span>: */*</span></span>
<span><span class='c'>#&gt; <span style='font-weight: bold;'>Accept-Encoding</span>: deflate, gzip</span></span>
<span></span></code></pre>
</div>
<p>As you can see, this request object will perform a simple <code>GET</code> request with automatic user agent and accept headers.</p>
<p>To make more complex requests, you modify the request object with functions that start with <code>req_</code>. For example, you could make it a <code>HEAD</code> request, with some query parameters, and a custom user agent:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>req</span> <span class='o'>|&gt;</span> </span>
<span>  <span class='nf'><a href='https://httr2.r-lib.org/reference/req_url.html'>req_url_query</a></span><span class='o'>(</span>param <span class='o'>=</span> <span class='s'>"value"</span><span class='o'>)</span> <span class='o'>|&gt;</span> </span>
<span>  <span class='nf'><a href='https://httr2.r-lib.org/reference/req_user_agent.html'>req_user_agent</a></span><span class='o'>(</span><span class='s'>"My user agent"</span><span class='o'>)</span> <span class='o'>|&gt;</span> </span>
<span>  <span class='nf'><a href='https://httr2.r-lib.org/reference/req_method.html'>req_method</a></span><span class='o'>(</span><span class='s'>"HEAD"</span><span class='o'>)</span> <span class='o'>|&gt;</span> </span>
<span>  <span class='nf'><a href='https://httr2.r-lib.org/reference/req_dry_run.html'>req_dry_run</a></span><span class='o'>(</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; HEAD /?param=value HTTP/1.1</span></span>
<span><span class='c'>#&gt; <span style='font-weight: bold;'>Host</span>: 127.0.0.1:51981</span></span>
<span><span class='c'>#&gt; <span style='font-weight: bold;'>User-Agent</span>: My user agent</span></span>
<span><span class='c'>#&gt; <span style='font-weight: bold;'>Accept</span>: */*</span></span>
<span><span class='c'>#&gt; <span style='font-weight: bold;'>Accept-Encoding</span>: deflate, gzip</span></span>
<span></span></code></pre>
</div>
<p>Or you could send some JSON in the body of the request:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>req</span> <span class='o'>|&gt;</span> </span>
<span>  <span class='nf'><a href='https://httr2.r-lib.org/reference/req_body.html'>req_body_json</a></span><span class='o'>(</span><span class='nf'><a href='https://rdrr.io/r/base/list.html'>list</a></span><span class='o'>(</span>x <span class='o'>=</span> <span class='m'>1</span>, y <span class='o'>=</span> <span class='s'>"a"</span><span class='o'>)</span><span class='o'>)</span> <span class='o'>|&gt;</span> </span>
<span>  <span class='nf'><a href='https://httr2.r-lib.org/reference/req_dry_run.html'>req_dry_run</a></span><span class='o'>(</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; POST / HTTP/1.1</span></span>
<span><span class='c'>#&gt; <span style='font-weight: bold;'>Host</span>: 127.0.0.1:51981</span></span>
<span><span class='c'>#&gt; <span style='font-weight: bold;'>User-Agent</span>: httr2/0.2.3.9000 r-curl/5.1.0 libcurl/8.1.2</span></span>
<span><span class='c'>#&gt; <span style='font-weight: bold;'>Accept</span>: */*</span></span>
<span><span class='c'>#&gt; <span style='font-weight: bold;'>Accept-Encoding</span>: deflate, gzip</span></span>
<span><span class='c'>#&gt; <span style='font-weight: bold;'>Content-Type</span>: application/json</span></span>
<span><span class='c'>#&gt; <span style='font-weight: bold;'>Content-Length</span>: 15</span></span>
<span><span class='c'>#&gt; </span></span>
<span><span class='c'>#&gt; &#123;"x":1,"y":"a"&#125;</span></span>
<span></span></code></pre>
</div>
<p>httr2 provides a <a href="https://httr2.r-lib.org/dev/reference/index.html#requests" target="_blank" rel="noopener">wide range of <code>req_</code> function</a>
 to customise the request in common ways; if there&rsquo;s something you need that httr2 doesn&rsquo;t support, please <a href="https://github.com/r-lib/httr2/issues/new" target="_blank" rel="noopener">file an issue</a>
!</p>
<h2 id="performing-the-request-and-handling-the-response">Performing the request and handling the response
</h2>
<p>Once you have a request that you are happy with, you can send it to the server with <a href="https://httr2.r-lib.org/reference/req_perform.html" target="_blank" rel="noopener"><code>req_perform()</code></a>
:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>req_json</span> <span class='o'>&lt;-</span> <span class='nv'>req</span> <span class='o'>|&gt;</span> <span class='nf'><a href='https://httr2.r-lib.org/reference/req_url.html'>req_url_path</a></span><span class='o'>(</span><span class='s'>"/json"</span><span class='o'>)</span></span>
<span><span class='nv'>resp</span> <span class='o'>&lt;-</span> <span class='nv'>req_json</span> <span class='o'>|&gt;</span> <span class='nf'><a href='https://httr2.r-lib.org/reference/req_perform.html'>req_perform</a></span><span class='o'>(</span><span class='o'>)</span></span></code></pre>
</div>
<p>Performing a request will return a response object (or throw an error, which we&rsquo;ll talk about next). You can see the basic details of the request by printing it or you can see the raw response with <a href="https://httr2.r-lib.org/reference/resp_raw.html" target="_blank" rel="noopener"><code>resp_raw()</code></a>
<sup id="fnref:3"><a href="#fn:3" class="footnote-ref" role="doc-noteref">3</a></sup>:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>resp</span></span>
<span><span class='c'>#&gt; <span style='color: #0000BB;'>&lt;httr2_response&gt;</span></span></span>
<span></span><span><span class='c'>#&gt; <span style='font-weight: bold;'>GET</span> http://127.0.0.1:51981/json</span></span>
<span></span><span><span class='c'>#&gt; <span style='color: #00BB00;'>Status</span>: 200 OK</span></span>
<span></span><span><span class='c'>#&gt; <span style='color: #00BB00;'>Content-Type</span>: application/json</span></span>
<span></span><span><span class='c'>#&gt; <span style='color: #00BB00;'>Body</span>: In memory (407 bytes)</span></span>
<span></span><span></span>
<span><span class='nv'>resp</span> <span class='o'>|&gt;</span> <span class='nf'><a href='https://httr2.r-lib.org/reference/resp_raw.html'>resp_raw</a></span><span class='o'>(</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; HTTP/1.1 200 OK</span></span>
<span><span class='c'>#&gt; <span style='font-weight: bold;'>Connection</span>: close</span></span>
<span><span class='c'>#&gt; <span style='font-weight: bold;'>Date</span>: Tue, 14 Nov 2023 14:41:32 GMT</span></span>
<span><span class='c'>#&gt; <span style='font-weight: bold;'>Content-Type</span>: application/json</span></span>
<span><span class='c'>#&gt; <span style='font-weight: bold;'>Content-Length</span>: 407</span></span>
<span><span class='c'>#&gt; <span style='font-weight: bold;'>ETag</span>: "de760e6d"</span></span>
<span><span class='c'>#&gt; </span></span>
<span><span class='c'>#&gt; &#123;</span></span>
<span><span class='c'>#&gt;   "firstName": "John",</span></span>
<span><span class='c'>#&gt;   "lastName": "Smith",</span></span>
<span><span class='c'>#&gt;   "isAlive": true,</span></span>
<span><span class='c'>#&gt;   "age": 27,</span></span>
<span><span class='c'>#&gt;   "address": &#123;</span></span>
<span><span class='c'>#&gt;     "streetAddress": "21 2nd Street",</span></span>
<span><span class='c'>#&gt;     "city": "New York",</span></span>
<span><span class='c'>#&gt;     "state": "NY",</span></span>
<span><span class='c'>#&gt;     "postalCode": "10021-3100"</span></span>
<span><span class='c'>#&gt;   &#125;,</span></span>
<span><span class='c'>#&gt;   "phoneNumbers": [</span></span>
<span><span class='c'>#&gt;     &#123;</span></span>
<span><span class='c'>#&gt;       "type": "home",</span></span>
<span><span class='c'>#&gt;       "number": "212 555-1234"</span></span>
<span><span class='c'>#&gt;     &#125;,</span></span>
<span><span class='c'>#&gt;     &#123;</span></span>
<span><span class='c'>#&gt;       "type": "office",</span></span>
<span><span class='c'>#&gt;       "number": "646 555-4567"</span></span>
<span><span class='c'>#&gt;     &#125;</span></span>
<span><span class='c'>#&gt;   ],</span></span>
<span><span class='c'>#&gt;   "children": [],</span></span>
<span><span class='c'>#&gt;   "spouse": null</span></span>
<span><span class='c'>#&gt; &#125;</span></span>
<span></span></code></pre>
</div>
<p>But generally, you&rsquo;ll want to use the <code>resp_</code> functions to extract parts of the response for further processing. For example, you could parse the JSON body into an R data structure:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>resp</span> <span class='o'>|&gt;</span> </span>
<span>  <span class='nf'><a href='https://httr2.r-lib.org/reference/resp_body_raw.html'>resp_body_json</a></span><span class='o'>(</span><span class='o'>)</span> <span class='o'>|&gt;</span> </span>
<span>  <span class='nf'><a href='https://rdrr.io/r/utils/str.html'>str</a></span><span class='o'>(</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; List of 8</span></span>
<span><span class='c'>#&gt;  $ firstName   : chr "John"</span></span>
<span><span class='c'>#&gt;  $ lastName    : chr "Smith"</span></span>
<span><span class='c'>#&gt;  $ isAlive     : logi TRUE</span></span>
<span><span class='c'>#&gt;  $ age         : int 27</span></span>
<span><span class='c'>#&gt;  $ address     :List of 4</span></span>
<span><span class='c'>#&gt;   ..$ streetAddress: chr "21 2nd Street"</span></span>
<span><span class='c'>#&gt;   ..$ city         : chr "New York"</span></span>
<span><span class='c'>#&gt;   ..$ state        : chr "NY"</span></span>
<span><span class='c'>#&gt;   ..$ postalCode   : chr "10021-3100"</span></span>
<span><span class='c'>#&gt;  $ phoneNumbers:List of 2</span></span>
<span><span class='c'>#&gt;   ..$ :List of 2</span></span>
<span><span class='c'>#&gt;   .. ..$ type  : chr "home"</span></span>
<span><span class='c'>#&gt;   .. ..$ number: chr "212 555-1234"</span></span>
<span><span class='c'>#&gt;   ..$ :List of 2</span></span>
<span><span class='c'>#&gt;   .. ..$ type  : chr "office"</span></span>
<span><span class='c'>#&gt;   .. ..$ number: chr "646 555-4567"</span></span>
<span><span class='c'>#&gt;  $ children    : list()</span></span>
<span><span class='c'>#&gt;  $ spouse      : NULL</span></span>
<span></span></code></pre>
</div>
<p>Or get the value of a header:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>resp</span> <span class='o'>|&gt;</span> <span class='nf'><a href='https://httr2.r-lib.org/reference/resp_headers.html'>resp_header</a></span><span class='o'>(</span><span class='s'>"Content-Length"</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; [1] "407"</span></span>
<span></span></code></pre>
</div>
<h2 id="error-handling">Error handling
</h2>
<p>You can use <a href="https://httr2.r-lib.org/reference/resp_status.html" target="_blank" rel="noopener"><code>resp_status()</code></a>
 to see the returned status:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>resp</span> <span class='o'>|&gt;</span> <span class='nf'><a href='https://httr2.r-lib.org/reference/resp_status.html'>resp_status</a></span><span class='o'>(</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; [1] 200</span></span>
<span></span></code></pre>
</div>
<p>But this will almost always be 200, because httr2 automatically follows redirects (statuses in the 300s) and turns HTTP failures (statuses in the 400s and 500s) into R errors. The following example shows what error handling looks like using an example endpoint that returns a response with the status defined in the URL:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>req</span> <span class='o'>|&gt;</span> </span>
<span>  <span class='nf'><a href='https://httr2.r-lib.org/reference/req_url.html'>req_url_path</a></span><span class='o'>(</span><span class='s'>"/status/404"</span><span class='o'>)</span> <span class='o'>|&gt;</span> </span>
<span>  <span class='nf'><a href='https://httr2.r-lib.org/reference/req_perform.html'>req_perform</a></span><span class='o'>(</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; <span style='color: #BBBB00; font-weight: bold;'>Error</span><span style='font-weight: bold;'> in `req_perform()`:</span></span></span>
<span><span class='c'>#&gt; <span style='color: #BBBB00;'>!</span> HTTP 404 Not Found.</span></span>
<span></span><span></span>
<span><span class='nv'>req</span> <span class='o'>|&gt;</span> </span>
<span>  <span class='nf'><a href='https://httr2.r-lib.org/reference/req_url.html'>req_url_path</a></span><span class='o'>(</span><span class='s'>"/status/500"</span><span class='o'>)</span> <span class='o'>|&gt;</span> </span>
<span>  <span class='nf'><a href='https://httr2.r-lib.org/reference/req_perform.html'>req_perform</a></span><span class='o'>(</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; <span style='color: #BBBB00; font-weight: bold;'>Error</span><span style='font-weight: bold;'> in `req_perform()`:</span></span></span>
<span><span class='c'>#&gt; <span style='color: #BBBB00;'>!</span> HTTP 500 Internal Server Error.</span></span>
<span></span></code></pre>
</div>
<p>Turning HTTP failures into R errors can make debugging hard, so httr2 provides the <a href="https://httr2.r-lib.org/reference/last_response.html" target="_blank" rel="noopener"><code>last_request()</code></a>
 and <a href="https://httr2.r-lib.org/reference/last_response.html" target="_blank" rel="noopener"><code>last_response()</code></a>
 helpers which you can use to figure out what went wrong:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nf'><a href='https://httr2.r-lib.org/reference/last_response.html'>last_request</a></span><span class='o'>(</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; <span style='color: #0000BB;'>&lt;httr2_request&gt;</span></span></span>
<span></span><span><span class='c'>#&gt; <span style='font-weight: bold;'>GET</span> http://127.0.0.1:51981/status/500</span></span>
<span></span><span><span class='c'>#&gt; <span style='font-weight: bold;'>Body</span>: empty</span></span>
<span></span><span></span>
<span><span class='nf'><a href='https://httr2.r-lib.org/reference/last_response.html'>last_response</a></span><span class='o'>(</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; <span style='color: #0000BB;'>&lt;httr2_response&gt;</span></span></span>
<span></span><span><span class='c'>#&gt; <span style='font-weight: bold;'>GET</span> http://127.0.0.1:51981/status/500</span></span>
<span></span><span><span class='c'>#&gt; <span style='color: #00BB00;'>Status</span>: 500 Internal Server Error</span></span>
<span></span><span><span class='c'>#&gt; <span style='color: #00BB00;'>Content-Type</span>: text/plain</span></span>
<span></span><span><span class='c'>#&gt; <span style='color: #00BB00;'>Body</span>: None</span></span>
<span></span></code></pre>
</div>
<p>httr2 provides two other tools to customise error handling:</p>
<ul>
<li><a href="https://httr2.r-lib.org/reference/req_error.html" target="_blank" rel="noopener"><code>req_error()</code></a>
 gives you full control over what responses should be turned into R errors, and allows you to add additional information to the error message.</li>
<li><a href="https://httr2.r-lib.org/reference/req_retry.html" target="_blank" rel="noopener"><code>req_retry()</code></a>
 helps deal with transient errors, where you need to wait a bit and try again. For example, many APIs are rate limited and will return a 429 status if you have made too many requests.</li>
</ul>
<p>You can learn more about both of these functions in &ldquo;<a href="https://httr2.r-lib.org/articles/wrapping-apis.html" target="_blank" rel="noopener">Wrapping APIs</a>
&rdquo; as they are particularly important when creating an R package (or script) that wraps a web API.</p>
<h2 id="control-the-request-process">Control the request process
</h2>
<p>There are a number of other <code>req_</code> functions that don&rsquo;t directly affect the HTTP request but instead control the overall process of submitting a request and handling the response. These include:</p>
<ul>
<li>
<p><a href="https://httr2.r-lib.org/reference/req_cache.html" target="_blank" rel="noopener"><code>req_cache()</code></a>
, which sets up a cache so if repeated requests return the same results, and you can avoid a trip to the server.</p>
</li>
<li>
<p><a href="https://httr2.r-lib.org/reference/req_throttle.html" target="_blank" rel="noopener"><code>req_throttle()</code></a>
, which automatically adds a small delay before each request so you can avoid hammering a server with many requests.</p>
</li>
<li>
<p><a href="https://httr2.r-lib.org/reference/req_progress.html" target="_blank" rel="noopener"><code>req_progress()</code></a>
, which adds a progress bar for long downloads or uploads.</p>
</li>
<li>
<p><a href="https://httr2.r-lib.org/reference/req_cookie_preserve.html" target="_blank" rel="noopener"><code>req_cookie_preserve()</code></a>
, which lets you preserve cookies across requests.</p>
</li>
</ul>
<p>Additionally, httr2 provides rich support for authenticating with OAuth, implementing many more OAuth flows than httr. You&rsquo;ve probably used OAuth a bunch without knowing what it&rsquo;s called: you use it when you login to a non-Google website using your Google account, when you give your phone access to your twitter account, or when you login to a streaming app on your smart TV. OAuth is a big, complex, topic, and is documented in &ldquo;<a href="https://httr2.r-lib.org/articles/oauth.html" target="_blank" rel="noopener">OAuth</a>
&rdquo;.</p>
<h2 id="multiple-requests">Multiple requests
</h2>
<p>httr2 includes three functions to perform multiple requests:</p>
<ul>
<li>
<p><a href="https://httr2.r-lib.org/reference/req_perform_sequential.html" target="_blank" rel="noopener"><code>req_perform_sequential()</code></a>
 takes a list of requests and performs them one at a time.</p>
</li>
<li>
<p><a href="https://httr2.r-lib.org/reference/req_perform_parallel.html" target="_blank" rel="noopener"><code>req_perform_parallel()</code></a>
 takes a list of requests and performs them in parallel (up to 6 at a time by default). It&rsquo;s similar to <a href="https://httr2.r-lib.org/reference/req_perform_sequential.html" target="_blank" rel="noopener"><code>req_perform_sequential()</code></a>
, but is obviously faster, at the expense of potentially hammering a server. It also has some limitations: most importantly it can&rsquo;t refresh an expired OAuth token and it doesn&rsquo;t respect <a href="https://httr2.r-lib.org/reference/req_retry.html" target="_blank" rel="noopener"><code>req_retry()</code></a>
 or <a href="https://httr2.r-lib.org/reference/req_throttle.html" target="_blank" rel="noopener"><code>req_throttle()</code></a>
.</p>
</li>
<li>
<p><a href="https://httr2.r-lib.org/reference/req_perform_iterative.html" target="_blank" rel="noopener"><code>req_perform_iterative()</code></a>
 takes a single request and a callback function to generate the next request from previous response. It&rsquo;ll keep going until the callback function returns <code>NULL</code> or <code>max_reqs</code> requests have been performed. This is very useful for paginated APIs that only tell you the URL for the <em>next</em> page.</p>
</li>
</ul>
<p>For example, imagine we wanted to download each person from the <a href="https://swapi.dev" target="_blank" rel="noopener">Star Wars API</a>
. The URLs have a very consistent structure so we can generate a bunch of them, then create the corresponding requests:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>urls</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://rdrr.io/r/base/paste.html'>paste0</a></span><span class='o'>(</span><span class='s'>"https://swapi.dev/api/people/"</span>, <span class='m'>1</span><span class='o'>:</span><span class='m'>10</span><span class='o'>)</span></span>
<span><span class='nv'>reqs</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://rdrr.io/r/base/lapply.html'>lapply</a></span><span class='o'>(</span><span class='nv'>urls</span>, <span class='nv'>request</span><span class='o'>)</span></span></code></pre>
</div>
<p>Now I can perform those requests, collecting a list of responses:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>resps</span> <span class='o'>&lt;-</span> <span class='nf'><a href='https://httr2.r-lib.org/reference/req_perform_sequential.html'>req_perform_sequential</a></span><span class='o'>(</span><span class='nv'>reqs</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; Iterating <span style='color: #00BB00;'>■■■■                            </span>  10% | ETA: 40s</span></span>
<span></span><span><span class='c'>#&gt; Iterating <span style='color: #00BB00;'>■■■■■■■                         </span>  20% | ETA:  3m</span></span>
<span></span><span><span class='c'>#&gt; Iterating <span style='color: #00BB00;'>■■■■■■■■■■                      </span>  30% | ETA:  2m</span></span>
<span></span><span><span class='c'>#&gt; Iterating <span style='color: #00BB00;'>■■■■■■■■■■■■■                   </span>  40% | ETA:  1m</span></span>
<span></span><span><span class='c'>#&gt; Iterating <span style='color: #00BB00;'>■■■■■■■■■■■■■■■■                </span>  50% | ETA: 46s</span></span>
<span></span><span><span class='c'>#&gt; Iterating <span style='color: #00BB00;'>■■■■■■■■■■■■■■■■■■■             </span>  60% | ETA: 33s</span></span>
<span></span><span><span class='c'>#&gt; Iterating <span style='color: #00BB00;'>■■■■■■■■■■■■■■■■■■■■■■          </span>  70% | ETA: 22s</span></span>
<span></span><span><span class='c'>#&gt; Iterating <span style='color: #00BB00;'>■■■■■■■■■■■■■■■■■■■■■■■■■       </span>  80% | ETA: 13s</span></span>
<span></span><span><span class='c'>#&gt; Iterating <span style='color: #00BB00;'>■■■■■■■■■■■■■■■■■■■■■■■■■■■■    </span>  90% | ETA:  6s</span></span>
<span></span><span><span class='c'>#&gt; Iterating <span style='color: #00BB00;'>■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ </span> 100% | ETA:  0s</span></span>
<span></span></code></pre>
</div>
<p>These responses contain their data in a JSON body:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>resps</span> <span class='o'>|&gt;</span> </span>
<span>  <span class='nv'>_</span><span class='o'>[[</span><span class='m'>1</span><span class='o'>]</span><span class='o'>]</span> <span class='o'>|&gt;</span> </span>
<span>  <span class='nf'><a href='https://httr2.r-lib.org/reference/resp_body_raw.html'>resp_body_json</a></span><span class='o'>(</span><span class='o'>)</span> <span class='o'>|&gt;</span> </span>
<span>  <span class='nf'><a href='https://rdrr.io/r/utils/str.html'>str</a></span><span class='o'>(</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; List of 16</span></span>
<span><span class='c'>#&gt;  $ name      : chr "Luke Skywalker"</span></span>
<span><span class='c'>#&gt;  $ height    : chr "172"</span></span>
<span><span class='c'>#&gt;  $ mass      : chr "77"</span></span>
<span><span class='c'>#&gt;  $ hair_color: chr "blond"</span></span>
<span><span class='c'>#&gt;  $ skin_color: chr "fair"</span></span>
<span><span class='c'>#&gt;  $ eye_color : chr "blue"</span></span>
<span><span class='c'>#&gt;  $ birth_year: chr "19BBY"</span></span>
<span><span class='c'>#&gt;  $ gender    : chr "male"</span></span>
<span><span class='c'>#&gt;  $ homeworld : chr "https://swapi.dev/api/planets/1/"</span></span>
<span><span class='c'>#&gt;  $ films     :List of 4</span></span>
<span><span class='c'>#&gt;   ..$ : chr "https://swapi.dev/api/films/1/"</span></span>
<span><span class='c'>#&gt;   ..$ : chr "https://swapi.dev/api/films/2/"</span></span>
<span><span class='c'>#&gt;   ..$ : chr "https://swapi.dev/api/films/3/"</span></span>
<span><span class='c'>#&gt;   ..$ : chr "https://swapi.dev/api/films/6/"</span></span>
<span><span class='c'>#&gt;  $ species   : list()</span></span>
<span><span class='c'>#&gt;  $ vehicles  :List of 2</span></span>
<span><span class='c'>#&gt;   ..$ : chr "https://swapi.dev/api/vehicles/14/"</span></span>
<span><span class='c'>#&gt;   ..$ : chr "https://swapi.dev/api/vehicles/30/"</span></span>
<span><span class='c'>#&gt;  $ starships :List of 2</span></span>
<span><span class='c'>#&gt;   ..$ : chr "https://swapi.dev/api/starships/12/"</span></span>
<span><span class='c'>#&gt;   ..$ : chr "https://swapi.dev/api/starships/22/"</span></span>
<span><span class='c'>#&gt;  $ created   : chr "2014-12-09T13:50:51.644000Z"</span></span>
<span><span class='c'>#&gt;  $ edited    : chr "2014-12-20T21:17:56.891000Z"</span></span>
<span><span class='c'>#&gt;  $ url       : chr "https://swapi.dev/api/people/1/"</span></span>
<span></span></code></pre>
</div>
<p>There&rsquo;s lots of ways to deal with this sort of data (e.g. for loops or functional programming) but to make life easier, httr2 comes with its own helper, <a href="https://httr2.r-lib.org/reference/resps_successes.html" target="_blank" rel="noopener"><code>resps_data()</code></a>
. This function takes a callback that retrieves the data for each response, then concatenates all the data into a single object. In this case, we need to wrap <a href="https://httr2.r-lib.org/reference/resp_body_raw.html" target="_blank" rel="noopener"><code>resp_body_json()</code></a>
 in a list, so we get one list for each person, rather than one list in total:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>resps</span> <span class='o'>|&gt;</span> </span>
<span>  <span class='nf'><a href='https://httr2.r-lib.org/reference/resps_successes.html'>resps_data</a></span><span class='o'>(</span>\<span class='o'>(</span><span class='nv'>resp</span><span class='o'>)</span> <span class='nf'><a href='https://rdrr.io/r/base/list.html'>list</a></span><span class='o'>(</span><span class='nf'><a href='https://httr2.r-lib.org/reference/resp_body_raw.html'>resp_body_json</a></span><span class='o'>(</span><span class='nv'>resp</span><span class='o'>)</span><span class='o'>)</span><span class='o'>)</span> <span class='o'>|&gt;</span> </span>
<span>  <span class='nv'>_</span><span class='o'>[</span><span class='m'>1</span><span class='o'>:</span><span class='m'>3</span><span class='o'>]</span> <span class='o'>|&gt;</span> </span>
<span>  <span class='nf'><a href='https://rdrr.io/r/utils/str.html'>str</a></span><span class='o'>(</span>list.len <span class='o'>=</span> <span class='m'>10</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; List of 3</span></span>
<span><span class='c'>#&gt;  $ :List of 16</span></span>
<span><span class='c'>#&gt;   ..$ name      : chr "Luke Skywalker"</span></span>
<span><span class='c'>#&gt;   ..$ height    : chr "172"</span></span>
<span><span class='c'>#&gt;   ..$ mass      : chr "77"</span></span>
<span><span class='c'>#&gt;   ..$ hair_color: chr "blond"</span></span>
<span><span class='c'>#&gt;   ..$ skin_color: chr "fair"</span></span>
<span><span class='c'>#&gt;   ..$ eye_color : chr "blue"</span></span>
<span><span class='c'>#&gt;   ..$ birth_year: chr "19BBY"</span></span>
<span><span class='c'>#&gt;   ..$ gender    : chr "male"</span></span>
<span><span class='c'>#&gt;   ..$ homeworld : chr "https://swapi.dev/api/planets/1/"</span></span>
<span><span class='c'>#&gt;   ..$ films     :List of 4</span></span>
<span><span class='c'>#&gt;   .. ..$ : chr "https://swapi.dev/api/films/1/"</span></span>
<span><span class='c'>#&gt;   .. ..$ : chr "https://swapi.dev/api/films/2/"</span></span>
<span><span class='c'>#&gt;   .. ..$ : chr "https://swapi.dev/api/films/3/"</span></span>
<span><span class='c'>#&gt;   .. ..$ : chr "https://swapi.dev/api/films/6/"</span></span>
<span><span class='c'>#&gt;   .. [list output truncated]</span></span>
<span><span class='c'>#&gt;  $ :List of 16</span></span>
<span><span class='c'>#&gt;   ..$ name      : chr "C-3PO"</span></span>
<span><span class='c'>#&gt;   ..$ height    : chr "167"</span></span>
<span><span class='c'>#&gt;   ..$ mass      : chr "75"</span></span>
<span><span class='c'>#&gt;   ..$ hair_color: chr "n/a"</span></span>
<span><span class='c'>#&gt;   ..$ skin_color: chr "gold"</span></span>
<span><span class='c'>#&gt;   ..$ eye_color : chr "yellow"</span></span>
<span><span class='c'>#&gt;   ..$ birth_year: chr "112BBY"</span></span>
<span><span class='c'>#&gt;   ..$ gender    : chr "n/a"</span></span>
<span><span class='c'>#&gt;   ..$ homeworld : chr "https://swapi.dev/api/planets/1/"</span></span>
<span><span class='c'>#&gt;   ..$ films     :List of 6</span></span>
<span><span class='c'>#&gt;   .. ..$ : chr "https://swapi.dev/api/films/1/"</span></span>
<span><span class='c'>#&gt;   .. ..$ : chr "https://swapi.dev/api/films/2/"</span></span>
<span><span class='c'>#&gt;   .. ..$ : chr "https://swapi.dev/api/films/3/"</span></span>
<span><span class='c'>#&gt;   .. ..$ : chr "https://swapi.dev/api/films/4/"</span></span>
<span><span class='c'>#&gt;   .. ..$ : chr "https://swapi.dev/api/films/5/"</span></span>
<span><span class='c'>#&gt;   .. ..$ : chr "https://swapi.dev/api/films/6/"</span></span>
<span><span class='c'>#&gt;   .. [list output truncated]</span></span>
<span><span class='c'>#&gt;  $ :List of 16</span></span>
<span><span class='c'>#&gt;   ..$ name      : chr "R2-D2"</span></span>
<span><span class='c'>#&gt;   ..$ height    : chr "96"</span></span>
<span><span class='c'>#&gt;   ..$ mass      : chr "32"</span></span>
<span><span class='c'>#&gt;   ..$ hair_color: chr "n/a"</span></span>
<span><span class='c'>#&gt;   ..$ skin_color: chr "white, blue"</span></span>
<span><span class='c'>#&gt;   ..$ eye_color : chr "red"</span></span>
<span><span class='c'>#&gt;   ..$ birth_year: chr "33BBY"</span></span>
<span><span class='c'>#&gt;   ..$ gender    : chr "n/a"</span></span>
<span><span class='c'>#&gt;   ..$ homeworld : chr "https://swapi.dev/api/planets/8/"</span></span>
<span><span class='c'>#&gt;   ..$ films     :List of 6</span></span>
<span><span class='c'>#&gt;   .. ..$ : chr "https://swapi.dev/api/films/1/"</span></span>
<span><span class='c'>#&gt;   .. ..$ : chr "https://swapi.dev/api/films/2/"</span></span>
<span><span class='c'>#&gt;   .. ..$ : chr "https://swapi.dev/api/films/3/"</span></span>
<span><span class='c'>#&gt;   .. ..$ : chr "https://swapi.dev/api/films/4/"</span></span>
<span><span class='c'>#&gt;   .. ..$ : chr "https://swapi.dev/api/films/5/"</span></span>
<span><span class='c'>#&gt;   .. ..$ : chr "https://swapi.dev/api/films/6/"</span></span>
<span><span class='c'>#&gt;   .. [list output truncated]</span></span>
<span></span></code></pre>
</div>
<p>Another option would be to convert each response into a data frame or tibble. That&rsquo;s a little tricky here because of the nested lists that will need to become list-columns<sup id="fnref:4"><a href="#fn:4" class="footnote-ref" role="doc-noteref">4</a></sup>, so we&rsquo;ll avoid that challenge here by focussing on the first nine columns:</p>
<div class="highlight">
<pre class='chroma'><code class='language-r' data-lang='r'><span><span class='nv'>sw_data</span> <span class='o'>&lt;-</span> <span class='kr'>function</span><span class='o'>(</span><span class='nv'>resp</span><span class='o'>)</span> <span class='o'>&#123;</span></span>
<span>  <span class='nf'>tibble</span><span class='nf'>::</span><span class='nf'><a href='https://tibble.tidyverse.org/reference/as_tibble.html'>as_tibble</a></span><span class='o'>(</span><span class='nf'><a href='https://httr2.r-lib.org/reference/resp_body_raw.html'>resp_body_json</a></span><span class='o'>(</span><span class='nv'>resp</span><span class='o'>)</span><span class='o'>[</span><span class='m'>1</span><span class='o'>:</span><span class='m'>9</span><span class='o'>]</span><span class='o'>)</span></span>
<span><span class='o'>&#125;</span></span>
<span><span class='nv'>resps</span> <span class='o'>|&gt;</span> <span class='nf'><a href='https://httr2.r-lib.org/reference/resps_successes.html'>resps_data</a></span><span class='o'>(</span><span class='nv'>sw_data</span><span class='o'>)</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># A tibble: 10 × 9</span></span></span>
<span><span class='c'>#&gt;    <span style='font-weight: bold;'>name</span>           <span style='font-weight: bold;'>height</span> <span style='font-weight: bold;'>mass</span>  <span style='font-weight: bold;'>hair_color</span> <span style='font-weight: bold;'>skin_color</span> <span style='font-weight: bold;'>eye_color</span> <span style='font-weight: bold;'>birth_year</span> <span style='font-weight: bold;'>gender</span></span></span>
<span><span class='c'>#&gt;    <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>          <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>  <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span> <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>      <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>      <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>     <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span>      <span style='color: #555555; font-style: italic;'>&lt;chr&gt;</span> </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 1</span> Luke Skywalker 172    77    blond      fair       blue      19BBY      male  </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 2</span> C-3PO          167    75    n/a        gold       yellow    112BBY     n/a   </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 3</span> R2-D2          96     32    n/a        white, bl… red       33BBY      n/a   </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 4</span> Darth Vader    202    136   none       white      yellow    41.9BBY    male  </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 5</span> Leia Organa    150    49    brown      light      brown     19BBY      female</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 6</span> Owen Lars      178    120   brown, gr… light      blue      52BBY      male  </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 7</span> Beru Whitesun… 165    75    brown      light      blue      47BBY      female</span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 8</span> R5-D4          97     32    n/a        white, red red       unknown    n/a   </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'> 9</span> Biggs Darklig… 183    84    black      light      brown     24BBY      male  </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'>10</span> Obi-Wan Kenobi 182    77    auburn, w… fair       blue-gray 57BBY      male  </span></span>
<span><span class='c'>#&gt; <span style='color: #555555;'># ℹ 1 more variable: </span><span style='color: #555555; font-weight: bold;'>homeworld</span><span style='color: #555555;'> &lt;chr&gt;</span></span></span>
<span></span></code></pre>
</div>
<p>When you&rsquo;re performing large numbers of requests, it&rsquo;s almost inevitable that something will go wrong. By default, all three functions will bubble up errors, causing you to lose all of the work that&rsquo;s been done so far. You can, however, use the <code>on_error</code> argument to change what happens, either ignoring errors, or returning when you hit the first error. This will changes the return value: instead of a list of responses, the list might now also contain error objects. httr2 provides other helpers to work with this object:</p>
<ul>
<li><a href="https://httr2.r-lib.org/reference/resps_successes.html" target="_blank" rel="noopener"><code>resps_successes()</code></a>
 filters the list to find the successful responses. You&rsquo;ll can then pair this with <a href="https://httr2.r-lib.org/reference/resps_successes.html" target="_blank" rel="noopener"><code>resps_data()</code></a>
 to get the data from the successful request.</li>
<li><a href="https://httr2.r-lib.org/reference/resps_successes.html" target="_blank" rel="noopener"><code>resps_failures()</code></a>
 filters the list to find the failed responses. You&rsquo;ll can then pair this with <a href="https://httr2.r-lib.org/reference/resps_successes.html" target="_blank" rel="noopener"><code>resps_requests()</code></a>
 to find the requests that generated them and figure out what went wrong,.</li>
</ul>
<h2 id="acknowledgements">Acknowledgements
</h2>
<p>A big thanks to all 87 folks who have helped make httr2 possible!</p>
<p><a href="https://github.com/allenbaron" target="_blank" rel="noopener">@allenbaron</a>
, <a href="https://github.com/asadow" target="_blank" rel="noopener">@asadow</a>
, <a href="https://github.com/atheriel" target="_blank" rel="noopener">@atheriel</a>
, <a href="https://github.com/boshek" target="_blank" rel="noopener">@boshek</a>
, <a href="https://github.com/casa-henrym" target="_blank" rel="noopener">@casa-henrym</a>
, <a href="https://github.com/cderv" target="_blank" rel="noopener">@cderv</a>
, <a href="https://github.com/colmanhumphrey" target="_blank" rel="noopener">@colmanhumphrey</a>
, <a href="https://github.com/cstjohn810" target="_blank" rel="noopener">@cstjohn810</a>
, <a href="https://github.com/cwang23" target="_blank" rel="noopener">@cwang23</a>
, <a href="https://github.com/DavidRLovell" target="_blank" rel="noopener">@DavidRLovell</a>
, <a href="https://github.com/DMerch" target="_blank" rel="noopener">@DMerch</a>
, <a href="https://github.com/dpprdan" target="_blank" rel="noopener">@dpprdan</a>
, <a href="https://github.com/ECOSchulz" target="_blank" rel="noopener">@ECOSchulz</a>
, <a href="https://github.com/edavidaja" target="_blank" rel="noopener">@edavidaja</a>
, <a href="https://github.com/elipousson" target="_blank" rel="noopener">@elipousson</a>
, <a href="https://github.com/emmansh" target="_blank" rel="noopener">@emmansh</a>
, <a href="https://github.com/Enchufa2" target="_blank" rel="noopener">@Enchufa2</a>
, <a href="https://github.com/ErdaradunGaztea" target="_blank" rel="noopener">@ErdaradunGaztea</a>
, <a href="https://github.com/fangzhou-xie" target="_blank" rel="noopener">@fangzhou-xie</a>
, <a href="https://github.com/fh-mthomson" target="_blank" rel="noopener">@fh-mthomson</a>
, <a href="https://github.com/fkohrt" target="_blank" rel="noopener">@fkohrt</a>
, <a href="https://github.com/flahn" target="_blank" rel="noopener">@flahn</a>
, <a href="https://github.com/gregleleu" target="_blank" rel="noopener">@gregleleu</a>
, <a href="https://github.com/guga31bb" target="_blank" rel="noopener">@guga31bb</a>
, <a href="https://github.com/gvelasq" target="_blank" rel="noopener">@gvelasq</a>
, <a href="https://github.com/hadley" target="_blank" rel="noopener">@hadley</a>
, <a href="https://github.com/hongooi73" target="_blank" rel="noopener">@hongooi73</a>
, <a href="https://github.com/howardbaek" target="_blank" rel="noopener">@howardbaek</a>
, <a href="https://github.com/jameslairdsmith" target="_blank" rel="noopener">@jameslairdsmith</a>
, <a href="https://github.com/JBGruber" target="_blank" rel="noopener">@JBGruber</a>
, <a href="https://github.com/jchrom" target="_blank" rel="noopener">@jchrom</a>
, <a href="https://github.com/jemus42" target="_blank" rel="noopener">@jemus42</a>
, <a href="https://github.com/jennybc" target="_blank" rel="noopener">@jennybc</a>
, <a href="https://github.com/jimrothstein" target="_blank" rel="noopener">@jimrothstein</a>
, <a href="https://github.com/jjesusfilho" target="_blank" rel="noopener">@jjesusfilho</a>
, <a href="https://github.com/jjfantini" target="_blank" rel="noopener">@jjfantini</a>
, <a href="https://github.com/jl5000" target="_blank" rel="noopener">@jl5000</a>
, <a href="https://github.com/jonthegeek" target="_blank" rel="noopener">@jonthegeek</a>
, <a href="https://github.com/JosiahParry" target="_blank" rel="noopener">@JosiahParry</a>
, <a href="https://github.com/judith-bourque" target="_blank" rel="noopener">@judith-bourque</a>
, <a href="https://github.com/juliasilge" target="_blank" rel="noopener">@juliasilge</a>
, <a href="https://github.com/kasperwelbers" target="_blank" rel="noopener">@kasperwelbers</a>
, <a href="https://github.com/kelvindso" target="_blank" rel="noopener">@kelvindso</a>
, <a href="https://github.com/kieran-mace" target="_blank" rel="noopener">@kieran-mace</a>
, <a href="https://github.com/KoderKow" target="_blank" rel="noopener">@KoderKow</a>
, <a href="https://github.com/lassehjorthmadsen" target="_blank" rel="noopener">@lassehjorthmadsen</a>
, <a href="https://github.com/llrs" target="_blank" rel="noopener">@llrs</a>
, <a href="https://github.com/lyndon-bird" target="_blank" rel="noopener">@lyndon-bird</a>
, <a href="https://github.com/m-mohr" target="_blank" rel="noopener">@m-mohr</a>
, <a href="https://github.com/maelle" target="_blank" rel="noopener">@maelle</a>
, <a href="https://github.com/maxheld83" target="_blank" rel="noopener">@maxheld83</a>
, <a href="https://github.com/mgirlich" target="_blank" rel="noopener">@mgirlich</a>
, <a href="https://github.com/MichaelChirico" target="_blank" rel="noopener">@MichaelChirico</a>
, <a href="https://github.com/michaelgfalk" target="_blank" rel="noopener">@michaelgfalk</a>
, <a href="https://github.com/misea" target="_blank" rel="noopener">@misea</a>
, <a href="https://github.com/MislavSag" target="_blank" rel="noopener">@MislavSag</a>
, <a href="https://github.com/mkoohafkan" target="_blank" rel="noopener">@mkoohafkan</a>
, <a href="https://github.com/mmuurr" target="_blank" rel="noopener">@mmuurr</a>
, <a href="https://github.com/multimeric" target="_blank" rel="noopener">@multimeric</a>
, <a href="https://github.com/nbenn" target="_blank" rel="noopener">@nbenn</a>
, <a href="https://github.com/nclsbarreto" target="_blank" rel="noopener">@nclsbarreto</a>
, <a href="https://github.com/nealrichardson" target="_blank" rel="noopener">@nealrichardson</a>
, <a href="https://github.com/Nelson-Gon" target="_blank" rel="noopener">@Nelson-Gon</a>
, <a href="https://github.com/olivroy" target="_blank" rel="noopener">@olivroy</a>
, <a href="https://github.com/owenjonesuob" target="_blank" rel="noopener">@owenjonesuob</a>
, <a href="https://github.com/paul-carteron" target="_blank" rel="noopener">@paul-carteron</a>
, <a href="https://github.com/pbulsink" target="_blank" rel="noopener">@pbulsink</a>
, <a href="https://github.com/ramiromagno" target="_blank" rel="noopener">@ramiromagno</a>
, <a href="https://github.com/rplati" target="_blank" rel="noopener">@rplati</a>
, <a href="https://github.com/rressler" target="_blank" rel="noopener">@rressler</a>
, <a href="https://github.com/samterfa" target="_blank" rel="noopener">@samterfa</a>
, <a href="https://github.com/schnee" target="_blank" rel="noopener">@schnee</a>
, <a href="https://github.com/sckott" target="_blank" rel="noopener">@sckott</a>
, <a href="https://github.com/sebastian-c" target="_blank" rel="noopener">@sebastian-c</a>
, <a href="https://github.com/selesnow" target="_blank" rel="noopener">@selesnow</a>
, <a href="https://github.com/Shaunson26" target="_blank" rel="noopener">@Shaunson26</a>
, <a href="https://github.com/SokolovAnatoliy" target="_blank" rel="noopener">@SokolovAnatoliy</a>
, <a href="https://github.com/spotrh" target="_blank" rel="noopener">@spotrh</a>
, <a href="https://github.com/stefanedwards" target="_blank" rel="noopener">@stefanedwards</a>
, <a href="https://github.com/taerwin" target="_blank" rel="noopener">@taerwin</a>
, <a href="https://github.com/vanhry" target="_blank" rel="noopener">@vanhry</a>
, <a href="https://github.com/wing328" target="_blank" rel="noopener">@wing328</a>
, <a href="https://github.com/xinzhuohkust" target="_blank" rel="noopener">@xinzhuohkust</a>
, <a href="https://github.com/yogat3ch" target="_blank" rel="noopener">@yogat3ch</a>
, <a href="https://github.com/yogesh-bansal" target="_blank" rel="noopener">@yogesh-bansal</a>
, <a href="https://github.com/yutannihilation" target="_blank" rel="noopener">@yutannihilation</a>
, and <a href="https://github.com/zacdav-db" target="_blank" rel="noopener">@zacdav-db</a>
.</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>Pronounced &ldquo;hitter 2&rdquo;.&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:2">
<p>Well, technically, it does send the request, just to another test server that returns the request that it received.&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:3">
<p>This is only an approximation. For example, it only shows the final response if there were redirects, and it automatically uncompresses the body if it was compressed. Nevertheless, it&rsquo;s still pretty useful.&#160;<a href="#fnref:3" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:4">
<p>To turn these into list-columns, you need to wrap each list in another list, something like <code>is_list &lt;- map_lgl(json, is.list); json[is_list] &lt;- map(json[is_list], list)</code>. This ensures that each element has length 1, the invariant for a row in a tibble.&#160;<a href="#fnref:4" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></description>
      <enclosure url="https://posit-open-source.netlify.app/blog/tidyverse/2023/httr2-1-0-0/thumbnail-wd.jpg" length="369135" type="image/jpeg" />
    </item>
  </channel>
</rss>
