Repository: aquasecurity/starboard
Pull request #399 (2021-02-16 20:57:17)

refactor: kubebench.ReadWriter to use controller-runtime Client
Signed-off-by: Daniel Pacak <pacak.daniel@gmail.com>

codecov[bot]: # [Codecov](https://codecov.io/gh/aquasecurity/starboard/pull/399?src=pr&el=h1) Report
> Merging [#399](https://codecov.io/gh/aquasecurity/starboard/pull/399?src=pr&el=desc) (8f91f69) into [main](https://codecov.io/gh/aquasecurity/starboard/commit/2954b44cb420597f5d288eb0b6cc5cca75890b6c?el=desc) (2954b44) will **decrease** coverage by `38.30%`.
> The diff coverage is `34.61%`.

[![Impacted file tree graph](https://codecov.io/gh/aquasecurity/starboard/pull/399/graphs/tree.svg?width=650&height=150&src=pr&token=qqTGKAJ0Wb)](https://codecov.io/gh/aquasecurity/starboard/pull/399?src=pr&el=tree)

```diff
@@             Coverage Diff             @@
##             main     #399       +/-   ##
===========================================
- Coverage   68.35%   30.05%   -38.31%     
===========================================
  Files          59       58        -1     
  Lines        3100     3018       -82     
===========================================
- Hits         2119      907     -1212     
- Misses        721     2048     +1327     
+ Partials      260       63      -197     
```


| [Impacted Files](https://codecov.io/gh/aquasecurity/starboard/pull/399?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [pkg/cmd/scan\_ciskubebench.go](https://codecov.io/gh/aquasecurity/starboard/pull/399/diff?src=pr&el=tree#diff-cGtnL2NtZC9zY2FuX2Npc2t1YmViZW5jaC5nbw==) | `0.00% <0.00%> (-54.35%)` | :arrow_down: |
| [pkg/kubebench/scanner.go](https://codecov.io/gh/aquasecurity/starboard/pull/399/diff?src=pr&el=tree#diff-cGtnL2t1YmViZW5jaC9zY2FubmVyLmdv) | `0.00% <0.00%> (-93.26%)` | :arrow_down: |
| [pkg/kubebench/io.go](https://codecov.io/gh/aquasecurity/starboard/pull/399/diff?src=pr&el=tree#diff-cGtnL2t1YmViZW5jaC9pby5nbw==) | `85.71% <85.71%> (ø)` | |
| [pkg/cmd/get.go](https://codecov.io/gh/aquasecurity/starboard/pull/399/diff?src=pr&el=tree#diff-cGtnL2NtZC9nZXQuZ28=) | `0.00% <0.00%> (-100.00%)` | :arrow_down: |
| [pkg/cmd/find.go](https://codecov.io/gh/aquasecurity/starboard/pull/399/diff?src=pr&el=tree#diff-cGtnL2NtZC9maW5kLmdv) | `0.00% <0.00%> (-100.00%)` | :arrow_down: |
| [pkg/cmd/root.go](https://codecov.io/gh/aquasecurity/starboard/pull/399/diff?src=pr&el=tree#diff-cGtnL2NtZC9yb290Lmdv) | `0.00% <0.00%> (-100.00%)` | :arrow_down: |
| [pkg/cmd/scan.go](https://codecov.io/gh/aquasecurity/starboard/pull/399/diff?src=pr&el=tree#diff-cGtnL2NtZC9zY2FuLmdv) | `0.00% <0.00%> (-100.00%)` | :arrow_down: |
| [pkg/cmd/polaris.go](https://codecov.io/gh/aquasecurity/starboard/pull/399/diff?src=pr&el=tree#diff-cGtnL2NtZC9wb2xhcmlzLmdv) | `0.00% <0.00%> (-100.00%)` | :arrow_down: |
| [pkg/cmd/version.go](https://codecov.io/gh/aquasecurity/starboard/pull/399/diff?src=pr&el=tree#diff-cGtnL2NtZC92ZXJzaW9uLmdv) | `0.00% <0.00%> (-100.00%)` | :arrow_down: |
| [pkg/cmd/kube\_bench.go](https://codecov.io/gh/aquasecurity/starboard/pull/399/diff?src=pr&el=tree#diff-cGtnL2NtZC9rdWJlX2JlbmNoLmdv) | `0.00% <0.00%> (-100.00%)` | :arrow_down: |
| ... and [36 more](https://codecov.io/gh/aquasecurity/starboard/pull/399/diff?src=pr&el=tree-more) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/aquasecurity/starboard/pull/399?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/aquasecurity/starboard/pull/399?src=pr&el=footer). Last update [2954b44...8f91f69](https://codecov.io/gh/aquasecurity/starboard/pull/399?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/pkg/cmd/scan_ciskubebench.go b/pkg/cmd/scan_ciskubebench.go
index 545bf4f..afd3e84 100644
--- a/pkg/cmd/scan_ciskubebench.go
+++ b/pkg/cmd/scan_ciskubebench.go
@@ -5,7 +5,6 @@ import (
 	"fmt"
 	"sync"
 
-	"github.com/aquasecurity/starboard/pkg/generated/clientset/versioned"
 	"github.com/aquasecurity/starboard/pkg/kubebench"
 	"github.com/aquasecurity/starboard/pkg/starboard"
 	"github.com/spf13/cobra"
@@ -14,6 +13,7 @@ import (
 	"k8s.io/cli-runtime/pkg/genericclioptions"
 	"k8s.io/client-go/kubernetes"
 	"k8s.io/klog"
+	"sigs.k8s.io/controller-runtime/pkg/client"
 )
 
 const (
@@ -35,11 +35,11 @@ func NewScanKubeBenchReportsCmd(cf *genericclioptions.ConfigFlags) *cobra.Comman
 func ScanKubeBenchReports(cf *genericclioptions.ConfigFlags) func(cmd *cobra.Command, args []string) error {
 	return func(cmd *cobra.Command, args []string) error {
 		ctx := context.Background()
-		kubernetesConfig, err := cf.ToRESTConfig()
+		kubeConfig, err := cf.ToRESTConfig()
 		if err != nil {
 			return err
 		}
-		kubernetesClientset, err := kubernetes.NewForConfig(kubernetesConfig)
+		kubeClientset, err := kubernetes.NewForConfig(kubeConfig)
 		if err != nil {
 			return err
 		}
@@ -47,23 +47,28 @@ func ScanKubeBenchReports(cf *genericclioptions.ConfigFlags) func(cmd *cobra.Com
 		if err != nil {
 			return err
 		}
-		starboardClientset, err := versioned.NewForConfig(kubernetesConfig)
-		if err != nil {
-			return err
-		}
-		nodeList, err := kubernetesClientset.CoreV1().Nodes().List(ctx, metav1.ListOptions{})
+		nodeList, err := kubeClientset.CoreV1().Nodes().List(ctx, metav1.ListOptions{})
 		if err != nil {
 			return fmt.Errorf("listing nodes: %w", err)
 		}
-		config, err := starboard.NewConfigManager(kubernetesClientset, starboard.NamespaceName).Read(ctx)
+		config, err := starboard.NewConfigManager(kubeClientset, starboard.NamespaceName).Read(ctx)
 		if err != nil {
 			return err
 		}
 
 		scheme := starboard.NewScheme()
-		scanner := kubebench.NewScanner(scheme, kubernetesClientset, config, opts)
-		writer := kubebench.NewReadWriter(scheme, starboardClientset)
+		scanner := kubebench.NewScanner(scheme, kubeClientset, config, opts)
+
+		kubeClient, err := client.New(kubeConfig, client.Options{
+			Scheme: scheme,
+		})
+		if err != nil {
+			return err
+		}
+
+		writer := kubebench.NewReadWriter(kubeClient)
 
+		// TODO Move this logic to scanner.ScanAll() method. We should not mix discovery / scanning logic with the CLI.
 		var wg sync.WaitGroup
 
 		for _, node := range nodeList.Items {
@@ -84,7 +89,7 @@ func ScanKubeBenchReports(cf *genericclioptions.ConfigFlags) func(cmd *cobra.Com
 					klog.Errorf("Error while running kube-bench on node: %s: %v", node.Name, err)
 					return
 				}
-				err = writer.Write(ctx, report, &node)
+				err = writer.Write(ctx, report)
 				if err != nil {
 					klog.Errorf("Error while writing kube-bench report for node: %s: %v", node.Name, err)
 					return
diff --git a/pkg/kubebench/io.go b/pkg/kubebench/io.go
new file mode 100644
index 0000000..e32dd86
--- /dev/null
+++ b/pkg/kubebench/io.go
@@ -0,0 +1,67 @@
+package kubebench
+
+import (
+	"context"
+
+	"github.com/aquasecurity/starboard/pkg/apis/aquasecurity/v1alpha1"
+	"github.com/aquasecurity/starboard/pkg/kube"
+	"k8s.io/apimachinery/pkg/api/errors"
+	"k8s.io/apimachinery/pkg/types"
+	"sigs.k8s.io/controller-runtime/pkg/client"
+)
+
+type Writer interface {
+	Write(ctx context.Context, report v1alpha1.CISKubeBenchReport) error
+}
+
+type Reader interface {
+	FindByOwner(ctx context.Context, node kube.Object) (*v1alpha1.CISKubeBenchReport, error)
+}
+
+type ReadWriter interface {
+	Writer
+	Reader
+}
+
+type rw struct {
+	client client.Client
+}
+
+func NewReadWriter(client client.Client) ReadWriter {
+	return &rw{
+		client: client,
+	}
+}
+
+func (w *rw) Write(ctx context.Context, report v1alpha1.CISKubeBenchReport) error {
+	// TODO Try CreateOrUpdate method
+	var existing v1alpha1.CISKubeBenchReport
+	err := w.client.Get(ctx, types.NamespacedName{
+		Name: report.Name,
+	}, &existing)
+
+	if err == nil {
+		copied := existing.DeepCopy()
+		copied.Labels = report.Labels
+		copied.Report = report.Report
+
+		return w.client.Update(ctx, copied)
+	}
+
+	if errors.IsNotFound(err) {
+		return w.client.Create(ctx, &report)
+	}
+
+	return err
+}
+
+func (w *rw) FindByOwner(ctx context.Context, node kube.Object) (*v1alpha1.CISKubeBenchReport, error) {
+	report := &v1alpha1.CISKubeBenchReport{}
+	err := w.client.Get(ctx, types.NamespacedName{
+		Name: node.Name,
+	}, report)
+	if err != nil {
+		return nil, err
+	}
+	return report, nil
+}
diff --git a/pkg/kubebench/scanner.go b/pkg/kubebench/scanner.go
index 3a0286d..9de182b 100644
--- a/pkg/kubebench/scanner.go
+++ b/pkg/kubebench/scanner.go
@@ -20,6 +20,7 @@ import (
 	"k8s.io/client-go/kubernetes"
 	"k8s.io/klog"
 	"k8s.io/utils/pointer"
+	"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
 )
 
 const (
@@ -60,17 +61,17 @@ func NewScanner(
 	}
 }
 
-func (s *Scanner) Scan(ctx context.Context, node corev1.Node) (v1alpha1.CISKubeBenchOutput, error) {
+func (s *Scanner) Scan(ctx context.Context, node corev1.Node) (v1alpha1.CISKubeBenchReport, error) {
 	// 1. Prepare descriptor for the Kubernetes Job which will run kube-bench
 	job, err := s.prepareKubeBenchJob(node)
 	if err != nil {
-		return v1alpha1.CISKubeBenchOutput{}, err
+		return v1alpha1.CISKubeBenchReport{}, err
 	}
 
 	// 2. Run the prepared Job and wait for its completion or failure
 	err = runner.New().Run(ctx, kube.NewRunnableJob(s.scheme, s.clientset, job))
 	if err != nil {
-		return v1alpha1.CISKubeBenchOutput{}, fmt.Errorf("running kube-bench job: %w", err)
+		return v1alpha1.CISKubeBenchReport{}, fmt.Errorf("running kube-bench job: %w", err)
 	}
 
 	defer func() {
@@ -91,14 +92,35 @@ func (s *Scanner) Scan(ctx context.Context, node corev1.Node) (v1alpha1.CISKubeB
 		job.Namespace, job.Name)
 	logsStream, err := s.logsReader.GetLogsByJobAndContainerName(ctx, job, kubeBenchContainerName)
 	if err != nil {
-		return v1alpha1.CISKubeBenchOutput{}, fmt.Errorf("getting logs: %w", err)
+		return v1alpha1.CISKubeBenchReport{}, fmt.Errorf("getting logs: %w", err)
 	}
 	defer func() {
 		_ = logsStream.Close()
 	}()
 
 	// 4. Parse the CISBenchmarkReport from the logs Reader
-	return s.converter.Convert(logsStream)
+	output, err := s.converter.Convert(logsStream)
+	if err != nil {
+		return v1alpha1.CISKubeBenchReport{}, err
+	}
+
+	report := v1alpha1.CISKubeBenchReport{
+		ObjectMeta: metav1.ObjectMeta{
+			Name: node.Name,
+			Labels: map[string]string{
+				kube.LabelResourceKind: string(kube.KindNode),
+				kube.LabelResourceName: node.Name,
+			},
+		},
+		Report: output,
+	}
+
+	err = controllerutil.SetOwnerReference(&node, &report, s.scheme)
+	if err != nil {
+		return v1alpha1.CISKubeBenchReport{}, err
+	}
+
+	return report, nil
 }
 
 func (s *Scanner) prepareKubeBenchJob(node corev1.Node) (*batchv1.Job, error) {
diff --git a/pkg/kubebench/writer.go b/pkg/kubebench/writer.go
deleted file mode 100644
index 85fe65c..0000000
--- a/pkg/kubebench/writer.go
+++ /dev/null
@@ -1,79 +0,0 @@
-package kubebench
-
-import (
-	"context"
-
-	"github.com/aquasecurity/starboard/pkg/apis/aquasecurity/v1alpha1"
-	"github.com/aquasecurity/starboard/pkg/generated/clientset/versioned"
-	"github.com/aquasecurity/starboard/pkg/kube"
-	corev1 "k8s.io/api/core/v1"
-	"k8s.io/apimachinery/pkg/api/errors"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"k8s.io/apimachinery/pkg/runtime"
-	"k8s.io/klog"
-	"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
-)
-
-type Writer interface {
-	Write(ctx context.Context, report v1alpha1.CISKubeBenchOutput, node *corev1.Node) error
-}
-
-type Reader interface {
-	Read(ctx context.Context, node kube.Object) (v1alpha1.CISKubeBenchOutput, error)
-}
-
-type ReadWriter interface {
-	Writer
-	Reader
-}
-
-type rw struct {
-	scheme    *runtime.Scheme
-	clientset versioned.Interface
-}
-
-func NewReadWriter(scheme *runtime.Scheme, clientset versioned.Interface) ReadWriter {
-	return &rw{
-		scheme:    scheme,
-		clientset: clientset,
-	}
-}
-
-func (w *rw) Write(ctx context.Context, report v1alpha1.CISKubeBenchOutput, node *corev1.Node) error {
-	reportExisting, err := w.clientset.AquasecurityV1alpha1().CISKubeBenchReports().Get(ctx, node.Name, metav1.GetOptions{})
-	if err != nil && errors.IsNotFound(err) {
-		klog.V(3).Infof("Creating CISKubeBenchReport for %s node", node.Name)
-		report := &v1alpha1.CISKubeBenchReport{
-			ObjectMeta: metav1.ObjectMeta{
-				Name: node.Name,
-				Labels: map[string]string{
-					kube.LabelResourceKind: string(kube.KindNode),
-					kube.LabelResourceName: node.Name,
-				},
-			},
-			Report: report,
-		}
-		err = controllerutil.SetOwnerReference(node, report, w.scheme)
-		if err != nil {
-			return err
-		}
-		_, err = w.clientset.AquasecurityV1alpha1().CISKubeBenchReports().Create(ctx, report, metav1.CreateOptions{})
-		return err
-	}
-	if err != nil {
-		return err
-	}
-	klog.V(3).Infof("Updating existing CISKubeBenchReport for %s node", node.Name)
-	reportCopied := reportExisting.DeepCopy()
-	reportCopied.Report = report
-	_, err = w.clientset.AquasecurityV1alpha1().CISKubeBenchReports().Update(ctx, reportCopied, metav1.UpdateOptions{})
-	return err
-}
-
-func (w *rw) Read(ctx context.Context, node kube.Object) (v1alpha1.CISKubeBenchOutput, error) {
-	report, err := w.clientset.AquasecurityV1alpha1().CISKubeBenchReports().Get(ctx, node.Name, metav1.GetOptions{})
-	if err != nil {
-		return v1alpha1.CISKubeBenchOutput{}, err
-	}
-	return report.Report, nil
-}
diff --git a/pkg/report/templates/default.qtpl b/pkg/report/templates/default.qtpl
index be7ebc5..2b51f0e 100644
--- a/pkg/report/templates/default.qtpl
+++ b/pkg/report/templates/default.qtpl
@@ -188,32 +188,33 @@ func (p *ReportPage) GetMergedVulnsSummary() (v1alpha1.VulnerabilitySummary) {
                   {% else %}
 
                   <div class="row">
-                      <table class="table table-sm table-bordered">
-                          <thead>
-                              <tr>
-                                <th scope="col">ID</th>
-                                <th scope="col">Severity</th>
-                                <th scope="col">Resource</th>
-                                <th scope="col">Installed Version</th>
-                                <th scope="col">Fixed Version</th>
-                              </tr>
-                            </thead>
-                            <tbody>
-                  {% for _, v := range report.Vulnerabilities %}
-                    <tr>
-                      <td>{%s v.VulnerabilityID %}</td>
-                      <td>{%s string(v.Severity) %}</td>
-                      <td>{%s v.Resource %}</td>
-                      <td>{%s v.InstalledVersion %}</td>
-                      <td>{%s v.FixedVersion %}</td>
-                    </tr>	
-                  {% endfor %}
-                            </tbody>
-                      </table>
+                    <table class="table table-sm table-bordered">
+                      <thead>
+                        <tr>
+                          <th scope="col">ID</th>
+                          <th scope="col">Severity</th>
+                          <th scope="col">Resource</th>
+                          <th scope="col">Installed Version</th>
+                          <th scope="col">Fixed Version</th>
+                        </tr>
+                      </thead>
+                      <tbody>
+                        {% for _, v := range report.Vulnerabilities %}
+                        <tr>
+                          <td>
+                            <a target="_blank" href="{%s v.PrimaryLink %}">{%s v.VulnerabilityID %}</a>
+                          </td>
+                          <td>{%s string(v.Severity) %}</td>
+                          <td>{%s v.Resource %}</td>
+                          <td>{%s v.InstalledVersion %}</td>
+                          <td>{%s v.FixedVersion %}</td>
+                        </tr>
+                        {% endfor %}
+                      </tbody>
+                    </table>
                   </div>
                 {% endif %}
                 {% endfor %}
-                
 
                 <!-- Config Audits -->
                 {% if p.ConfigAuditReport != nil && len(p.ConfigAuditReport.Report.PodChecks) > 0 %}
diff --git a/pkg/report/templates/default.qtpl.go b/pkg/report/templates/default.qtpl.go
index 8b0e292..7d7d49b 100644
--- a/pkg/report/templates/default.qtpl.go
+++ b/pkg/report/templates/default.qtpl.go
@@ -436,74 +436,79 @@ func (p *ReportPage) StreamBody(qw422016 *qt422016.Writer) {
 			qw422016.N().S(`
 
                   <div class="row">
-                      <table class="table table-sm table-bordered">
-                          <thead>
-                              <tr>
-                                <th scope="col">ID</th>
-                                <th scope="col">Severity</th>
-                                <th scope="col">Resource</th>
-                                <th scope="col">Installed Version</th>
-                                <th scope="col">Fixed Version</th>
-                              </tr>
-                            </thead>
-                            <tbody>
-                  `)
+                    <table class="table table-sm table-bordered">
+                      <thead>
+                        <tr>
+                          <th scope="col">ID</th>
+                          <th scope="col">Severity</th>
+                          <th scope="col">Resource</th>
+                          <th scope="col">Installed Version</th>
+                          <th scope="col">Fixed Version</th>
+                        </tr>
+                      </thead>
+                      <tbody>
+                        `)
 //line pkg/report/templates/default.qtpl:202
 			for _, v := range report.Vulnerabilities {
 //line pkg/report/templates/default.qtpl:202
 				qw422016.N().S(`
-                    <tr>
-                      <td>`)
-//line pkg/report/templates/default.qtpl:204
+                        <tr>
+                          <td>
+                            <a target="_blank" href="`)
+//line pkg/report/templates/default.qtpl:205
+				qw422016.E().S(v.PrimaryLink)
+//line pkg/report/templates/default.qtpl:205
+				qw422016.N().S(`">`)
+//line pkg/report/templates/default.qtpl:205
 				qw422016.E().S(v.VulnerabilityID)
-//line pkg/report/templates/default.qtpl:204
-				qw422016.N().S(`</td>
-                      <td>`)
 //line pkg/report/templates/default.qtpl:205
+				qw422016.N().S(`</a>
+                          </td>
+                          <td>`)
+//line pkg/report/templates/default.qtpl:207
 				qw422016.E().S(string(v.Severity))
-//line pkg/report/templates/default.qtpl:205
+//line pkg/report/templates/default.qtpl:207
 				qw422016.N().S(`</td>
-                      <td>`)
-//line pkg/report/templates/default.qtpl:206
+                          <td>`)
+//line pkg/report/templates/default.qtpl:208
 				qw422016.E().S(v.Resource)
-//line pkg/report/templates/default.qtpl:206
+//line pkg/report/templates/default.qtpl:208
 				qw422016.N().S(`</td>
-                      <td>`)
-//line pkg/report/templates/default.qtpl:207
+                          <td>`)
+//line pkg/report/templates/default.qtpl:209
 				qw422016.E().S(v.InstalledVersion)
-//line pkg/report/templates/default.qtpl:207
+//line pkg/report/templates/default.qtpl:209
 				qw422016.N().S(`</td>
-                      <td>`)
-//line pkg/report/templates/default.qtpl:208
+                          <td>`)
+//line pkg/report/templates/default.qtpl:210
 				qw422016.E().S(v.FixedVersion)
-//line pkg/report/templates/default.qtpl:208
-				qw422016.N().S(`</td>
-                    </tr>	
-                  `)
 //line pkg/report/templates/default.qtpl:210
+				qw422016.N().S(`</td>
+                        </tr>
+                        `)
+//line pkg/report/templates/default.qtpl:212
 			}
-//line pkg/report/templates/default.qtpl:210
+//line pkg/report/templates/default.qtpl:212
 			qw422016.N().S(`
-                            </tbody>
-                      </table>
+                      </tbody>
+                    </table>
                   </div>
                 `)
-//line pkg/report/templates/default.qtpl:214
+//line pkg/report/templates/default.qtpl:216
 		}
-//line pkg/report/templates/default.qtpl:214
+//line pkg/report/templates/default.qtpl:216
 		qw422016.N().S(`
                 `)
-//line pkg/report/templates/default.qtpl:215
+//line pkg/report/templates/default.qtpl:217
 	}
-//line pkg/report/templates/default.qtpl:215
+//line pkg/report/templates/default.qtpl:217
 	qw422016.N().S(`
-                
 
                 <!-- Config Audits -->
                 `)
-//line pkg/report/templates/default.qtpl:219
+//line pkg/report/templates/default.qtpl:220
 	if p.ConfigAuditReport != nil && len(p.ConfigAuditReport.Report.PodChecks) > 0 {
-//line pkg/report/templates/default.qtpl:219
+//line pkg/report/templates/default.qtpl:220
 		qw422016.N().S(`
                   <div class="row pt-3 text-center border-bottom my-4">
                       <h3 class="mx-auto" id="ca_header" style="color: rgb(0, 160, 170);">Configuration Audit</h3>
@@ -521,19 +526,19 @@ func (p *ReportPage) StreamBody(qw422016 *qt422016.Writer) {
                              <div class="row">
                                 <div class="col">
                                     <p class="my-0">Name:  `)
-//line pkg/report/templates/default.qtpl:235
+//line pkg/report/templates/default.qtpl:236
 		qw422016.E().S(p.ConfigAuditReport.Report.Scanner.Name)
-//line pkg/report/templates/default.qtpl:235
+//line pkg/report/templates/default.qtpl:236
 		qw422016.N().S(`</p>
                                     <p class="my-0">Vendor:  `)
-//line pkg/report/templates/default.qtpl:236
+//line pkg/report/templates/default.qtpl:237
 		qw422016.E().S(p.ConfigAuditReport.Report.Scanner.Vendor)
-//line pkg/report/templates/default.qtpl:236
+//line pkg/report/templates/default.qtpl:237
 		qw422016.N().S(`</p>
                                     <p class="my-0">Version:  `)
-//line pkg/report/templates/default.qtpl:237
+//line pkg/report/templates/default.qtpl:238
 		qw422016.E().S(p.ConfigAuditReport.Report.Scanner.Version)
-//line pkg/report/templates/default.qtpl:237
+//line pkg/report/templates/default.qtpl:238
 		qw422016.N().S(`</p>
                                 </div>
                              </div>
@@ -547,85 +552,85 @@ func (p *ReportPage) StreamBody(qw422016 *qt422016.Writer) {
                             </div>
                             <div class="row">
                                 `)
-//line pkg/report/templates/default.qtpl:250
+//line pkg/report/templates/default.qtpl:251
 		sumDanger := p.ConfigAuditReport.Report.Summary.DangerCount
 		sumWarning := p.ConfigAuditReport.Report.Summary.WarningCount
 		sumPass := p.ConfigAuditReport.Report.Summary.PassCount
 
-//line pkg/report/templates/default.qtpl:253
+//line pkg/report/templates/default.qtpl:254
 		qw422016.N().S(`
 
                                 `)
-//line pkg/report/templates/default.qtpl:255
+//line pkg/report/templates/default.qtpl:256
 		if sumDanger > 0 {
-//line pkg/report/templates/default.qtpl:255
+//line pkg/report/templates/default.qtpl:256
 			qw422016.N().S(`
                                 <div class="col text-center p-0 text-danger font-weight-bold">
                                 `)
-//line pkg/report/templates/default.qtpl:257
+//line pkg/report/templates/default.qtpl:258
 		} else {
-//line pkg/report/templates/default.qtpl:257
+//line pkg/report/templates/default.qtpl:258
 			qw422016.N().S(`
                                 <div class="col text-center p-0">
                                 `)
-//line pkg/report/templates/default.qtpl:259
+//line pkg/report/templates/default.qtpl:260
 		}
-//line pkg/report/templates/default.qtpl:259
+//line pkg/report/templates/default.qtpl:260
 		qw422016.N().S(`
                                     <p class="mx-auto mb-1">`)
-//line pkg/report/templates/default.qtpl:260
+//line pkg/report/templates/default.qtpl:261
 		qw422016.N().D(sumDanger)
-//line pkg/report/templates/default.qtpl:260
+//line pkg/report/templates/default.qtpl:261
 		qw422016.N().S(`</p>
                                     <p class="mx-auto">DANGER</p>
                                 </div>
 
                                 `)
-//line pkg/report/templates/default.qtpl:264
+//line pkg/report/templates/default.qtpl:265
 		if sumWarning > 0 {
-//line pkg/report/templates/default.qtpl:264
+//line pkg/report/templates/default.qtpl:265
 			qw422016.N().S(`
                                 <div class="col text-center p-0 text-warning font-weight-bold">
                                 `)
-//line pkg/report/templates/default.qtpl:266
+//line pkg/report/templates/default.qtpl:267
 		} else {
-//line pkg/report/templates/default.qtpl:266
+//line pkg/report/templates/default.qtpl:267
 			qw422016.N().S(`
                                 <div class="col text-center p-0">
                                 `)
-//line pkg/report/templates/default.qtpl:268
+//line pkg/report/templates/default.qtpl:269
 		}
-//line pkg/report/templates/default.qtpl:268
+//line pkg/report/templates/default.qtpl:269
 		qw422016.N().S(`
                                     <p class="mx-auto mb-1">`)
-//line pkg/report/templates/default.qtpl:269
+//line pkg/report/templates/default.qtpl:270
 		qw422016.N().D(sumWarning)
-//line pkg/report/templates/default.qtpl:269
+//line pkg/report/templates/default.qtpl:270
 		qw422016.N().S(`</p>
                                     <p class="mx-auto">WARNING</p>
                                 </div>
 
                                 `)
-//line pkg/report/templates/default.qtpl:273
+//line pkg/report/templates/default.qtpl:274
 		if sumPass > 0 {
-//line pkg/report/templates/default.qtpl:273
+//line pkg/report/templates/default.qtpl:274
 			qw422016.N().S(`
                                 <div class="col text-center p-0 text-success font-weight-bold">
                                 `)
-//line pkg/report/templates/default.qtpl:275
+//line pkg/report/templates/default.qtpl:276
 		} else {
-//line pkg/report/templates/default.qtpl:275
+//line pkg/report/templates/default.qtpl:276
 			qw422016.N().S(`
                                 <div class="col text-center p-0">
                                 `)
-//line pkg/report/templates/default.qtpl:277
+//line pkg/report/templates/default.qtpl:278
 		}
-//line pkg/report/templates/default.qtpl:277
+//line pkg/report/templates/default.qtpl:278
 		qw422016.N().S(`
                                     <p class="mx-auto mb-1">`)
-//line pkg/report/templates/default.qtpl:278
+//line pkg/report/templates/default.qtpl:279
 		qw422016.N().D(sumPass)
-//line pkg/report/templates/default.qtpl:278
+//line pkg/report/templates/default.qtpl:279
 		qw422016.N().S(`</p>
                                     <p class="mx-auto ">PASS</p>
                                 </div>
@@ -642,9 +647,9 @@ func (p *ReportPage) StreamBody(qw422016 *qt422016.Writer) {
                                 <div class="col">
                                     <p class="my-0">
                                         Generated at:  `)
-//line pkg/report/templates/default.qtpl:293
+//line pkg/report/templates/default.qtpl:294
 		qw422016.E().S(p.ConfigAuditReport.Report.UpdateTimestamp.Format("2 Jan 2006 15:04:01"))
-//line pkg/report/templates/default.qtpl:293
+//line pkg/report/templates/default.qtpl:294
 		qw422016.N().S(`
                                     </p>
                                 </div>
@@ -665,53 +670,53 @@ func (p *ReportPage) StreamBody(qw422016 *qt422016.Writer) {
                             </thead>
                             <tbody>
                               `)
-//line pkg/report/templates/default.qtpl:312
+//line pkg/report/templates/default.qtpl:313
 		for _, check := range p.ConfigAuditReport.Report.PodChecks {
-//line pkg/report/templates/default.qtpl:312
+//line pkg/report/templates/default.qtpl:313
 			qw422016.N().S(`
                                 <tr>
                                   <td>`)
-//line pkg/report/templates/default.qtpl:314
-			qw422016.E().V(check.Success)
-//line pkg/report/templates/default.qtpl:314
-			qw422016.N().S(`</td>
-                                  <td>`)
 //line pkg/report/templates/default.qtpl:315
-			qw422016.E().S(check.ID)
+			qw422016.E().V(check.Success)
 //line pkg/report/templates/default.qtpl:315
 			qw422016.N().S(`</td>
                                   <td>`)
 //line pkg/report/templates/default.qtpl:316
-			qw422016.E().S(check.Severity)
+			qw422016.E().S(check.ID)
 //line pkg/report/templates/default.qtpl:316
 			qw422016.N().S(`</td>
                                   <td>`)
 //line pkg/report/templates/default.qtpl:317
-			qw422016.E().S(check.Category)
+			qw422016.E().S(check.Severity)
 //line pkg/report/templates/default.qtpl:317
+			qw422016.N().S(`</td>
+                                  <td>`)
+//line pkg/report/templates/default.qtpl:318
+			qw422016.E().S(check.Category)
+//line pkg/report/templates/default.qtpl:318
 			qw422016.N().S(`</td>
                                 </tr>
                               `)
-//line pkg/report/templates/default.qtpl:319
+//line pkg/report/templates/default.qtpl:320
 		}
-//line pkg/report/templates/default.qtpl:319
+//line pkg/report/templates/default.qtpl:320
 		qw422016.N().S(`
                             </tbody>
                       </table>
                   </div>
                   `)
-//line pkg/report/templates/default.qtpl:323
+//line pkg/report/templates/default.qtpl:324
 		for container, checks := range p.ConfigAuditReport.Report.ContainerChecks {
-//line pkg/report/templates/default.qtpl:323
+//line pkg/report/templates/default.qtpl:324
 			qw422016.N().S(`
                     <div class="row"><h5 class="text-info" id="ca_container_`)
-//line pkg/report/templates/default.qtpl:324
+//line pkg/report/templates/default.qtpl:325
 			qw422016.E().S(container)
-//line pkg/report/templates/default.qtpl:324
+//line pkg/report/templates/default.qtpl:325
 			qw422016.N().S(`">Container `)
-//line pkg/report/templates/default.qtpl:324
+//line pkg/report/templates/default.qtpl:325
 			qw422016.E().S(container)
-//line pkg/report/templates/default.qtpl:324
+//line pkg/report/templates/default.qtpl:325
 			qw422016.N().S(`</h5></div>
                     <div class="row">
                         <table class="table table-sm table-bordered">
@@ -725,113 +730,113 @@ func (p *ReportPage) StreamBody(qw422016 *qt422016.Writer) {
                               </thead>
                               <tbody>
                                 `)
-//line pkg/report/templates/default.qtpl:336
+//line pkg/report/templates/default.qtpl:337
 			for _, check := range checks {
-//line pkg/report/templates/default.qtpl:336
+//line pkg/report/templates/default.qtpl:337
 				qw422016.N().S(`
                                   <tr>
                                     <td>`)
-//line pkg/report/templates/default.qtpl:338
-				qw422016.E().V(check.Success)
-//line pkg/report/templates/default.qtpl:338
-				qw422016.N().S(`</td>
-                                    <td>`)
 //line pkg/report/templates/default.qtpl:339
-				qw422016.E().S(check.ID)
+				qw422016.E().V(check.Success)
 //line pkg/report/templates/default.qtpl:339
 				qw422016.N().S(`</td>
                                     <td>`)
 //line pkg/report/templates/default.qtpl:340
-				qw422016.E().S(check.Severity)
+				qw422016.E().S(check.ID)
 //line pkg/report/templates/default.qtpl:340
 				qw422016.N().S(`</td>
                                     <td>`)
 //line pkg/report/templates/default.qtpl:341
-				qw422016.E().S(check.Category)
+				qw422016.E().S(check.Severity)
 //line pkg/report/templates/default.qtpl:341
+				qw422016.N().S(`</td>
+                                    <td>`)
+//line pkg/report/templates/default.qtpl:342
+				qw422016.E().S(check.Category)
+//line pkg/report/templates/default.qtpl:342
 				qw422016.N().S(`</td>
                                   </tr>
                                 `)
-//line pkg/report/templates/default.qtpl:343
+//line pkg/report/templates/default.qtpl:344
 			}
-//line pkg/report/templates/default.qtpl:343
+//line pkg/report/templates/default.qtpl:344
 			qw422016.N().S(`
                               </tbody>
                         </table>
                     </div>
                   `)
-//line pkg/report/templates/default.qtpl:347
+//line pkg/report/templates/default.qtpl:348
 		}
-//line pkg/report/templates/default.qtpl:347
+//line pkg/report/templates/default.qtpl:348
 		qw422016.N().S(`
                   `)
-//line pkg/report/templates/default.qtpl:348
+//line pkg/report/templates/default.qtpl:349
 	}
-//line pkg/report/templates/default.qtpl:348
+//line pkg/report/templates/default.qtpl:349
 	qw422016.N().S(`
             </div>
         </div>
 `)
-//line pkg/report/templates/default.qtpl:351
+//line pkg/report/templates/default.qtpl:352
 }
 
-//line pkg/report/templates/default.qtpl:351
+//line pkg/report/templates/default.qtpl:352
 func (p *ReportPage) WriteBody(qq422016 qtio422016.Writer) {
-//line pkg/report/templates/default.qtpl:351
+//line pkg/report/templates/default.qtpl:352
 	qw422016 := qt422016.AcquireWriter(qq422016)
-//line pkg/report/templates/default.qtpl:351
+//line pkg/report/templates/default.qtpl:352
 	p.StreamBody(qw422016)
-//line pkg/report/templates/default.qtpl:351
+//line pkg/report/templates/default.qtpl:352
 	qt422016.ReleaseWriter(qw422016)
-//line pkg/report/templates/default.qtpl:351
+//line pkg/report/templates/default.qtpl:352
 }
 
-//line pkg/report/templates/default.qtpl:351
+//line pkg/report/templates/default.qtpl:352
 func (p *ReportPage) Body() string {
-//line pkg/report/templates/default.qtpl:351
+//line pkg/report/templates/default.qtpl:352
 	qb422016 := qt422016.AcquireByteBuffer()
-//line pkg/report/templates/default.qtpl:351
+//line pkg/report/templates/default.qtpl:352
 	p.WriteBody(qb422016)
-//line pkg/report/templates/default.qtpl:351
+//line pkg/report/templates/default.qtpl:352
 	qs422016 := string(qb422016.B)
-//line pkg/report/templates/default.qtpl:351
+//line pkg/report/templates/default.qtpl:352
 	qt422016.ReleaseByteBuffer(qb422016)
-//line pkg/report/templates/default.qtpl:351
+//line pkg/report/templates/default.qtpl:352
 	return qs422016
-//line pkg/report/templates/default.qtpl:351
+//line pkg/report/templates/default.qtpl:352
 }
 
-//line pkg/report/templates/default.qtpl:353
+//line pkg/report/templates/default.qtpl:354
 func streamaquaLogoImg(qw422016 *qt422016.Writer) {
-//line pkg/report/templates/default.qtpl:353
+//line pkg/report/templates/default.qtpl:354
 	qw422016.N().S(`
 <img class="mx-auto" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAeAAAACaCAYAAABxGpuGAAAAAXNSR0IArs4c6QAAAIRlWElmTU0AKgAAAAgABQESAAMAAAABAAEAAAEaAAUAAAABAAAASgEbAAUAAAABAAAAUgEoAAMAAAABAAIAAIdpAAQAAAABAAAAWgAAAAAAAAEsAAAAAQAAASwAAAABAAOgAQADAAAAAQABAACgAgAEAAAAAQAAAeCgAwAEAAAAAQAAAJoAAAAAa7B3kwAAAAlwSFlzAAAuIwAALiMBeKU/dgAAAVlpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDYuMC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iPgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90aWZmOk9yaWVudGF0aW9uPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KGV7hBwAAQABJREFUeAHtfQmcHEd1d1XPtStLvuU7RtauJOw9bCwImMtyHGxwTAIEOUAIkJCYD3IRwkeSXwiRE3JgIAe5iAnhhmABzpfgA3N4cWKMHa+PPWxLWskGHB8I29iSpZ3Z6e7v/3/VPTtaze707M7Rs/tKmu2Z7urqqn+/ele9qjJGkyKgCCgCioAioAgoAoqAIqAIKAKKgCKgCCgCioAioAgoAoqAIqAIKAKKgCKgCCgCioAioAgoAoqAIqAIKAKKgCKgCCgCioAioAgoAoqAIqAIKAKKgCKgCCgCioAioAgoAoqAIqAIKAKKgCKgCCgCioAioAgoAoqAIqAIKAKKgCKgCCgCioAioAgoAoqAIqAIKAKKgCKgCCgCioAioAgoAoqAIqAIKAKKgCKgCCgCioAioAgoAoqAIqAIKAKKgCKgCCgCioAioAgoAoqAIqAIKAKKgCKgCCgCioAioAgoAoqAIqAIKAKKgCKgCCgCioAioAgoAopAhxCwHXpu6h8bbjOe+eM2VvMKPGvbNnwW+cxt20K8zHCRd+ttioAioAgoAopAZxEIrzaZ8CaT7WwtGn96aLZ54datmcbv1DsUAUVAEVAEOoGAWsBVqFPw2gtMmafCO8wqHI4yAazKadManPiEA/hz/AFjvr/ZmNfg8xJ8x395Og4LpmI2NIWyNV6ubK//xF7mpRC227f7C96nFxUBRUARUAQ6jkBrBEvHm9V4BSBwc/a5ZgZC+GjTaz6AEi7B5yiIXrp13V8W20zEpGQarZCX3z7fmKvXQxjj+wwewufUcyjP1oo5/9vYzOX26//6sAphoKFJEVAEFIGUI9B1rtZW4BlOmrwdMKXwTrPWzJjvmONMv9mHJwWteFpcJoUs5GaA49RJxjyWN2a1B6GLcx6lL1J0cD8W+ot78r0/Y4oH/gO5nqsW8EJY6TVFQBFQBNKBADj+yk5i+VL43izC9zazGsL3cXPQlOCKLsM0beZnJipPjqGPZ/jmgRN8szfvm1zgGx+fcDEflFU8UDSZ7ObwZW9+Ed9ouGXbclOuqI7wQ5rlJ7F6grwrOdXCrVuwq37f8Xtf6Ngt7YrpsdH2xfel/ch2Vbct/p32ere9fsuNSTcE4CGWb8ncbo4w68wzpohCehsqKGlmkiETWQidxj88BuO9cEEXYGrT8uW5xSc4pFlG6Oq+7+H4aYsvsf13OsG6Zcts3UdG6IfgJ0YnPsa1Q96tntmy190zshbXtzNP/InzLecj204c7CwOI2w/YwF4ZIqP7pf7mzEx1unEbTHvkFjUamt1u9PyfTHtS0vdF0tz6Ktb2M+NSSfNtRVfgrgi0yHCdwbCd7VxwhdhTS0DhN0tZg+PH23Mfridy/g8gwt7NmEU91kIvgLPpFu68RTAAvZgQV9ob/zEt8LNl+fs6FUzjRfT9js8MzCQNWvXBmZkRALgatTAM8PDvUf6fiGYzmRtJhfsC54qmaOOOmhGR+dpIyLCB+7NmMmzAOhyDUrbkjUDez0zOUncag+Y9PcXTHBUz2ovyJvQt/t9D76d3qJ56NaDNXDmqSTvY55bm3y6v//II/yeXr5v1n3e0m0mDP0Z75k13n4zNvYM8sW9bN5b0nDhyIGBY/0DNle3fahsGAT2mcz0j83UFA2EzqUtoLl9+yz6HZW7ZDQ3E86YYPX0AjRnzObNOWnU6ChpmZxyRaQVaQFX3M5uzPe2Ksu3dcKX5BSzhSeONKYIyzcHGqb44Pn52QvvTJ7CxUnv5A9oWk4IyAEIyMmSfKJiezYOrQ8CMwQ8hrzQPBtG/em4dIJ5Jjiy5HmF0IZZE5TCgumdNk+VnrEbhh5Hnv8FfDvADcbBEsZKvcEOM7kd5dICnHSde3Q9Li8TQUwmyESFBc2TNDx8RG5/cGbG884GHsPgYX3G2lNxPNZ4pV6QWR6Y2kI2KJns/oNmw9CTJrSPgIfugcwd98LgnoNhYdLsGX2q8j5mme08Sk707GYf+Fy0De/4Q+WM+bXQlB+31oBBV/PluDNZRFKUSzbjHZc/GP5eyZgrQVe5ShuaXbellxdX3CsVvRvDjDkb9X8a7Yt4cdzGOBsDRdDwjF1TCFddCul7gwireRXPpVewRgkWz8yK0K1WktdvPqrXK50FjjOMGg7ivj4wspNxPAY0tyqmuXyeYaWguf6hp3DtMTQHNGfvtaG9B42e2L977IdVijSflcPvFSGIV5wAPszydW7nEphT4ZD+XYMKF32KXSjuTz9eY0wJwjcLeVCGJ4b9i9dWRoKLdEsmcj35YJI+mGW+ULLnQ3D+DATGS8PAnGUhaK2N/PTCfhwP4t8qrI7iD6w+sh73PQ8fQMkcvikUvamwbwhR4ea6UpC/EZ0ZHX+UdzuX68gItXcpjie7JEXYjVQ8BUecMXii73kXo52XhAfCF5qM9xOh5+EnRyMcZrVbCYKz9ifwGbYWtIhMUHpMISw9CiZ5G4C8wfPD6w6OjHy/go0Tiu3BjRYWErrGapMFi/LLx6KurHSlOu6L+433HtpMBkbyTGuGjuY8tUk/2fOPMh48OoHP9kXFxkf+xHehUvzx8J4CeDGYpqerM8mpFv3xIAwzIhwjgV9Yf+YGzLZ4OeoGuittDqw9Cf0Vj6+mOVZ6toqVb9aehvMDaOpPSX4Q3UwY/LjQP3xXaMIbwQOuLe0ZH68IYyeISXOgzuWZVpQAPkz4xm7ndgnfp4+A8AWxZkBPXLeKXRBmnvSyCpUuT0KD4IVVg/HZke3UbE1+w+CZmMD8K2Y6fK3xvHWYgQ0YgEXAT+BDJLDjMREZ18Plp/wmaEi4gf/cXTzBfFljvX6bsf24/JaCKf3Q9A1dA8Q/NrN7fBSWFfPFgljqwhOpTrFFEFkfPRuHXwKc3obKXwrsoIggETtoL8b3Z/gNZ4gbPuTsJDb5jQOvgfBCAu3uiq4BN3sSsPs5/P65wPMPFPqHbkTuq4q7x68XaxsX2ml9gbmXnVIFP1EYOhcl6zCb4nbOQAbDwrcxzczmSPe3srwB+sFCeHZm31t1reU94XrGWKpJSD09PNfKZCtehNHRwGAYI296XwtK+mXQw0uhDLh3QXpjFwTNoTLxu4hpLT6ynrhWk+bQJns0aO4ClH0BiPcvIIxvgU/j49Mz+74AQTwtjYSSDmU9foacWi5/yLBWRFrQ7dxKciYZsvx9WHBjJrJ8KXgrH1zjd8mEw/JL7Mx5x8C3+739wy8o9A9+Ce6ne6E5vxtTrtZxgIuCA4IXnQwR3U6QUtvnh52dZhpplR8iGn/neTKuOC+/Y7wwQOy6lOejg59gspm3eZ69o7Bh6FoRXjSTKcxYr3Sn2B0nzKfQN/xyCMVvw967OfQyv4i2YaEY38cHDBxtZtsdXjFuwAOMexa3CDs5R6yIbZwXnDQsS1mBz7JWgdG+Clb1dXjmaL5/8DKcgyMBY+5UplyZcqp1f0RxYPGsd61PTA80+uN88qUL/lB1rK539G5qtjPO55rVSgvYvdtQXPibNq3Jbxh6D4YCdlov81kIygtRgRxoxNEJ6aUmzVX6a/zO8J5q0hzNZleWLzQHqrIvgjvjXwvZNbsKfYO/a047r3d2OGH5rfRHAl72SSxfLrJxC8YSGXB1hDkD0c4ldIDWuZ1jVClbn+lx7mZavkzCNuYKYZxn3uWUqjpzYf05G8DIt2O86FYEi/08mymac0g1WpgOhUEsbB07ZabGE9GNhQuC0lA+hTF9sjZzCYUXOvaXOdYcdWy6dpk/XckFpYQUeLn+4XMLfUPfwDjg9RCKL0VbIqEr2LG9xG2pQrEaNwptOiHAHCHYPe9c62W/2NM3dHtP38AFkTUciDWcLtS6qTZLofFWtJPu5lz0bg3o7TcK5fwOz8t+AIre6U4xEyWPXIr00QyaIwZxX+UxlKmYVCjhrrbZ3IcKPft39GwYeotcYwxH+pVmVDV5Yqdb1qnidqbwzRrO812HpR4ZSdh664ekegBxXT7oVYRvJHQpaYl8bPmKNbzMXkPF6gXQ/UPvM55/n8lkXiuC0PcRKyPqBjuxINGi1rODs3w+x4KJQOmC6zWbfQ1E1/2wKP8vzsMtnjJrmNi5MTdb2DD8QazLMgrsLqRrXhihsyZaiR1xi5kjgt7gmYAwDjPe80Iv+y28z48jKv0IqaNjiMyrqVsRcApoIMrexrN/EorynTab+TtYoyeHfhl9RrxSscCNaaMVraWl74Q7ninPtohrsJlPoE43VZRmV99lIbuWRSPmowRZ25mLbMTCN57n28qpRnFlKHynIeMDQOzByCPZcrw3dj3HQjg+F9/X/UfnNkV0c37j0LPZmRFncgWalYElGgteKj+dYNp8LrRsqUcOTOZKduzVfcMniDXcee16Frv1Q0Oo2wRcf+8GAwQdwSqYVSbwta2JzDcjghiM0ctkfqVwIKRl8lLnRcA8bFe3tlZKH9YEBKqs3p7+oSu8MLwNHo/nRN4pupjZZygU2534TEydg9VN2vcyW6g09/QNv7nigelMvZqKw7IVwOBZGW6sEN5uThLLN452bofw5SsqgWeJ8KUkRoqt3FjgVqzf6JoYhJKzm/+QnjhHcAZjR2+wgZ1Ax0FnhhbtLF525k7THJ/PegRSL3Tskg3v6+0beJEIE+f6xeW2pwp2Pf2Dv2Q9MwZGeBbqSG8NiYhCsBNKSwwEn406hB6YcxHjgaeGxvs2lIR3RdO7oGUuvzG6uPHL8hh7WtadczSCn76FoaH3iYdKYjEqLuZON925qEUBtbkw630SMST/EFXKT+XwUQOIdZoZNlDV5Fk52oeoOp9bC4J13YBg/3Vmv+xpxLmQkURMXl7DOUugGU7HpeXLx4nQZSn4TjYWW8GHHHm9qxNpiQ0OMFb4J5je8jl8h9Uk1iYFHluepuQEceAXQSzHBl7mvyXQiK7f9gth1oV0GdAKgZv30wJUgDm7mB2ET5qwY10QOwG3NNz5NpP9MFz5/yT1lXnWKoQdFin/S+Ebe6my/jiC7S6IlD1WnMpe2hKVPyzX689g4ZJ3QPG7DhW0Yg2nMYYjIXrs+MsvbY+srNPN88AqzjZPmTJelQu4YuRhKxNWDpBZH7Gly6MI3kj48tlEPb7O37F1zO/dmdgiCl8Eb4AZZ7N/BMGLaGaJkqTwTXMCXWClHmptXuaLsD5/RcY22yeEiZ0QCZjK34sVwuAnOMpxPs3YgSFaehFm4Mr/P6j7dveSZbGTTrgs00xj6apbJHxz6weeZwNzJzwtp0Gw0dOSNmVvLm6kqywVBSh+r0Aswi2VwLEuFcLLSwBvCz1zU5jdPnC1YwAhRC+39qMlZhH1jFjklnywlA0YJqa+eO5oKXjwsRT8PEa/varv1dcsp98Iw8Wh6xIBpgAxYMJXkRmTKeMnaYvuo8UmlkkhxHfG8ua+O56Lz4vwx+/FJmr8CHDCDCYv8/H8huHXVwUYLbbMJPfFymBI4Qum8usV7FwwSpIyauUhHjFeMUbx77l4LgE7mVqSQ52xElX2tYwujyoTTyWrVTc910kEYuHbN7TZ87zvwFfYC7qPPS1LqJnMwZ5LW7VojrQh/GKRD2OfKVAII7bkvMKPS9+UcmSOfPd5X5bCIBeJX4tuuxrM4DIhgoATFrfdtC1rz9t2X3hbuN2caLea/Vi9sFovr4gNZI7ZIKtG0qj+HZ/jkSm+Lz66s+6vrG2Ar2RpnMLIsioffIm/0z3N71zeNodPBrKqBx/wf5SPE12UZGWrkTJcp38J6+3XyIxRewq0xbaDHZQfLgzBifquqLmlET8mBijJbBwRxjxDmp6bm+frJVIHp91k4ZL+PCzhR6YnJ0Zk2gOXy2xFirGDyx7YxcJ3sfVnDcnwSH054Eb88BWfuWhUsENW4oeIBZdx0a7HPBkipo28hkpYcWr88qg8Pjl+Gr5q6igC9OqMjpYYTYwuMyI0Qu/P4j0tfLe8H+8ZC6UgcEFobi69sdFCBfgj/VWiqtnH2eequTJzJk0UwtM2m30J1xUoTk28FrEIpP2uornlIYBh9ZoLbNlACK8qTDznQJD90bYLznyQb/Le1VvfeNZj27+F13I6fmI6RQuDgISZRe+fQrYikEl9FLA8xudx9HFiP4RM6fED5sn82RDCWyFMSETI3AWJ2vTISAnC6q2YJvN76BAUAIsVIOyQATpxDgt0YHV9aCNB8DjWKN6Nc3sw3PgoPPX7kQcoh1gKyK6FfOE77cfndCxFmBP43QJaZAqLqQfv4b05lP+fvX2DZx2cnPiBW8VrhG1rXoqxQ1Qnpvf8EZZbZPlkRiSgRhKJithhYTEPygP348DPMPwhpj7vxkjHg9AFH6tgZ+0q3HACQiGehXv6wTBPges9L9OxA6E9lrUY7CiEaQn/GgLwpkq7xq8U96CbToUiNXUWAViHo9tnuLBFGOy/EbSyGspm7HZutGqkOdJrDkGWjKsBBWLIKfT3wPCYwu8fYKGdx0GDmEOOoL0Qq10Zcyo+Z+DTx2eDTjMRnbK/kd8tRhD3iOKXyf18z4bB90/vmnhvt9EcO1p3p+t2FSB8iz3X3LXOePd+NcjkBnrAzab/Y/Lj4SsH3m4tFuU35qPtayTlJ1N8dL/m/3tALoWnPutCMxxs5eKo4KXpF8CRNp2DKwvC6l/QAdkO1rvRuvNGFOE5izcIvodOdQ3c9tflTe7u/VN37WXB86ZTNq/KHTG90fPtFhTDZRS3QBnIRfVZjCDOgXGUwFhWY8YNXao/GU17IJsh41l6irHbOHA2FItPYrycZbL8RrEjE/RQV/RjVC0I7sWw7FdQ0NenC8EEgmyeYMHzJqx01OsXBhDX8lOeta8Krcc1tT3Uh+0URWTeew+/wPpzfA7FeB+AlXXn9OjoN7qNIR7erOVyxg3RY2GLL0BJ6qPgQss45ttImhW8ro8FoJWvQbm7JsiY/yqtKeyWoZsFSsRKeKf5fvBc0OklyPZK0O5JVKmhNcYKbqMyiYofzKrMHxY2DH63ODr61ZZ6rRZo22IuNdrYxTyjdfdcPZk3l2wo9v7n5OkQW7fa1UeeFO5/GlaUzR5x7Nq32a/ee5MxZ33xa1/79BEXXfSmIpYzIJNIT+L+AM+cl7XvwtZwwwePMfCSN24AdaQ5nnQ0BD54Dz3+eUzYB/MXVxZdz40kbIJhoUFD7oT+GN7hlSVz8EvxlmvkEFHKgJEfKpzc7kaBeXj0ACTF3cjHz9/k+4YHrR+8A9/fik6ZB4OgJhRbdfiaKPG+ItzCz4Nr/S+mp8b/AM/nbjAUSktNMk2LU3Y8//4vyvDD7LSPpGU7Ael5LkjL978Bhvah4tTk1w4vAJbP5j21sPPNjh37sCfhd3EPP3/OqViB9d6Jd/JavBMuOcj20jI59H6cmCcxH9c3zoKnfs6sO2cTMPuxm560THaimqfhqT4djftydSsI35+DwKJR0qDwxfAeBSUFL+nC9//ZBJmPFPfcvWtO2y08RhnZsjC+sGYNF7thPwwOTo09hCM//w5BubqnZF6LYt+FvjoEIQw+AOW3MZc4eTrrBteP9wlz2sAmp3hyPDj9NNe9ApjC97KBkgjfECtc9a6i8CXPBlMKp/3pgz2r/HAT7cuLn9qMpc3EZYJf6UrhlotB1beSbfmLcsJ0ojluh5Sg8NDjV6JDb1yENh0JEBGQP8ZuMO+Z3j3+sUpT4ojG2Q27uUqPmImVPGY0Vqbcxgq8gE5e2j02gW/v6Nk0/EHI3itgjf2S65wNd2wGF8Eyt7+f2zhwzczo6O1NseYiQV7ov/9DwG5T49gxziHE6HiWmj82I/R+F5slzArew7DDuNioKCCz0DnsKCzJLB2O2CHq4O7JW3DulhxWQ0K84IfxjBdjzi/vo3WSlFdkgTeiVDMnwD/4j1hN/w0sQFOHECA9cJjIjfv+FWiGFUn6LuNKk3/S3QwRWv6y9ex7pneO74kuRhubYKMVs5392q0sF985eySdgea2gub2xjS3H/TxSZz/JBZ1+WUI4j+HgD8Jwt15dpIrfjHNHY99Kj6CMt8ozxhBySlPSTXbdDWDbudY+AZY27ln1Unm4IFYq+NM3wwYL6fiNsNiSVfbO10bdmhYglyfGMLpd6IO3YjlK5owGDStzBtzod1UEb7U1CkUGNEoUY2iwTI/O/bc5Do7td9Kfvr9ofminOkdYw+UpsbehNngr4BAeEysYRdsNLec+X6zb4DxYHu/wPuIZHIWcCz457tv/vPO9TxDAQfs3rkI7MCYEGyI8FVMw/0ggp0Gi1P3QPjSykWADVMFi7rYEddq7EIZ60Y5Mzvvub24a+IlEL5YZAPNZUBXY9hBOfB9jG2/HlbXK8QSiRUD1lFTuxBgX+J7hnEZ/g36AGmEfLIRvg8vFbwhUKoQJ/AGBjuJ8HV9ld4RR0PO2pyvryKb9GFcB11WaBTE5cox07vGP1HMlKDMB59BPUlvrKNoC7w5QUJQFmjO834RQVkXyTPiPpHg5k5laeRFdKqOhz73ULfz7bB8T4TwheULV+bc1G0RxXPrn8bfUYeGv+cvxXXcWIcWZoAOlgnLZQqQi2Uzbmx3hqZaWYmqtrBtAAl0cEYtk+HjU9w9dkOxnHk2hP3NIvQbFCR0t+G+52MJvDdJJWjBLi7R9SwMxQuCKxeBHReo57MDjE3/PATke6QawsDQ5ma4x8kYWY5jihbv56/BIM7DloBPQuizf5F5J0lUUpzSZM0H5QaWram9CNAVDHrhLlroc68ELdOd0YiyzFgIvPfgQazqN1zaNfYFY1y/ivrqHK9Uw81zuy6x75MHYEhElOaw/HbQeqz4NUI3kaJur5SaLFVhbrg5jd/QXQI4cjv3fPneZ2G4gJYvhS+YggUDr2UkNQ6I3rEAAk6jDETD9LyXoUOzcxyu+NQuIha+HmLk3l3cLQKELtBsNObb3BcYa9ns2A/e/WMIk/OhIX9pEUIYrhTEXdvwfWJpLrZTO2aI+b7DPwumdn6D2GEuuaUVMh143nmlXRNfiYSkFzHC2ogv9mw87QrYYczuuxDAZyPA6/uREE7qVXKbOGQyA1gZ7XKpSmTtLLZael+DCGBYgXc42hXHDfugfElQkhO+gT9Z9PPnFPfcs1OEpEGZzVemQscD4Mmh0rxr4qPwZdFz1agQJs0h8jpzdrSDkkE/aUThSABLc7N0jwCO3M4UviYbOMt3WtzOEADN5d3NhXjZlEYLzmm8ocUuQkn7caX9jFTkHJn3QPh+WAQvLzW/M1ceKF+mporxsyCEt8Lt+2WMM1FpSGrNYTlTLJTiZfp6+u5/q5S5mE4dM0MT/kFj9MoxX1i+3KjNC86ne1gYoROSTqk5tMXN+uWYIoXw7okfZLDoAZjbD8Ud6SKkkzwnUl7su0V5cXXuHp6TpIVpzUPFFoRG6xfDcXh3oiwnFUagd3g8An9nsRC8wOwZfUoUPvalxoi3QXQi9zRojp4rrCX/0xFrZ1sasLa5tbUBzSGlnOa6ozNEbueeL98J4YvdOnqPOGFet7Ogrn+ajoBzvQa59YOYQoCO4abO0MWVJGF+KMZ1Av/vi7vGPigC0Qmk9mhOFPKOIRmOYcESxo4vIoSTWnPQNmgFm9+QxjbaqZ3nIOxZP3whZvm8AIKMzCSJKxv4ILoTUeYYf9s6s3PydrNuXU8cJZ4E+CXnIdPFMw/suOvhwGYu5mAiygQjl0Vv6hXvJiV73oZ8346tkpkBfJpaj4AEMOIxXvibDSrLvnhbguApRD9cCAG2X4Svo/nW15tPiGhues/YN7GH6JvQV+PnJuEX3LXLxz0D+b7BV8uNW7akVs6ltmIx4iZ2O19Ly7dwm7qdK8i09wunEiB5nn2zhSGLRAsyiRks2jSGn74LCxTMAGlkhGUl6UySvSl/KIQjF2g2k30NlIGnhdEk06zZqWHBe0MuqAg1akSQyJQp3OOFb8Mz2Zykbef4M7YVCa4s7Z64Rur/4IMI8mxz4jMhhGd23X03wioudwyR/sG6iY0Vy8V64a9KbjcOnoRu6hauGeZBQJTN7X5h0/AmUNrLG1CW+U7xbvh6vF+QKUMcwmmn8I2bRJpDf52emvgMFXf0A0rhJArzLM1Z+3YpLopbiYtO0zHdAjh2O1P4cmNBBlyJ25kBV0n6f5qg7uq6eOIqxqIXaMXPOSMoUSQlXxLmDQZlRBK/WRBw1mAD7qQm4kZGAoZCaw425a9HgVBJCImduswttvBx7RgdTeb+jZhh78azsX0fx7VkGI7l1UsYy/IYTTyOaUa/J5knJxsJSKlXfmPXRfBvzUxPjf0LGOJ/QAjTgk/CEOn5YHe9ML9h8EzcQ7zTzXcaQyZ9ufftE/oKy+FWDLcQa9JNEpqjwkevxT9IdD37qnM7d6aNEb1Dcf9t9IOd6K8cOkrSBzhXmXV+Wb5/4Cwc2ekqZjQvpCWltyPccUeOi2zImG8ZbueeVZHbmUE/SXhmWiBeBvWIXDiFVeWXQCj8BDooqTsJQbNDo+fbP5MgDlqgzYjWXQqkwlAoSCY+i076rQYECZbO42Ld4cVrNm4+HlUgBvX7T8wMA/9iPGs1fMlgIHAr109ghOCaHhYpYHLWezKhX7/sJeWwGftOYEfhyzHFenViW7lEJZptuVIZvQdJ2i9Z9U/DCLhFcnibNZdKIFMyhskFjKjwPYbpQIhTQIo9N/KjI3+CaHodVtwyv+NUCHEh1RMAVDY47IWWZ5wbemAgCb9qeyPT2RG4tvNznzvTc8196yTgitHOzvLldBVN7UYgEiJYreoVXKkQicJnYY2a2+m5Dv3odMH/kFR5cjKJxSRZW/onWggAi9T+kbNIRZmo16kRjMW1bTNHF8OZ86V+9ceWKoFrWNHjlVGbxASu0z4GfdESuR5zLr8h49edcAMeVkkEycAq4hxrXOLuTcyRxCIB1ODvxl4qRcbBfPJD/zQXASx0gVRYf84GfDk3Wn8+CZ/HuCmz2b/kdCAX8Yz33enkhiy84p7x69Afvok6UpAmoTmsJ48ubcOfkSY43rMwz+pAW5O8mPZW62psJYiNFY64dvIkbGh/q+ldfQKEL6Pv1PJt75uYfVpstVr7UjJSpPp0g5FLrLdOBfwfJJAjCkSaLbSD31wAmEV073dQQVrBbE8S5SCg/g339UVS+1gxWbgpgel//pHIcl4k7OthR66BPBDZoXWKy8Llt/dqFAuAGv49IsrRL2X+fT0rmGPoqGf4HLri8YU/6uHQ3nYtl6dFyqW1wQtB1/BQiMelnvXnAq/K/iPFA7mrBIqpqaSzBFqNXAjvj2h68KD8LfsFEtsjXxZ4OCLwqfSZc3rOOPNZkt9NBVzglvZfSm0n8H37t/bo404yB545CEtKLd/200b8RKGR3vUDp+PEmY6R1nU/R9Zv+aDnZz4rBUWMOy60w8cQlpx0agjTT0pdsHoajvU6NdzQkuUFck+smMiPWn+2OuzCZwZBwydC2FPw1GOGsLKxQ5YfjE3vHvuWlBpNYar1hLafk7rAhe+WIrzeWU113dCAGR4Rz1vlB1iIn6mRILa2N7L7H4g9iF4oztr6QwRsrCjLOH6Ga6tHbt96faF9IFXGgjddB/6D3ZZoqlv2pToJkfqe1xtkM5sl4969qZN36aoQ9q0yl13mr/7KPSfAdXJJ+PSTNDcKNKM0dQiBiFFikf4BEHMPalHf/UxB5lzVI9MP3v0g7mEQV+fdWdUQRgpBNvS+hrWosdIThF79Tk23MFu3gbu6uOK46Ps8KdoEAXr4ucIzEgbDRMFe10ip0XzOeZ7QidOwSO6VNqO3ui128LbrVgTzSaCEcEaVE8DT0/XvqVuoZjgMgaifwXtyjrhgyUEXThRkeYZ1BJngS5K182O/c2scuBgIcYkjAJBNcq64uRmrfiMT8pDmQs/RHBaKrrqeiq/pEsDbt0t9Sl72eJAN96skSPUIKBVALttKxIzSs4PRq0igeUZohOH18s25kNJF/I5ReVwKExX7H6cw1NX0SIvo1F4vcm6Uts3daShq+iEHa4YP+T3/D2KbY7CXDYMbJVsyN/f8JbbiyuSkKFPZbPkmBGPtB5OjQK73fmkFU5cGHSFNnpUuhUwq1fV/RDJhF6qjQxOsjwyX+RVE11xOrwNVhztmTll7lzslmyqkC4y1ayO+E34talcy2UWaM+GANMbFHqRKniRrRLtfRUA/X73+3O5KrdDnxVpjGDiBk0whkjE/iJHvCGpxGemCsDK2hOCgWyM1LwnRiVYN+uyX5sQKSq22zU5V6otEe73+BlsS/CEIHzloj5iQItNnjbBa4gU5cN99jwCwSWeRyLlaKMTn0DCB91nuhFgz9fCI79VjMgQEz3x25hR00+MjQVVP4AjNYX+t292qdOLRSdIPktWoWbkiyz7rm3tgmHEOPxWLesZATHNnRNVg/np4NKvGicpJZwfIs+6pwikRmMswUyWKF+8jcrnWbSU7NAl/70yYn5LcKY96DWwwJswqbCAwyAtPl7bNr1yQgGMr7+RGmCFIf5eZuu1p3I8ysJ1gGlNlDN2MyeuuzwxBEsLXTzCbNq1xTXIRu2lsXlfWKdpaEptlnSJWbbLhIvFM4A/308bYvOwdnT4BHGlvzzww8Rhq+YAoqslpbi29AtK+lAmWdArgCCk9dBwBChERAPiyNuoDPLdQiixEbLrNNWRdSqcQidxaYWC/J8IBw0ULNaz6GsIVTpDf8weXOZyw6TjyHZMQO2QlPwwflLKjDRzke1r/WLsrYdViujmyN+xhVLip7AubsADNVgeBeLgiCE+K5Ew9QcrroHkerFOWF/Lo1Hl8Gy7H7vTvRe2rx1cqNNdji0e5+rkVUdtQ10SPSMxwEpWmmZYnAggEglA4MuGoAHoz6T78oQNjgSClTqPllsQ0max9AgKY0y6k4kmqhYyuQ7s1d+OOftitq4v5Xpzkh2nefO6yy2FDQy3fmJihyo+U/YmnI4XBo5F7vX7bXMYerIvGFdVWeqonHBvHJxKeCI47NqK0JM9AYKG4flx/nd+j03h9mn1HZOGjG+2ljy1BgjYrEPQEGe+IBPnbnkUFcNsh76YHRi7CJ57ANDALIUJirkv5caffLy2N5iWmtNVS10wpOID6cU5r4mrCzx4JkfkCVhx2vvE5hY5bCTZSNt3PxqTbGpEqBqHdJ1+Sg5cNbeCmFaZZwYga1cJDcmKLKxFK+G/8a95jGHhrGioctOn70gfmLTNdF0LQXCMtxErkJsMZHKlLKoBT90pSWKEDB7CiRjx/Ffp1goTApnruoQSltCeLzeRYV7jOW/A8+LdRaoMlwwbW1DgC0Ioav6ljd7C2yd8zcwahiymoZ6XawC1c0UjTbBfRXBgmWTRntvWkiiBIpaxLZaVmkdNvqUDgwFHYED5eKSpZRwW/cFbOSCpa0IFKOMs4Yzyu4laKgkYS1cOzIceNV3yCEldsRKSCmXWPa9vNr4dnJNFrhgiBvLY26U5YHE5pKMG4TrpXcEPltiQz9klsqFxinFIFQwVwQ29ypWWO3KsPj7Ljw01Luq/LMYRZIBeCtphStgCHq1Tb/u7PFg/iYTHjrAse4YU57gK8KnMf21bddD0oNM8k5rTADb4ZBLsh1bMQ09DKJ0VZQDS4kES9Zsp1LK6RSLAilvCp+oRWAQGSHVtOm+B4OdMFwx6Vmif9Ug/dpOW0IJ8K4BaAuoyKjPsxJ2Y/lVDvlKAOBEmcHO3gwzJS3AVa9rYcdjt2PIMnIBo8KQTiR10ntXJzH5Pe2LKGdKpgjBU/kfDZDqPAuKlys/OvE97e1mxS155s6Tg89ZgoNmAhPuzoCMtaYa2qeFZB7QpHigcW4fhRpCcnoR0uGwvq9E6vXaiebSUCC734Vj5Xy24VAow3aF5CWS6KGT35kUiI1CvfRR6G5tTCtHGdOoWLoDcPonlLIk7sXxxffjSSv/y+UIqjNvuN23uZ+K/YPuqF9uF6xObAhARhkJs16/GbQodjpenEbXYHrfWYq0u3ryxqguP8yYX87s/mso9LpvmmvkXnMQ/4kQSCnUURK9H4sEy5W6FspXtdBOD2/UknkTaj/cl6bjOelK4yAr+573R2qcU9kRCph6xjgGAuWF3nXAEnhYugt+WlRetoQzYAO8Li5lQv8OxYAJ+e6ymeJflm8V/gtmV2KRIkoQ2/l0yQwPnslgY+o2fj0BmCxqygSxc4UeQ3Vht9brSASbxYS7167j2QLf1IMo2M1Fbk4vOe9wPgQXc1eUG9/upy2Gi95JGRcnSfPEr/tBaB5jLr1tY1eekkT5JdbTJNXk535cRUXTbYc9N/1pxSv+MlaV80JgQON9mAWwvPplvL/rQ8YoVr1ZC94yJ+6+PN/jjDjcQ9622pn32Z5ogFSRjuwa5QFFD11pomvNj5JlPAWMkLBJW0TnGKlhZFhS+IZqbV48HRwjZQRtye0AsJVeF405mZh4HB/8r65vBHCx7z/3EbjJjw3GjbPuSMph/Of49eaRIC9V5+kx7TxmLYXeuRXBur06ZHzWA1Ca6//APzZH5UnjmyLalmvXAVI+Hph/aeyMqIV6OZ/z46tZxFcrG4Up1WXf+++Uvszisxsw2Du6JtDDk9pK5iRMYM6+810mi3IXlC+d2dMNWotWBU7DHfByV9z22UIa7aGlnllBPA+OsF5lI548aBU4Ybh3O2+6s2PecU1PGF0WYz9foFehOaEZoxaZfzqixEQxknqO2k3Id9ueW++f9w027wj0yv8bIXSbZ0z92fvyVdeGVZCWCL2WHx7NNIu+zCV9JwldnBshGT+h07etVMuGVbVrpsw0XVuCFaBH3mYP4+dFRo1eJLXVjF4ZKOjBnxMqfnV81cIqVu3rysaK0GUjVOuSjyXGZmHLsbPQHsiMHC2PFdBlB3rD0vt/Hsn0R+MNsVNw5MARMJkvCuaLOHerjJBiBwRl9yxBmDJ+J+9ot0CeBoG0e/XH4N+gammoV099arI5RZIYJbkbd+ilaLguH7ncjFXf8e5gDDxIz1t0jm2AMhP/RPKxFYNkxRAvQjXY8zVWW2aj3dr5XItqdsttAz2bw15dLb7Dc+9eUQy0bakW3s2M1KoeGetNyo24TfjQR9vfLJVIRhgnv8plQk5RsyNAusOeVQkNh9O3f+CF/uSGDJ8XZih3nXnskEwW/zRLRAvnxdMX/iZQdDc3MkoeoJKlpyJbjvjyp75o2CUzQGnxLMvMiFTOb0VhGp9StG+qFCVvIC/7uSPWE/yoThzdzjF4mBXvWUlxwX+YB++MKeDUMvlfybN3fPvGC2skvTshDAmK4/S2IktVgAd+lLSVht9q6MyeZi4XuVWL7O3ZuwiMayQaO+NtLX6zFDFoxO7ZcR6fnSQt/QK/A7MCuvU4dos1uVyNrrqrAjY10oETvYJPYNuf7hc83o6MwKxE7wwSrF3wp9n3glECQ2w72U4Wl4lzntvF7BzSk0C2HdnmuRMpDfMPzzcPWeUzW2vdDz2X/Izu6YfuC+7yEj+93CwjSyXg/a4h1QSBD8J8tXLnyP1IDkJqzzffIzlS58qdmy+tP1AljWhqE9Vs3S+J2fBGTXpW8zsnzBk8rly2H5XhVuvjzXZMt3FpqoU3te9mtYNJYbsJMZino9m6nGNxkLxnlrPihXKUhcZGaNzMv0VDxlJPCvBXaMTCV21dQ6X8PhwucCCeFfSYYUbiY+X8Wbcj6iudLusQl4s+4gFkh1enQo45mwgk/J9+x7j9Sjv182N21KnRZfCLf1lOUTbRi+X16/OJYjlWz+cjEUIe3+D8mSbDpfIB6rqSmYJeENkfs+Cb3RhY85wZkL8/1D3DLIN+nAbn50lsGVrhbAlmsMxc7QWOjypVR/XwYvaU4TIuFLt/MM3M6f/Fg4sDVvRq+KkZiTvSk/iah3YMddjK5EpxayqS+ALSz0MGCAx0BP39CfSk0GBpxF2JRqdUEhbgzdK+6enEJtv4WxP1a6jiCRdoEh+sTu/EL/8DvlnpXFEINoIReOTX4ZSp+AkuBPBhYzJJt9b+GM4U2GgqjTnpeBASpdJt8/uA3KwbMh6KiI1ekHlv0rH/pl3wbeNbzfuJ235OuCf6IIcOt5/xYFevFZ9YQwAZaZFPjydxC+Rwp20ToACz5PLy4aga4VwB7WF2LQVUWHjIVuzNr4O/6+aHhSdyM75aFuZ1i+ZnL7jPMetay+dKWK5ACmn2DABlKSTs18GVh+IdaafW/P+uELZRysv9+tE82ryz+FECTCbBHZ/LH6fLACCBkiscMh/OveDcPPF4a4krCbPEuUPIxnfh44cDnPJDRHnjYDJTFrs+Fn8N1E1qejXznRxj98X5g+1Ns3+EJYs39M5QBJBPLCtcA0AiprobmhuOeenciLdm1PxtGiyPnpnWP/BYub3gPSUpJ7sxxHx3NPLJheh52RQMKulRMLY9z5q10JrLcf9BQJX4l6jnW7WAjHvzuP7yJqMG/l2XMRcIW+W+12RtRzi4Wva0MU/FHcM34dLLO70alJO0k6NfMJ1wm98N8L/YN9K0+QTNLiMaVdE1+BRXIfxuXA6BK48J27HgFZ8FeG4XW96wdOF+zWrUvl1mpsY3PTdp/W68HdEz9AdPMX4Q1g8eLKrfMcjKHDyvQyzwO9QelholeVQqyNicIXFviajZuPD6z9SmQt0FNFgbhQAhOg7xkHL/yoZHRK3LzMYU5hs7EHof276HFJ+iqLydPzAkv9ZxG78QH8pkubuLUXO9ZkBaSuA9Xj7qNkZ3RJkaRIqiTLmDTj70nJDbemK9Xsm7HwnXU7b22523kuLBWXYGi9Kxvs1NSsZ8BTMPXC3tzbP3zaihPCkRsUZPtBiYuxiZQXvgOxSkLPOzbwvFt6N559qnnwwWm4CFeGFyGaS411of86cqdyTDfu7XNptPo33Ldw4XvZX+3pH7qC82+ji+2xhAcG8kLjWFK0FJRugsJ6IoZjEriepZYY/7cZGwR3FHdNfFXOTE4mUTxm2x+NOU/vHvssBOpOPJ9Wd9JhqiywK0PheU++b/gPTSWw0y1LO/sQ/bZUBLpHAKPLeU+juSUIKMooEb74Egnc5SOED+MtZByR23k24Mpsb7nb+XDacivx2NKusS+gU98ZdeqkjAFbr9Eq8U4JTDiKjj0oDEoE0wro2M4taKZ3jX8CzO2eBrGDVSLYnYY4mbtzfUObBTvSBaeILetEwbk1M7Nz8h54AT4Hy4ytFY9CgmZzCo8fepn3YXrNnyI/uYZY1QnuXWwWK8oR+8r6zUcVVpW+C0t8UN4frctkCUyAUVqWdcY0NJkSdBhjqFuUuw9D6CHKIdOMuWXdO5kZGyT5gc1474cC8xf4DezwLqhYRIXVLUUz1EUg/QJY6CYSvkX84O+YFHmEbyomKxHCcZPjPPHvtB+DeBOFqMGuvrHlC921iGhnBFwx2rldbudamEWRmDawLspUXGWVN1LrjupzFCS0hE/A9px3YUrG6934XNyxl7UgplvQjf2F9vcjUNj/klJqjN3xGNG7o7Bh8P/gXl+sE5Ybl12N9nL5Hq3MhEGP90F5ofCl9Z/Ex8XOBEGC6F4v814EQX1KIImndTVbeXHCyVA5yp8xOFzwSuN47hAEGeucVPjSdc5paF8vTo0x+tmLI6il7o38iYaNpqcmPos5wbc2aAWTNuGnwaB1JvP7hf6ha8zw8BFuLjMWhnH0dgizaqRqmtchkF4BTLbE14uj9wS+HIzeNUUSu178kd+4xiM+EjtYnQenuyJZTKGINQlXYbaiyvL9zMfC9rudD4eO7igwruk9Y9/EnMvPQkNGvRONy8Vl0RKm1ZxFUMrn8/3Dn17d/5y1rmNHgrjZjDF+cqePZPxoW3H32A3WD74Aa24R2MGVz2Sz/wSmeH1+49CzhUE7l2MmslDS268X8w5IcxBu0zvH90Dffr/NiNGf1J0K5oDoA7ijcd+bgNl4ZW51VC6qxPew+CTCCMqj8xCFhb7B34QD+W4omj/RoPAlV+MYLLqI+V2p0NI2lajMvcdSqL/VYPAkH0+mS+yoFLyqcCDciYj8nxVL2NGbVYtY3tKi/6TTfRWPlFD4PooJBZxuxJrGzk6SBT9MlSO+0ATmgeeQ3zvoJtGd9tCRmYfM1ehka+Pccmsn/2zBw0fMlvD6h65n5y+jc2CpQqd04jcQsHmTRSPE8oXwZbTz9jYFXKECC6ZoOkSpnPnNgvEvBuBrUX8yxKT0REswAKOBdzDzSzN++ZWwTq4slexHzeT4k5VnVwvipFMwKjfX+7Kdrj1aF0FYLkHRaZPMGhmhammm/cw7Ctb/6SVgR6vu5TbwLyr0DV8VWv/vSlOT90IIUHGLEoRCM9b1rYwBxuV24BiNgZZ2jf8phACWcvTOEW9Koohi4RI5mYfteYNeEI5CEP9NzmT/fP/kXXuj1nhQjjw31Qe0MUcbjvJE/AObFcS4EhsRRqOmd/3ZLw4y/l8gxu7FEFooIWCfSGr58hFUEgqIgdpW2jMxLlbmyEjM9aIqNHhg3aAgzIyO3tGzYfDPTCb3h5jaxKWLksYQsM1UCkqg1VPw+X+FDUPXwV/3/oNT47dGSgcr5fDjtxH+WSt0zm/NSXgnDz0U8UqJ6m5OsR0uJTUCSXC4GkLyssv8/NfHz7QHvXszD0D47oNUxcZ2cr26tvwef2IQ4982nLGrj8n5M0++++DbBz4cX077MbzwTV8x+Z5XU/0Fc4FF7/+q/eanPh67nVNVf2r96NyyylXGQ2Q01n6GpYE6Vr+lJFVmx85jzqIJfdlI/PPoXl84OLXpf6oCZ5KUs/g8mzatKfj5H6AeR0GRIONYqA1YnQgmWBB8FS7CVyIv28x7kjOcGLsNgy/Dwgc3oixaPkyNagFkzjmOi4Lh8/lfx3gfooW9m6Z3jD3AApuYiMlsG6kcQfjk+4ZehedfAwZdTwFjGwWrMLTDXGBDBIyzpJJVM35m/9kD8I1ORDc5T1GyEpirGrMf453/C6aHfby0c/z+GkVUOAquse3xe6rKujVT6NuB9wgL09pXiBLN+dvOqm7kfdLKzMNV/J3S1PiLogccinnVUxv8WikHi2zcar3MC/C+GhHC8eOccgetWXhUaG4Cd/4ktO4b9u8e+2GcqdXHnv7hP4db/A+gSNRz7Tuag0UWBOFzZ3aPY6MaDnMxriAdKanF0tba5h8pmOz9mEz/MOhGJlyQfpB4iL4e+pt9AxfEAmYGLCDTA37whLfxeHPv4My63PHeg+gUcHrKfan4Q05vvbK1+/bObLybVbLf/PRrwpe9+SIIgY249N8QvndzbWcz0tJFNhaHRqRZF0dHr0eQxp9gNyaMz9XtELWeBe06xERhn9uuHQ/h8VuQR79V6L9vV2gGb8UrvQN8exemcTzmheV9NpeDtwBxJTYeM69VZMJz2DsZ+0YUy+XgJJCPrPmX8M6lZSN2cKkWJye+jmC093rZ7Psj7OgZaIRGxZMA4UuGkgMDvwg94SIoblSM7gO1U0hNgc4eAwvaB4CDWCLE0jBuSPy7cmQMEG7EWP2avC18ad/O0R8hL29nls6kyGVcmrxnsqd/8K2guY9HikfEABJVaxYza4+GJf1u6/vvhkX8bbT2Wi8IbsnY3K79U2IZs1x+ZhOiz3uyq08Oy8Ewrlxo7P2XoIx+gQYeHWhCVET4jEYSp5qhH5SfxojOZXJjpGw0UsgCed167sAvY+xWDInfi+etAZ8RZWSB++ZeogWKXRtEwcii3ReARC6YCfx9oLfb0CVvgyo5jkw/wK7kT2Km4nRT+mnU38OZmWxxxnscCtNxqDvr1khfmduWVPxOWQPoJr7MP9nsPBPo3Bsh1EjnqgYVZnPGmjx0DBoHKWupqyibloFKPn3dr2+aefW2yQFqdJWEMd+M3Z4eba1SsdkvRJWfAEL4ajDEreA/XDBhsfNUydydRQOT2C1jix7PzuaMROLTKgFAl1wSKlm6BYwHRc8S7PIbhj6JdSPeDOwWY5W40pygIHYkKghjj9IzegzkAs82lMBaYeiHM8V/Kk5NvCO6lQW6kmJrtJ0WsKsE3L9bMrS+ITT/CnX8nSXgFtMblRfBixsYYPGKJ8A8HgKlwT1tnwKMM5A6q0Adx0C3PxnVOBX49nCZSFl72u16QFwooJLQkGuJ++s8B3gIdJ7zESV/s4yruvHk6nxL/84gMZTLDRfwdr8tRMH56FyxrvHE9jp649K0wIL0Jn2VHryQfxJHqzfydD6XCk4S45F1YMXUAm4EYXMccpMsOfYrTqs5d8dsYGFSxw5woA9+JB/N48iVPae49v6UevCRUStmwoI58ZJ/vP/R1+Hcp/9z8z+vunT9R8pm79oAwpcopDmxM4hRNT01fhmtCLgjXwqrZLFCmGVJeeBsZTi12YGIExkEzsNKWPidI9siU+MSapEPqtxG7KQ1GNd8C8Y1j4MwuXQJwoRlxUwJ8oLmWEVZ4bWkyLFeXIWpEJRL7ytNTfwpfjPxfl7rdAohfMn4TXFq/F1wR54C3H5hkbjF9EarrozGsX15+M+OBdM+lvo7k2u0I0v3C2cEX0ZLgTYXJ8BYNNuRofCHvHpDsZXCl0+jUMfwx/To6M35vsHXoa9yqUr2LacEME/yRHAcvVHYOlcEoSJQPE/Bt1hFHLcvkFxf5bOS0vQChXX2UkxVna3F3KdzsQ0K3/m6vOsRlb4gPYTn5n7kTLxWltyEP/Hvw3JHd1dfn/udv6vPxWXMPVf9u/oefudjKIQrwmU6NNPwjpv1OGdeOXr5jN0+WbJ0t3VH8mGRSEcsnnbchZi18B0wRHY8WnNLSSyTASzUdkkJFMZgeBDLTfvE5QkjRPFtT2iTm3rF8eSwXL4W2NESp6VPGllsipkj8YsxJJ5ktjzO/cTnyQ8sGHMBi0BcwYCnqH48v5T64PamJtaFdTbTU2OvC/2Z/4xwI80tpp7Ei3RGrBAcSNUPAVR0tc79MLCK9OcEDRVCqQd+N5rYvyl8LVzgl8vcesYGtMLyra5ZNPxR2j3xReuHb6GnBIn0sBR+w0Ji/FgW+yqEcjP7alVZERPFM7o+CfqpbIVjt05HJLkv5oNBL7wrtpEdLPrM/R2fj4/V1+d+5+/qc7Xu4bnqPNX3xOflyHqB6L1VIbQNjGu4FW8c8eJSFyUqC5FLEgEkjAD9WsQQOcbEN7fUxHdH7MnsmviJy5PjUuu4yPsxxBArMLvHL4UC8xlgR0FAQbIUplirPsSxVuJ5YZoQvlmMIf8JBNs2nAPWshYwr6Utga5i5WXiZ7E8K6Z1ifISc4rF1heWm9AYBQmFytwPz5MG58MSl+omBh5mxW0blH9pevf4xxoOSKv7iAUyxJbw7rFPoa++DnWh2sV2HTIEtkAJ9S6Rt/HTxL56SFlLwb5e3dt6nSBp6gwCYK4Whi8MnrD0hkdmno1go5vQCWQmc2dqtJSnxkIYrYE193K4BD8GZk7mxU7YrI69lBqm917xdjhhUpoaexOMrm2wTOjCI1NcqichSbspYEMnfIMrMJzwx/jN9yZCOUkBncnD+AiHG4TYG+BBuBIWJQSbTSvNUakq4t3mYR3Cx+dfxEUy2ip84xcVBVGKJYyxZ9TnaWBHxY/0lkaFK675sjqqAO7M6wTjoPCFpzY8+IsP+xu/gC9gthc02+Jpb+uqBAnG5y6Ht+7tUgEyHCeEtWPP+0Yk2I6Cw8O46xUYU7sUwUBP0h2Mc6QLWnatSLHwxc5LFL60fEWoUVjwk/JUEcLY8nH89xD38UYIE6wBLcKklUF7jeLCdwglB1Z6ENyDmKVBrPP8dQm4ojDsRIrc0Qz8grY3gP56e+RFoIXZmTp1AocOPlMFcPvBp+WL8A4Rvm+A8P38ZnMHLEXb3cK3gqMIEtDV1gwYzEcxwehsMJw7nVsVbEc6dpda+ZU2tuwLhawsWQnsrgSrXxsAAAwRSURBVM2a7Ca4CL/krLrKimPCyJtUA7FwIeSrhC8t39S6nedpttBcSFc+hkA+hwC+syCIGYuAMVqhOQjijtEc35dsjwiXM1aVKv81lNNzuKpXy6Kd50Gp5unIHX1wauwhKH7Px1So9wMzTMqrbN7QTHqrWYWVfFIFcHvfPoi5YvlS+H5hwEzmR81zl5u2CcYOpohpD6UHJsbAcDYjyPT3IVsOYgI9lA0Zc+0kU2zvW2/saaGsrATsOBcV2HFq12sgVKYEO25l6Kxh0sxSLNTY8sWY7yGWrwjlxqqcityMjpYlK4u7J6e4mAWE8DthDe+DgkEPTOSWbpsg5vvhuudZeW9BcJcXlF+M9/kuQYvj/q0OuEr6WmgJR3EIsIb/KIAKiOlV3xHFD/PjUAwVw+XGo5Ki09J8KoBbCu8hhVe7nSvCd9IMLF/CjrRrogCG+AG4uTYiwOdj+Fl21okwRbY/1rKXIlD4mOWThDnTFbw1g3G6a8C4NyHQ6LchiB9wjFHG19le4ucs5+QCuYbly2eJ5dvd74C4xUFtu8b+NlsONsKL8A+AptRimiNuxBXvA0KeFiSVzTDYY8v+2/D+zj24e/IWGe9lgJIM1yB3WpKrj2yyMDM1dicVGIsAMXiv7osEMeM5ovbJsbvpJCW4qwBuz4ug5Ru5nQ+8npYv3c4QvhyjWt6E7Ma3ZNF2urnAiC4HUzqTrjhYJ3vRubkIArRsCcWMO3gslPl7eeOzIP3RtYoPp6eA+RV3T3ykaA6eiY0c3mz88n8TM1h3XHSD1h3H7arxizGk4kcBzWuYGuKENe7LwiuxrQuinVHtBlMs3OBFeObByUdBc78BRzRozv/w4TR3CGZUBOvRXCxoiSnzxzjzdXjOS4EgMFi8eE+/ViwEZyJA7CppARUD1x/4jDSmQOrnFBjLADFgN8hxdbGIZ9sXy43q9sc0toL7a+OvlO4FTa1FgAwwCrgqQvhu+jfndj501avWVqHjpYfibostk5GRKdToXdgv9YqecOZV2Gz99cDohRAka+Cyw6oEuOpW02HFyazYudPSsTkPFP1G5oKyfq1Pjml7cOnTbVnEKiefxkM/nds4cHbGN69GsNYlWGJmGPgVIAQcfoQrXlwkPhJDLrkJiLGORLTIhli+9YRO69vYiifEXgRsnDA9MrIHj3i36X/+n/T4B1+NaX9c+OZFjuaIWYSXw2ohmqPwYYQ6jjJ9Rw4AlHh/H/OGb8DZzyGS/OZKk9wKVDOps3orFZzzxSkwbqcjYCjj6mhTbuPZP+mVg1/EMgaXoP39wA5LpfHeQ7CLBfGcQjvyk+8Ry5VhyAtrqnakBnUeqgK4DkBLvEzhWx1wJcI3snyXWHQX3h5bJoyy5W4yIyNPQZh8Ci351Kozzzy5PJN9MezglyBW9Fx06j6cP5GBK2R2tI8dp+OxXYl9Vh6Mo/uOpfaw+YEs0XhMu2oRPSeIxgw9uFjpwvS5ST3Mr3twfVvPxqH1WEMb2zth/A4Rrajvs3D+BHzWoA2c6+asZMqNMHgPFtn4oLhqR7aTSaWSOaFeTUjwIIywmArNPX0ozWVegkUgXwKMngMYNiDjWggWCtcqmpuFR+SzUw4xXSf8X+S/Hz9vww3fni7vu808+CCKjxIVzpGR+L3FZ7vl6JRmCrAKvd1zOyqPz9Z39fbveB6WID8f/fL5oB7QmzkN/RTLdUK7wzzquNfM9p/2N1sWM4/6L9w9OboqHN9pf13me+IsTvPlaOv5aC3oPNaCDpa8FnRba17jYXDPxJYv3c6b/m2zCXOjxgod1Mi/Ek9ZuFfhllsPIUB3a1Vad87R+Wx4KpYJOgW755wA/RUCD6t2UpPFiaqc7f1qLWJUwl4wnfs4NouHsy6zHLqttYFQGbiX+9CSpubWwZp15xzVY4tHBblsL9Za5HSmvA2yB0pT90xG1Vx83Z1wae9uSM3Bdn6aO33omHzeO8Ua/1QAcwKELZUsRlI7mvPsfpx7AquUP0rhO13a9/AhApf143DBmjUuIKw59U1RKaC3zXu4heehPAxt7n1y+mR4Vk7xw+BkLOJ+HAA7UvppjF0nWlF5tmezQfCZZx6YeAzVgK4kXrVO1OiwZ3aOkR1WFZ5wAvik/K6zwOZiJkHGkrJ61qx89ckqy9cJX7qdV6zlW43MfN/J0Pfu9czatUHXuOo6KnwPAdLCSskIfj09jKKmMkPLdr5EJsR+NVdoz5f/8PPdK4Bn29IcmnMCnaXWx3322d39jcFa9Kh0W5sXr3C26H2lzAW9VRgCdg0sccFftLmKQdCH30HLZ8EXwLoxYWTJhGUMs+XcPF8Vvg6XBH8r7mnJSwGBzrLVuYwS3N72LCPccHyO1d72SlQeONfiIqOZxbCSLf6SmnrHFerMcSk0594/+72bNtaZFnTqqQzWihW8iNa28pji/jpCpTTi01LTVPxJmQCWzQrsQ0U7dXJ25y0Zc8KLffNDWpMRM3HvOBXIHVqJSsU8sxoRq6DN8MDr4Hb+YuR2ZrSzpuQIRJ17u3Hjd8lv1JyCgBMM8hUYakqCgNJcEpQOzxPRWkRnI4dn0DPzI0DBlrK03dWpnH0jhO+dUOTh6pCoB9Qz5iupO6JCrBOnJRwYx1ZOF1UJ30PHS1KGtlZHEVAEFAFFoDMIpMwCJgiXweK9OvOIWf89iLPNJ+anBhFA4lmTEwnXGZjqPbWELVOwg5stFR8uPnuHyx1mNeCqHm56XRFQBBSBlYtACgUwXwaFMKdNWP+xUv9E970ezhNdLms7dx/6WmNFQBFQBLoBgZQKYELH1Xu2wR19qYu26wY0pY6bOf0IH02KgCKgCCgCisD8CKRYALPS2xAYwY8mRUARUAQUAUVgeSGQwiCs5QWwtkYRUAQUAUVAEaiFgArgWqjoOUVAEVAEFAFFoMUIqABuMcBavCKgCCgCioAiUAsBFcC1UNFzioAioAgoAopAixFQAdxigLV4RUARUAQUAUWgFgIqgGuhoucUAUVAEVAEFIEWI6ACuMUAa/GKgCKgCCgCikAtBFQA10JFzykCioAioAgoAi1GQAVwiwHW4hUBRUARUAQUgVoIqACuhYqeUwQUAUVAEVAEWoyACuAWA6zFKwKKgCKgCCgCtRBQAVwLFT2nCCgCioAioAi0GAEVwC0GWItXBBQBRUARUARqIaACuBYqek4RUAQUAUVAEWgxAiqAWwywFq8IKAKKgCKgCNRCQAVwLVT0nCKgCCgCioAi0GIEVAC3GGAtXhFQBBQBRUARqIWACuBaqOg5RUARUAQUAUWgxQioAG4xwFq8IqAIKAKKgCJQCwEVwLVQ0XOKgCKgCCgCikCLEVAB3GKAtXhFQBFQBBQBRaAWAiqAa6Gi5xQBRUARUAQUgRYjoAK4xQBr8YqAIqAIKAKKQC0EVADXQkXPKQKKgCKgCCgCLUZABXCLAdbiFQFFQBFQBBSBWgioAK6Fip5TBBQBRUARUARajIAK4BYDrMUrAoqAIqAIKAK1EFABXAsVPacIKAKKgCKgCLQYARXALQZYi1cEFAFFQBFQBGohoAK4Fip6ThFQBBQBRUARaDECKoBbDLAWrwgoAoqAIqAI1EJABXAtVPScIqAIKAKKgCLQYgRUALcYYC1eEVAEFAFFQBGohUC21kk9pwgoAorAIhAIE9yTJE+CYjSLItD9CKgA7v53qC1QBDqIQGjdwy2O8ff5qsOsoXrd5oNHz684BFQAr7hXrg1WBJqJgIVFS6M29PEHEpa/maqFseRhPvKbslzWP4qAIsAOo0kRUAQUgYYREHPWDAyszhfN6TaT8cOwWugeWp61FpdDHGxY9A88aKamisjhyjg0q/5SBBQBRUARUAQUgToILEWBX8q9daqllxWB7kBAO0F3vCetpSKQVgSs2bIl01DlRkboro5c1Q3dqZkVAUVAEVAEFAFFQBFQBBQBRUARUAQUAUVAEVAEFAFFQBFQBBQBRUARUAQUAUVAEVAEFAFFQBFQBBQBRUARUAQUAUVAEVAEFAFFQBFQBBQBRUARUAQUAUVAEVAEFAFFQBFQBBQBRUARUAQUAUVAEVAEFAFFQBFQBBQBRUARUAQUAUVAEVAEFAFFQBFQBBQBRUAR6EYE/j+m8VXNlZj5GQAAAABJRU5ErkJggg==" alt="Aqua logo">
 `)
-//line pkg/report/templates/default.qtpl:355
+//line pkg/report/templates/default.qtpl:356
 }
 
-//line pkg/report/templates/default.qtpl:355
+//line pkg/report/templates/default.qtpl:356
 func writeaquaLogoImg(qq422016 qtio422016.Writer) {
-//line pkg/report/templates/default.qtpl:355
+//line pkg/report/templates/default.qtpl:356
 	qw422016 := qt422016.AcquireWriter(qq422016)
-//line pkg/report/templates/default.qtpl:355
+//line pkg/report/templates/default.qtpl:356
 	streamaquaLogoImg(qw422016)
-//line pkg/report/templates/default.qtpl:355
+//line pkg/report/templates/default.qtpl:356
 	qt422016.ReleaseWriter(qw422016)
-//line pkg/report/templates/default.qtpl:355
+//line pkg/report/templates/default.qtpl:356
 }
 
-//line pkg/report/templates/default.qtpl:355
+//line pkg/report/templates/default.qtpl:356
 func aquaLogoImg() string {
-//line pkg/report/templates/default.qtpl:355
+//line pkg/report/templates/default.qtpl:356
 	qb422016 := qt422016.AcquireByteBuffer()
-//line pkg/report/templates/default.qtpl:355
+//line pkg/report/templates/default.qtpl:356
 	writeaquaLogoImg(qb422016)
-//line pkg/report/templates/default.qtpl:355
+//line pkg/report/templates/default.qtpl:356
 	qs422016 := string(qb422016.B)
-//line pkg/report/templates/default.qtpl:355
+//line pkg/report/templates/default.qtpl:356
 	qt422016.ReleaseByteBuffer(qb422016)
-//line pkg/report/templates/default.qtpl:355
+//line pkg/report/templates/default.qtpl:356
 	return qs422016
-//line pkg/report/templates/default.qtpl:355
+//line pkg/report/templates/default.qtpl:356
 }


Test patch:
diff --git a/pkg/kubebench/io_test.go b/pkg/kubebench/io_test.go
new file mode 100644
index 0000000..7659ce2
--- /dev/null
+++ b/pkg/kubebench/io_test.go
@@ -0,0 +1,245 @@
+package kubebench_test
+
+import (
+	"context"
+	"testing"
+
+	"github.com/aquasecurity/starboard/pkg/apis/aquasecurity/v1alpha1"
+	"github.com/aquasecurity/starboard/pkg/kube"
+	"github.com/aquasecurity/starboard/pkg/kubebench"
+	"github.com/aquasecurity/starboard/pkg/starboard"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/types"
+	"sigs.k8s.io/controller-runtime/pkg/client/fake"
+)
+
+func TestReadWriter(t *testing.T) {
+	kubernetesScheme := starboard.NewScheme()
+
+	t.Run("Should create CISKubeBenchReport", func(t *testing.T) {
+		client := fake.NewClientBuilder().WithScheme(kubernetesScheme).Build()
+		instance := kubebench.NewReadWriter(client)
+		err := instance.Write(context.Background(), v1alpha1.CISKubeBenchReport{
+			ObjectMeta: metav1.ObjectMeta{
+				Name: "control-plane",
+				Labels: map[string]string{
+					kube.LabelResourceKind: string(kube.KindNode),
+					kube.LabelResourceName: "control-plane",
+				},
+			},
+			Report: v1alpha1.CISKubeBenchOutput{
+				Scanner: v1alpha1.Scanner{
+					Vendor:  "Aqua Security",
+					Name:    "kube-bench",
+					Version: "0.5.1",
+				},
+				Summary: v1alpha1.CISKubeBenchSummary{
+					FailCount: 10,
+					WarnCount: 5,
+					InfoCount: 3,
+					PassCount: 2,
+				},
+			},
+		})
+		require.NoError(t, err)
+
+		found := &v1alpha1.CISKubeBenchReport{}
+		err = client.Get(context.Background(), types.NamespacedName{Name: "control-plane"}, found)
+		require.NoError(t, err)
+
+		assert.Equal(t, &v1alpha1.CISKubeBenchReport{
+			TypeMeta: metav1.TypeMeta{
+				APIVersion: "aquasecurity.github.io/v1alpha1",
+				Kind:       "CISKubeBenchReport",
+			},
+			ObjectMeta: metav1.ObjectMeta{
+				Name:            "control-plane",
+				ResourceVersion: "1",
+				Labels: map[string]string{
+					kube.LabelResourceKind: string(kube.KindNode),
+					kube.LabelResourceName: "control-plane",
+				},
+			},
+			Report: v1alpha1.CISKubeBenchOutput{
+				Scanner: v1alpha1.Scanner{
+					Vendor:  "Aqua Security",
+					Name:    "kube-bench",
+					Version: "0.5.1",
+				},
+				Summary: v1alpha1.CISKubeBenchSummary{
+					FailCount: 10,
+					WarnCount: 5,
+					InfoCount: 3,
+					PassCount: 2,
+				},
+			},
+		}, found)
+	})
+
+	t.Run("Should update CISKubeBenchReport", func(t *testing.T) {
+		client := fake.NewClientBuilder().
+			WithScheme(kubernetesScheme).
+			WithObjects(&v1alpha1.CISKubeBenchReport{
+				ObjectMeta: metav1.ObjectMeta{
+					Name: "control-plane",
+					Labels: map[string]string{
+						kube.LabelResourceKind: string(kube.KindNode),
+						kube.LabelResourceName: "control-plane",
+					},
+				},
+				Report: v1alpha1.CISKubeBenchOutput{
+					Scanner: v1alpha1.Scanner{
+						Vendor:  "Aqua Security",
+						Name:    "kube-bench",
+						Version: "0.5.1",
+					},
+					Summary: v1alpha1.CISKubeBenchSummary{
+						FailCount: 10,
+						WarnCount: 5,
+						InfoCount: 3,
+						PassCount: 2,
+					},
+				},
+			}).
+			Build()
+		instance := kubebench.NewReadWriter(client)
+		err := instance.Write(context.Background(), v1alpha1.CISKubeBenchReport{
+			ObjectMeta: metav1.ObjectMeta{
+				Name: "control-plane",
+				Labels: map[string]string{
+					kube.LabelResourceKind: string(kube.KindNode),
+					kube.LabelResourceName: "control-plane",
+				},
+			},
+			Report: v1alpha1.CISKubeBenchOutput{
+				Scanner: v1alpha1.Scanner{
+					Vendor:  "Aqua Security",
+					Name:    "kube-bench",
+					Version: "0.5.1",
+				},
+				Summary: v1alpha1.CISKubeBenchSummary{
+					FailCount: 20,
+					WarnCount: 10,
+					InfoCount: 6,
+					PassCount: 4,
+				},
+			},
+		})
+		require.NoError(t, err)
+
+		found := &v1alpha1.CISKubeBenchReport{}
+		err = client.Get(context.Background(), types.NamespacedName{Name: "control-plane"}, found)
+		require.NoError(t, err)
+
+		assert.Equal(t, &v1alpha1.CISKubeBenchReport{
+			TypeMeta: metav1.TypeMeta{
+				APIVersion: "aquasecurity.github.io/v1alpha1",
+				Kind:       "CISKubeBenchReport",
+			},
+			ObjectMeta: metav1.ObjectMeta{
+				Name: "control-plane",
+				Labels: map[string]string{
+					kube.LabelResourceKind: string(kube.KindNode),
+					kube.LabelResourceName: "control-plane",
+				},
+				ResourceVersion: "1",
+			},
+			Report: v1alpha1.CISKubeBenchOutput{
+				Scanner: v1alpha1.Scanner{
+					Vendor:  "Aqua Security",
+					Name:    "kube-bench",
+					Version: "0.5.1",
+				},
+				Summary: v1alpha1.CISKubeBenchSummary{
+					FailCount: 20,
+					WarnCount: 10,
+					InfoCount: 6,
+					PassCount: 4,
+				},
+			},
+		}, found)
+	})
+
+	t.Run("Should find CISKubeBenchReport by owner node", func(t *testing.T) {
+		client := fake.NewClientBuilder().
+			WithScheme(kubernetesScheme).
+			WithObjects(&v1alpha1.CISKubeBenchReport{
+				ObjectMeta: metav1.ObjectMeta{
+					Name: "control-plane",
+					Labels: map[string]string{
+						kube.LabelResourceKind: string(kube.KindNode),
+						kube.LabelResourceName: "control-plane",
+					},
+				},
+				Report: v1alpha1.CISKubeBenchOutput{
+					Scanner: v1alpha1.Scanner{
+						Vendor:  "Aqua Security",
+						Name:    "kube-bench",
+						Version: "0.5.1",
+					},
+					Summary: v1alpha1.CISKubeBenchSummary{
+						FailCount: 10,
+						WarnCount: 5,
+						InfoCount: 3,
+						PassCount: 2,
+					},
+				},
+			}, &v1alpha1.CISKubeBenchReport{
+				ObjectMeta: metav1.ObjectMeta{
+					Name: "worker",
+					Labels: map[string]string{
+						kube.LabelResourceKind: string(kube.KindNode),
+						kube.LabelResourceName: "worker",
+					},
+				},
+				Report: v1alpha1.CISKubeBenchOutput{
+					Scanner: v1alpha1.Scanner{
+						Vendor:  "Aqua Security",
+						Name:    "kube-bench",
+						Version: "0.5.1",
+					},
+					Summary: v1alpha1.CISKubeBenchSummary{
+						FailCount: 20,
+						WarnCount: 10,
+						InfoCount: 6,
+						PassCount: 4,
+					},
+				},
+			}).
+			Build()
+		instance := kubebench.NewReadWriter(client)
+
+		found, err := instance.FindByOwner(context.Background(), kube.Object{Name: "worker"})
+		require.NoError(t, err)
+
+		assert.Equal(t, &v1alpha1.CISKubeBenchReport{
+			TypeMeta: metav1.TypeMeta{
+				APIVersion: "aquasecurity.github.io/v1alpha1",
+				Kind:       "CISKubeBenchReport",
+			},
+			ObjectMeta: metav1.ObjectMeta{
+				Name: "worker",
+				Labels: map[string]string{
+					kube.LabelResourceKind: string(kube.KindNode),
+					kube.LabelResourceName: "worker",
+				},
+			},
+			Report: v1alpha1.CISKubeBenchOutput{
+				Scanner: v1alpha1.Scanner{
+					Vendor:  "Aqua Security",
+					Name:    "kube-bench",
+					Version: "0.5.1",
+				},
+				Summary: v1alpha1.CISKubeBenchSummary{
+					FailCount: 20,
+					WarnCount: 10,
+					InfoCount: 6,
+					PassCount: 4,
+				},
+			},
+		}, found)
+	})
+
+}
diff --git a/pkg/kubebench/writer_test.go b/pkg/kubebench/writer_test.go
deleted file mode 100644
index ccf9ebe..0000000
--- a/pkg/kubebench/writer_test.go
+++ /dev/null
@@ -1,143 +0,0 @@
-package kubebench_test
-
-import (
-	"context"
-	"testing"
-
-	"github.com/aquasecurity/starboard/pkg/apis/aquasecurity/v1alpha1"
-	"github.com/aquasecurity/starboard/pkg/generated/clientset/versioned"
-	"github.com/aquasecurity/starboard/pkg/generated/clientset/versioned/fake"
-	"github.com/aquasecurity/starboard/pkg/kube"
-	"github.com/aquasecurity/starboard/pkg/kubebench"
-	"github.com/aquasecurity/starboard/pkg/starboard"
-	. "github.com/onsi/ginkgo"
-	. "github.com/onsi/gomega"
-	. "github.com/onsi/gomega/gstruct"
-	corev1 "k8s.io/api/core/v1"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"k8s.io/apimachinery/pkg/labels"
-	"k8s.io/apimachinery/pkg/runtime"
-)
-
-func TestReadWriter(t *testing.T) {
-	RegisterFailHandler(Fail)
-	RunSpecs(t, "ReadWriter Suite")
-}
-
-var _ = Describe("ReadWriter", func() {
-
-	var (
-		workerNodeName = "worker-node"
-		workerNode     = &corev1.Node{
-			ObjectMeta: metav1.ObjectMeta{
-				Name: workerNodeName,
-			},
-		}
-		workerNodeReport = v1alpha1.CISKubeBenchOutput{
-			Scanner: v1alpha1.Scanner{
-				Name: "worker-node-report",
-			},
-		}
-	)
-
-	var (
-		objects   []runtime.Object
-		clientset versioned.Interface
-		rw        kubebench.ReadWriter
-	)
-
-	BeforeEach(func() {
-		objects = []runtime.Object{}
-		clientset = fake.NewSimpleClientset(objects...)
-		rw = kubebench.NewReadWriter(starboard.NewScheme(), clientset)
-	})
-
-	Describe("Writing report", func() {
-
-		Context("when report does not exist", func() {
-
-			It("should create a report", func() {
-				err := rw.Write(context.TODO(), workerNodeReport, workerNode)
-				Expect(err).ToNot(HaveOccurred())
-
-				report, err := clientset.AquasecurityV1alpha1().CISKubeBenchReports().
-					Get(context.TODO(), workerNodeName, metav1.GetOptions{})
-
-				Expect(err).ToNot(HaveOccurred())
-				Expect(report.Labels).To(MatchAllKeys(Keys{
-					kube.LabelResourceKind: Equal(string(kube.KindNode)),
-					kube.LabelResourceName: Equal(workerNodeName),
-				}))
-			})
-
-		})
-
-		Context("when report already exists", func() {
-
-			BeforeEach(func() {
-				err := rw.Write(context.TODO(), workerNodeReport, workerNode)
-				Expect(err).ToNot(HaveOccurred())
-			})
-
-			It("should update a report", func() {
-				err := rw.Write(context.TODO(), workerNodeReport, workerNode)
-				Expect(err).ToNot(HaveOccurred())
-
-				report, err := clientset.AquasecurityV1alpha1().CISKubeBenchReports().
-					Get(context.TODO(), workerNodeName, metav1.GetOptions{})
-				Expect(err).ToNot(HaveOccurred())
-
-				Expect(report.Labels).To(MatchAllKeys(Keys{
-					kube.LabelResourceKind: Equal(string(kube.KindNode)),
-					kube.LabelResourceName: Equal(workerNodeName),
-				}))
-
-				reportList, err := clientset.AquasecurityV1alpha1().CISKubeBenchReports().
-					List(context.TODO(), metav1.ListOptions{
-						LabelSelector: labels.Set{
-							kube.LabelResourceKind: string(kube.KindNode),
-							kube.LabelResourceName: workerNodeName,
-						}.String(),
-					})
-				Expect(err).ToNot(HaveOccurred())
-				Expect(reportList.Items).To(HaveLen(1))
-			})
-		})
-
-	})
-
-	Describe("Reading report", func() {
-
-		Context("when report does not exist", func() {
-
-			It("should return error not found", func() {
-				_, err := rw.Read(context.TODO(), kube.Object{
-					Kind: kube.KindNode,
-					Name: workerNodeName,
-				})
-				Expect(err).To(HaveOccurred())
-				Expect(err.Error()).To(Equal("ciskubebenchreports.aquasecurity.github.io \"worker-node\" not found"))
-			})
-
-		})
-
-		Context("when report exists", func() {
-
-			BeforeEach(func() {
-				err := rw.Write(context.TODO(), workerNodeReport, workerNode)
-				Expect(err).ToNot(HaveOccurred())
-			})
-
-			It("should return report", func() {
-				report, err := rw.Read(context.TODO(), kube.Object{
-					Kind: kube.KindNode,
-					Name: workerNodeName,
-				})
-				Expect(err).ToNot(HaveOccurred())
-				Expect(report).To(Equal(workerNodeReport))
-			})
-
-		})
-	})
-
-})