{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "29b239f0",
   "metadata": {},
   "source": [
    "# Argument Intent Linter"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3e6ef992",
   "metadata": {},
   "source": [
    "The previous notebooks have all focused on using Loki to perform code transformations. Loki can also be used as a Fortran linter. In this notebook, we will use Loki to check whether the declared intent of a subroutine argument is consistent with how that variable is used.\n",
    "\n",
    "For brevity, only the core functionality of a subroutine dummy argument intent-linter is developed here.\n",
    "\n",
    "Let us start by first examining the sample subroutine that we will use to illustrate this notebook:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "65da8ec9",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "MODULE kernel_mod\n",
      "  USE parkind1, ONLY: jpim, jprb\n",
      "  IMPLICIT NONE\n",
      "  CONTAINS\n",
      "  SUBROUTINE some_kernel (n, vout, var_out, var_in, var_inout, b, l, h, y)\n",
      "    \n",
      "    INTEGER(KIND=jpim), INTENT(IN) :: n, l, b\n",
      "    INTEGER(KIND=jpim), INTENT(IN) :: h\n",
      "    REAL(KIND=jprb), INTENT(IN) :: var_in(n)\n",
      "    REAL(KIND=jprb), INTENT(INOUT) :: var_out(n)\n",
      "    REAL(KIND=jprb), INTENT(INOUT) :: var_inout(n)\n",
      "    REAL(KIND=jprb), INTENT(INOUT) :: vout(n)\n",
      "    REAL(KIND=jprb), INTENT(INOUT) :: y(:)\n",
      "    \n",
      "  END SUBROUTINE some_kernel\n",
      "END MODULE kernel_mod\n",
      "\n",
      "SUBROUTINE intent_test (m, n, var_in, var_out, var_inout, tendency_loc)\n",
      "  USE parkind1, ONLY: jpim, jprb\n",
      "  USE kernel_mod, ONLY: some_kernel\n",
      "  USE yoecldp, ONLY: nclv\n",
      "  IMPLICIT NONE\n",
      "  \n",
      "  INTEGER(KIND=jpim), INTENT(IN) :: m, n\n",
      "  INTEGER(KIND=jpim) :: i, j, k, h, l\n",
      "  REAL(KIND=jprb), INTENT(IN) :: var_in(n, n, n)\n",
      "  REAL(KIND=jprb), TARGET, INTENT(OUT) :: var_out(n, n, n)\n",
      "  REAL(KIND=jprb), INTENT(INOUT) :: var_inout(n, n, n)\n",
      "  REAL(KIND=jprb), ALLOCATABLE :: x(:), y(:)\n",
      "  REAL(KIND=jprb), POINTER :: vout(n)\n",
      "  TYPE(state_type), INTENT(OUT) :: tendency_loc\n",
      "  \n",
      "  ALLOCATE (x(n))\n",
      "  ASSOCIATE (mtmp=>m)\n",
      "  ALLOCATE (y(mtmp))\n",
      "  END ASSOCIATE\n",
      "  \n",
      "  ASSOCIATE (mtmp=>n)\n",
      "  DO k=1,mtmp\n",
      "    DO j=1,mtmp\n",
      "      DO i=1,mtmp\n",
      "        var_out(i, j, k) = 2._jprb\n",
      "      END DO\n",
      "      \n",
      "      ASSOCIATE (mbuf=>mtmp)\n",
      "      var_out(m:mbuf, j, k) = var_in(m:mbuf, j, k) + var_inout(m:mbuf, j, k) + var_out(m:mbuf, j, k)\n",
      "      END ASSOCIATE\n",
      "      \n",
      "      vout => var_out(:, j, k)\n",
      "      \n",
      "      ASSOCIATE (vin=>mtmp)\n",
      "      CALL some_kernel(vin, vout, vout, var_in(:, j, k), var_inout(:, j, k), 1, h=vin, l=5, y=y)\n",
      "      END ASSOCIATE\n",
      "      \n",
      "      NULLIFY (vout)\n",
      "      \n",
      "      ASSOCIATE (vout=>tendency_loc%cld(:, j, k))\n",
      "      \n",
      "      ASSOCIATE (vin=>var_in(:, j, k))\n",
      "      CALL some_kernel(mtmp, vout, var_out(:, j, k), vin, var_inout(:, j, k), 1, h=mtmp, l=5, y=y)\n",
      "      END ASSOCIATE\n",
      "      \n",
      "      END ASSOCIATE\n",
      "      \n",
      "      DO i=1,mtmp\n",
      "        var_inout(i, j, k) = var_out(i, j, k)\n",
      "      END DO\n",
      "    END DO\n",
      "  END DO\n",
      "  END ASSOCIATE\n",
      "  \n",
      "  DEALLOCATE (x)\n",
      "  DEALLOCATE (y)\n",
      "  \n",
      "END SUBROUTINE intent_test\n"
     ]
    }
   ],
   "source": [
    "from loki import Sourcefile\n",
    "\n",
    "source = Sourcefile.from_file('src/intent_test.F90')\n",
    "print(source.to_fortran())\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b365ec21",
   "metadata": {},
   "source": [
    "## Retrieving variable intent"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "71b72f2e",
   "metadata": {},
   "source": [
    "We can access all the variables declared in subroutine `intent_test` using the `variables` property of the [_Subroutine_](https://sites.ecmwf.int/docs/loki/main/loki.subroutine.html#loki.subroutine.Subroutine) object:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "0566471b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "vars:: m, n, i, j, k, h, l, var_in(n, n, n), var_out(n, n, n), var_inout(n, n, n), x(:), y(:), vout(n), tendency_loc\n"
     ]
    }
   ],
   "source": [
    "routine = source['intent_test']\n",
    "print('vars::', ', '.join([str(v) for v in routine.variables]))\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a6244a0f",
   "metadata": {},
   "source": [
    "In the Loki IR, variables are stored as symbols with base `class` [_MetaSymbol_](https://sites.ecmwf.int/docs/loki/main/loki.expression.symbols.html#loki.expression.symbols.MetaSymbol) and the `intent` of a variable is stored in the `property` [`MetaSymbol.type`](https://sites.ecmwf.int/docs/loki/main/loki.expression.symbols.html#loki.expression.symbols.MetaSymbol.type). To retrieve all variables with declared intent, we only need to look through the subroutine `arguments`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "3b251eb0",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "in:: m, n, var_in(n, n, n) out:: var_out(n, n, n), tendency_loc inout:: var_inout(n, n, n)\n"
     ]
    }
   ],
   "source": [
    "from collections import defaultdict\n",
    "\n",
    "intent_vars = defaultdict(list)\n",
    "for var in routine.arguments:\n",
    "    intent_vars[var.type.intent].append(var)\n",
    "\n",
    "in_vars = intent_vars['in']\n",
    "out_vars = intent_vars['out']\n",
    "inout_vars = intent_vars['inout']\n",
    "\n",
    "print('in::', ', '.join([str(v) for v in in_vars]), 'out::', ', '.join([str(v) for v in out_vars]), 'inout::', ','.join([str(v) for v in inout_vars]))\n",
    "assert all([len(in_vars) == 3, len(out_vars) == 2, len(inout_vars) == 1])\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d1732e23",
   "metadata": {},
   "source": [
    "## Separating variables from dimensions"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "82041e9c",
   "metadata": {},
   "source": [
    "In Loki, the most general way of retrieving the variables used in an expression or node is the [_FindVariables_](https://sites.ecmwf.int/docs/loki/main/loki.expression.expr_visitors.html#loki.expression.expr_visitors.FindVariables) visitor. In the IR nodes in the body of a subroutine, the `FindVariables` visitor will return variables that appear in their own right, as well as any variables used for array indexing. An example of this is seen when `FindVariables` is applied to an [_Allocation_](https://sites.ecmwf.int/docs/loki/main/loki.ir.html#loki.ir.Allocation):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "56c5c4e7",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x(n), n\n"
     ]
    }
   ],
   "source": [
    "from loki import FindNodes, FindVariables, Allocation\n",
    "\n",
    "alloc = FindNodes(Allocation).visit(routine.body)[0]\n",
    "alloc_vars = FindVariables().visit(alloc.variables)\n",
    "print(', '.join([str(v) for v in alloc_vars]))\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c2ffad04",
   "metadata": {},
   "source": [
    "Utilities to distingiush between variables and their dimensions can be constructed by wrapping small functions around `FindVariables`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "2a1de40b",
   "metadata": {},
   "outputs": [],
   "source": [
    "from loki import Array, flatten\n",
    "\n",
    "def findvarsnotdims(o, return_vars=True):\n",
    "    \"\"\"Return list of variables excluding any array dimensions.\"\"\"\n",
    "\n",
    "    dims = flatten([FindVariables().visit(var.dimensions) for var in FindVariables().visit(o) if isinstance(var, Array)])\n",
    "\n",
    "#   remove duplicates from dims\n",
    "    dims = list(set(dims))\n",
    "\n",
    "    if return_vars:\n",
    "        return [var for var in FindVariables().visit(o) if not var in dims]\n",
    "\n",
    "    return [var.name for var in FindVariables().visit(o) if not var in dims]\n",
    "\n",
    "def finddimsnotvars(o, return_vars=True):\n",
    "    \"\"\"Return list of all array dimensions.\"\"\"\n",
    "\n",
    "    dims = flatten([FindVariables().visit(var.dimensions) for var in FindVariables().visit(o) if isinstance(var, Array)])\n",
    "\n",
    "#   remove duplicates from dims\n",
    "    dims = list(set(dims))\n",
    "\n",
    "    if return_vars:\n",
    "        return dims\n",
    "\n",
    "    return [var.name for var in dims]\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "808792c4",
   "metadata": {},
   "source": [
    "A quick test reveals:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "09018be6",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "vars:['x']\n",
      "dims:['n']\n"
     ]
    }
   ],
   "source": [
    "print(f'vars:{findvarsnotdims(alloc.variables, return_vars=False)}')\n",
    "print(f'dims:{finddimsnotvars(alloc.variables, return_vars=False)}')\n",
    "\n",
    "assert len(findvarsnotdims(alloc.variables)) == 1\n",
    "assert len(finddimsnotvars(alloc.variables)) == 1\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c242a047",
   "metadata": {},
   "source": [
    "## Resolving associations"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bba91785",
   "metadata": {},
   "source": [
    "You may have noticed that `intent_test` contains several nested associations. The simplest way of dealing with these is to resolve all the associations before we begin linting the program:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "97e3e472",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "ALLOCATE (x(n))\n",
      "ALLOCATE (y(m))\n",
      "\n",
      "DO k=1,n\n",
      "  DO j=1,n\n",
      "    DO i=1,n\n",
      "      var_out(i, j, k) = 2._jprb\n",
      "    END DO\n",
      "    \n",
      "    var_out(m:n, j, k) = var_in(m:n, j, k) + var_inout(m:n, j, k) + var_out(m:n, j, k)\n",
      "    \n",
      "    vout => var_out(:, j, k)\n",
      "    \n",
      "    CALL some_kernel(n, vout, vout, var_in(:, j, k), var_inout(:, j, k), 1, h=n, l=5, y=y)\n",
      "    \n",
      "    NULLIFY (vout)\n",
      "    \n",
      "    \n",
      "    CALL some_kernel(n, tendency_loc%cld(:, j, k), var_out(:, j, k), var_in(:, j, k), var_inout(:, j, k), 1, h=n, l=5, y=y)\n",
      "    \n",
      "    \n",
      "    DO i=1,n\n",
      "      var_inout(i, j, k) = var_out(i, j, k)\n",
      "    END DO\n",
      "  END DO\n",
      "END DO\n",
      "\n",
      "DEALLOCATE (x)\n",
      "DEALLOCATE (y)\n",
      "\n"
     ]
    }
   ],
   "source": [
    "from loki import fgen, SubstituteExpressions, Associate, Transformer\n",
    "\n",
    "assoc_map = {}\n",
    "for assoc in FindNodes(Associate).visit(routine.body):\n",
    "    vmap = {}\n",
    "    for rexpr, lexpr in assoc.associations:\n",
    "        vmap.update({var: rexpr for var in FindVariables().visit(assoc.body) if lexpr == var})\n",
    "    assoc_map[assoc] = SubstituteExpressions(vmap).visit(assoc.body)\n",
    "routine.body = Transformer(assoc_map).visit(routine.body)\n",
    "print(fgen(routine.body))\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4797ecc6",
   "metadata": {},
   "source": [
    "In Loki, an [_Associate_](https://sites.ecmwf.int/docs/loki/main/loki.ir.html#loki.ir.Associate) statement is a `ScopedNode`. A `ScopedNode` is a mix-in that attaches to an [_InternalNode_](https://sites.ecmwf.int/docs/loki/main/loki.ir.html#loki.ir.InternalNode). It declares a new scope that sits within the `Subroutine` scope, but also defines a few of its own symbols. This means that the new variables declared in an `Associate` statement are only in scope in the body of that particular node. Therefore to resolve the associations we can simply apply the [_SubstituteExpressions_](https://sites.ecmwf.int/docs/loki/main/loki.expression.expr_visitors.html#loki.expression.expr_visitors.SubstituteExpressions) visitor to the `Associate`'s body, as shown in the previous code-cell.\n",
    "\n",
    "Resolving pointer associations that use the `=>` operator is a little more involved. Firstly, pointers and targets must be declared in the `Subroutine` specification, unlike an `Associate` statement which declares new symbols. It would thus be wrong to think of a pointer association as having its own localised scope. Secondly, an associated pointer can be disassociated either by exiting the encompassing scope (i.e. exiting the `Subroutine`), by using the [_Nullify_](https://sites.ecmwf.int/docs/loki/main/loki.ir.html#loki.ir.Nullify) intrinsic or by assigning to `NULL()`.\n",
    "\n",
    "Therefore before we can apply the `SubstituteExpressions` visitor to resolve pointer associations, we must first determine the *range* of nodes over which the pointer is valid. The best way to do so is to develop a bespoke visitor: "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "d8b139a5",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Comment:: \n",
      "Call:: some_kernel\n",
      "Comment:: \n"
     ]
    }
   ],
   "source": [
    "from loki import Assignment\n",
    "\n",
    "class FindPointerRange(FindNodes):\n",
    "    \"\"\"Visitor to find range of nodes over which pointer associations apply.\"\"\"\n",
    "\n",
    "\n",
    "    def __init__(self, match, greedy=False):\n",
    "\n",
    "        super().__init__(match, mode='type', greedy=greedy)\n",
    "        self.rule = lambda match, o: o == match\n",
    "        self.stat = False\n",
    "\n",
    "    def visit_Assignment(self, o, **kwargs):\n",
    "        \"\"\"\n",
    "        Check for pointer assignment (=>). Also check if pointer is disassociated,\n",
    "        else add the node to the returned list.\n",
    "        \"\"\"\n",
    "\n",
    "        ret = kwargs.pop('ret', self.default_retval())\n",
    "        if self.rule(self.match, o):\n",
    "            assert not self.stat # we should only visit the pointer assignment node once\n",
    "            self.stat = True\n",
    "        elif self.match.lhs in findvarsnotdims(o.lhs) and 'null' in [v.name.lower for v in findvarsnotdims(o.rhs)]:\n",
    "            assert self.stat\n",
    "            self.stat = False\n",
    "            ret.append(o)\n",
    "        elif self.stat:\n",
    "            ret.append(o)\n",
    "        return ret or self.default_retval()\n",
    "\n",
    "    def visit_Nullify(self, o, **kwargs):\n",
    "        \"\"\"\n",
    "        Check if pointer is disassociated, else add the node to the returned list.\n",
    "        \"\"\"\n",
    "\n",
    "        ret = kwargs.pop('ret', self.default_retval())\n",
    "        if self.match.lhs in findvarsnotdims(o.variables):\n",
    "            assert self.stat\n",
    "            self.stat = False\n",
    "            ret.append(o)\n",
    "        elif self.stat:\n",
    "            ret.append(o)\n",
    "        return ret or self.default_retval()\n",
    "\n",
    "    def visit_Node(self, o, **kwargs):\n",
    "        \"\"\"\n",
    "        Add the node to the returned list if stat is True and visit\n",
    "        all children.\n",
    "        \"\"\"\n",
    "\n",
    "        ret = kwargs.pop('ret', self.default_retval())\n",
    "        if self.stat:\n",
    "            ret.append(o)\n",
    "            if self.greedy:\n",
    "                return ret\n",
    "        for i in o.children:\n",
    "            ret = self.visit(i, ret=ret, **kwargs)\n",
    "        return ret or self.default_retval()\n",
    "\n",
    "for assign in [a for a in FindNodes(Assignment).visit(routine.body) if a.ptr]:\n",
    "    nodes = FindPointerRange(assign).visit(routine.body)\n",
    "    for node in nodes[:-1]:\n",
    "        print(node)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3fceef8d",
   "metadata": {},
   "source": [
    "As the above output shows, our new visitor correctly identifies all three nodes over which the pointer association applies. We can now finally proceed to resolve the pointer association:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "aef2e705",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "ALLOCATE (x(n))\n",
      "ALLOCATE (y(m))\n",
      "\n",
      "DO k=1,n\n",
      "  DO j=1,n\n",
      "    DO i=1,n\n",
      "      var_out(i, j, k) = 2._jprb\n",
      "    END DO\n",
      "    \n",
      "    var_out(m:n, j, k) = var_in(m:n, j, k) + var_inout(m:n, j, k) + var_out(m:n, j, k)\n",
      "    \n",
      "    \n",
      "    CALL some_kernel(n, var_out(:, j, k), var_out(:, j, k), var_in(:, j, k), var_inout(:, j, k), 1, h=n, l=5, y=y)\n",
      "    \n",
      "    \n",
      "    \n",
      "    CALL some_kernel(n, tendency_loc%cld(:, j, k), var_out(:, j, k), var_in(:, j, k), var_inout(:, j, k), 1, h=n, l=5, y=y)\n",
      "    \n",
      "    \n",
      "    DO i=1,n\n",
      "      var_inout(i, j, k) = var_out(i, j, k)\n",
      "    END DO\n",
      "  END DO\n",
      "END DO\n",
      "\n",
      "DEALLOCATE (x)\n",
      "DEALLOCATE (y)\n",
      "\n"
     ]
    }
   ],
   "source": [
    "pointer_map = {}\n",
    "for assign in [a for a in FindNodes(Assignment).visit(routine.body) if a.ptr]:\n",
    "    nodes = FindPointerRange(assign).visit(routine.body)\n",
    "    pointer_map[assign] = None\n",
    "    for node in nodes[:-1]:\n",
    "        vmap = {var: assign.rhs for var in FindVariables().visit(node) if assign.lhs == var}\n",
    "        pointer_map[node] = SubstituteExpressions(vmap).visit(node)\n",
    "    pointer_map[nodes[-1]] = None\n",
    "routine.body = Transformer(pointer_map).visit(routine.body)\n",
    "print(fgen(routine.body))\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "feacf206",
   "metadata": {},
   "source": [
    "## Modifying variable values"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "852fd85d",
   "metadata": {},
   "source": [
    "Putting aside function or subroutine calls for the moment (and also ignoring I/O), there are only two mechanisms for modifying the value of a variable. The obvious one is an [_Assignment_](https://sites.ecmwf.int/docs/loki/main/loki.ir.html#loki.ir.Assignment) statement, where the `rhs` value is assigned to the `lhs` value.\n",
    "\n",
    "Values can also be assigned to a variable by using it as the induction variable of a loop. Although an extremely unusual practice, Fortran compilers do allow dummy arguments of kind `intent(out)` or `intent(inout)`  to be used as the induction variables of a loop. This is however (in my humble opinion) bad coding practice; for ease of readability, local variables rather than dummy arguments should be used as loop induction variables. Therefore in our linter rules, we will forbid the use of variables with declared `intent` as loop induction variables.\n",
    "\n",
    "To enable us to check all our linter rules in just one pass of the subroutine's IR, we will create a new visitor: `IntentLinterVisitor`. The next section creates the `IntentLinterVisitor` visitor and defines linter rules for checking `intent` consistency within the `Subroutine` body. We will later examine how this can be extended to subroutine calls."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a4db06cc",
   "metadata": {},
   "source": [
    "## Checking `intent` in `Subroutine` body"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fec94f1c",
   "metadata": {},
   "source": [
    "Let us first define an initialization method for an instance of `IntentLinterVisitor`, and a method to check for rule violations:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "b9a024c2",
   "metadata": {},
   "outputs": [],
   "source": [
    "from loki import Visitor\n",
    "\n",
    "class IntentLinterVisitor(Visitor):\n",
    "    \"\"\"Visitor to check for dummy argument intent violations.\"\"\"\n",
    "\n",
    "    def __init__(self, in_vars, out_vars, inout_vars):  # pylint: disable=redefined-outer-name\n",
    "        \"\"\"Initialise an instance of the intent linter visitor.\"\"\"\n",
    "\n",
    "        super().__init__()\n",
    "        self.in_vars = in_vars\n",
    "        self.out_vars = out_vars\n",
    "        self.inout_vars = inout_vars\n",
    "        self.var_check = {var: True for var in (in_vars + out_vars + inout_vars)}\n",
    "\n",
    "        self.vars_read = set(in_vars + inout_vars)\n",
    "        self.vars_written = set()\n",
    "        self.alloc_vars = set() # set of variables that are allocated\n",
    "\n",
    "    def rule_check(self):\n",
    "        \"\"\"Check rule-status for all variables with declared intent.\"\"\"\n",
    "\n",
    "        for v, s in self.var_check.items():\n",
    "            assert s, f'intent({v.type.intent}) rule broken for {v.name}'\n",
    "        print('All rules satisfied')\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9c679257",
   "metadata": {},
   "source": [
    "You may have noticed that in defining our new visitor, we also introduced an attribute called `alloc_vars`. This is intended to accumulate the variables allocated in a subroutine. The reason for including this attribute will be clear later on.\n",
    "\n",
    "We can now proceed to define the rules for our linter. The rule to check whether variables with declared intent are used as loop induction variables can be implemented as follows:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "f4a62f1b",
   "metadata": {},
   "outputs": [],
   "source": [
    "def visit_Loop(self, o, **kwargs):\n",
    "    \"\"\"\n",
    "    Check if loop induction variable has declared intent, update vars_read/vars_written\n",
    "    if variables with declared intent are used in loop bounds and visit any nodes in loop body.\n",
    "    \"\"\"\n",
    "\n",
    "    if o.variable.type.intent:\n",
    "        self.var_check[o.variable] = False\n",
    "        print(f'intent({o.variable.type.intent}) {o.variable.name} used as loop induction variable.')\n",
    "    for v in [v for v in FindVariables().visit(o.bounds) if v.type.intent]:\n",
    "        if v not in self.vars_read | self.vars_written:\n",
    "            print(f'undefined intent({v.type.intent}) variable {v.name} used for loop bounds.')\n",
    "            self.var_check[v] = False\n",
    "        self.vars_read.add(v)\n",
    "        self.vars_written.discard(v)\n",
    "    self.visit(o.body, **kwargs)\n",
    "\n",
    "IntentLinterVisitor.visit_Loop = visit_Loop\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "42f4e4d1",
   "metadata": {},
   "source": [
    "For `intent(in)` variables, we don't want their value to be reassigned in the `Subroutine`. Therefore the rule for checking `intent(in)` variables is the simplest: variables of kind `intent(in)` should not appear in the `lhs` of an `Assignment`. The rule for `intent(out)` variables is that upon entry to a subroutine, a value must be assigned to them before the variable can be used: `intent(out)` variables must be written to before they can be read. For `Assignment` statements, the above rules can be implemented as follows:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "b28b2e39",
   "metadata": {},
   "outputs": [],
   "source": [
    "def visit_Assignment(self, o):\n",
    "    \"\"\"Check intent rules for assignment statements.\"\"\"\n",
    "\n",
    "    if o.lhs.type.intent == 'in':\n",
    "        print(f'value of intent(in) var {o.lhs.name} modified')\n",
    "        self.var_check[o.lhs] = False\n",
    "\n",
    "    self.vars_written.add(o.lhs)\n",
    "    self.vars_read.discard(o.lhs)\n",
    "\n",
    "    for v in FindVariables().visit(o.rhs):\n",
    "        if v.type.intent == 'out' and v not in self.vars_read | self.vars_written:\n",
    "            print('intent(out) var read from before being written to.')\n",
    "            self.var_check[v] = False\n",
    "        elif v.type.intent:\n",
    "            self.vars_read.add(v)\n",
    "            self.vars_written.discard(v)\n",
    "\n",
    "IntentLinterVisitor.visit_Assignment = visit_Assignment\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ccb50ad2",
   "metadata": {},
   "source": [
    "In principle we could also build similar checks for `intent(inout)` variables. However, the way in which some Fortran compilers treat `allocatable` variables prevents us from doing so.\n",
    "\n",
    "If an `allocatable` array is passed to a subroutine as a dummy argument of kind `intent(out)`, some Fortran compilers will deallocate that array upon exiting the subroutine. This is why in the IFS, data arrays are sometimes declared as `intent(inout)` even if their true intent is `intent(out)`. An example can be seen in the 'cloudsc-dwarf' in `src/cloudsc_driver_mod.F90`: the `REAL` array `PCOVPTOT` is declared `intent(inout)` even though it's value entering the subroutine is never used.\n",
    "\n",
    "An allocatable array passed as a dummy argument to a subroutine could thus belong to two possible categories:\n",
    "1. A variable that is truly of type `intent(inout)`\n",
    "2. A variable that is strictly of type `intent(out)`, but has been declared `intent(inout)` to avoid deallocation\n",
    "\n",
    "It would be very difficult to discern between the two options from a static analysis of the source code. As such, we will not impose any rules related to `Assignment` expressions for `intent(inout)` variables.\n",
    "\n",
    "We can however impose the rule that the dummy argument corresponding to an `allocatable` array must be of kind `intent(inout)` or `intent(in)`. To enable a `visit_CallStatement` method to perform this check, we first need a `visit_Allocation` method that updates the `alloc_vars` set:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "6b6b5179",
   "metadata": {},
   "outputs": [],
   "source": [
    "def visit_Allocation(self, o):\n",
    "    \"\"\"\n",
    "    Update set of allocated variables and read/written sets for variables used to define\n",
    "    allocation size.\n",
    "    \"\"\"\n",
    "\n",
    "    self.alloc_vars.update(o.variables)\n",
    "    for v in [v for v in finddimsnotvars(o.variables) if v.type.intent]:\n",
    "        if v not in self.vars_read | self.vars_written:\n",
    "            print(f'undefined intent({v.type.intent}) variable {v.name} used to set allocation size.')\n",
    "            self.var_check[v] = False\n",
    "        self.vars_read.add(v)\n",
    "        self.vars_written.discard(v)\n",
    "\n",
    "IntentLinterVisitor.visit_Allocation = visit_Allocation\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "feaa4c96",
   "metadata": {},
   "source": [
    "We are now ready to implement a `visit_CallSatement` method."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "27f1275c",
   "metadata": {},
   "source": [
    "## Building `intent` map between function caller and callee"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "df378590",
   "metadata": {},
   "source": [
    "We have already defined one linter rule for `CallStatement`s; dummy arguments corresponding to `allocatable` variables must of type `intent(in)` or `intent(inout)`. Another very important check we have to perform is to ensure that the declared `intent` of a dummy argument is consistent with the `intent` of the argument in the calling (parent) subroutine.\n",
    "\n",
    "For example, `var_in` is a variable of kind `intent(in)` in `Subroutine` `intent_test`. Therefore `var_in` must not be modified within `intent_test` or any subroutines called by `intent_test`. Hence in `some_kernel`, `var_in` must also be of kind `intent(in)`.\n",
    "\n",
    "The mapping for `intent(out)` variables is a little more complicated and depends on whether before the [_CallStatement_](https://sites.ecmwf.int/docs/loki/main/loki.ir.html#loki.ir.CallStatement), the variable in question has ever been written to, and if so, whether the value last assigned to it has been read at least once. The procedure for building the mapping is best illustrated using the flowchart below:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "d795ea6a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<IPython.core.display.Image object>"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from IPython.display import Image\n",
    "\n",
    "fig = Image(filename='gfx/intent_out_map-crop.png')\n",
    "fig\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b8d64913",
   "metadata": {},
   "source": [
    "A similar process can be used to determine the mapping for `intent(inout)` variables:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "bc9b5b41",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAl4AAAF8CAYAAAAerbUmAAABJ2lDQ1BrQ0dDb2xvclNwYWNlQWRvYmVSR0IxOTk4AAAokWNgYFJILCjIYRJgYMjNKykKcndSiIiMUmB/xsDBwMMgzsDMwJ2YXFzgGBDgwwAEMBoVfLvGwAiiL+uCzMKUxwu4UlKLk4H0HyDOTi4oKmFgYMwAspXLSwpA7B4gWyQpG8xeAGIXAR0IZG8BsdMh7BNgNRD2HbCakCBnIPsDkM2XBGYzgeziS4ewBUBsqL0gIOiYkp+UqgDyvYahpaWFJol+IAhKUitKQLRzfkFlUWZ6RomCIzCkUhU885L1dBSMDIyMGBhA4Q5R/TkQHJ6MYmcQYgiAEJsjwcDgv5SBgeUPQsykl4FhgQ4DA/9UhJiaIQODgD4Dw745yaVFZVBjGJmMGRgI8QHbBUozZ45GUQAAADhlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAACXqADAAQAAAABAAABfAAAAACZtezAAABAAElEQVR4AeydB3xc1bH/R733XmxJ7kXuvXfjYGoIKYZHElrqg7yXAqRBkhfyXkJCOsH8qYGEQAIGHGPcwL3J3ZJlucmyrN57139+Z31XV6tdaSWttG2OPtLecur3XO3Ozpkz49HJiSQJASEgBByAQE1tI505X+AAPZEuOCOBKeMTKTQkwBm7Ln12IwLebjRWGaoQEAIOTiA3v5ye/uMO8gsIc/CeSvccjUBzYzX94rH1NHVisqN1TfojBLoREMGrGw45EQJCwN4E/AOCySsgwd7dkPadjIAHtTtZj6W77krA010HLuMWAkJACAgBISAEhMBwExDBa7iJS3tCQAgIASEgBISA2xIQwcttp14GLgSEgBAQAkJACAw3ARG8hpu4tCcEhIAQEAJCQAi4LQERvNx26mXgQkAICAEhIASEwHATEMFruIlLe0JACAgBISAEhIDbEhDBy22nXgYuBITAcBPoaG+lCyf+NWzN1lbmU8GlA8PWntZQaf4pammq1U6Nr3VV+VRddsV4LgdCwB0JiODljrMuYxYCLkzg9N6/WCVsZB16lY7vfLZXEs2NVWYFiF4L6W6als87v4uu8S+SNe3rqrL6sL66kDo7DD6tPDw86ehHv6D2thary/eVsbL4PH348j3U2dlhMeuxHb8m5DNNV7O20cWTwyd4mrYv50LAEQiI4OUIsyB9EAJCwGYEqkouUENtcZ/1JY5eTKmTP9VrvjN7N7Kg8E6veXq7aVr+atZWGjF+pSpiTfu91W3p3rbXHyBoupCCwxMpiH8LLu2zlL3f14PDk2nqkq8ShDpJQkAI9J+AeK7vPzMpIQSEgJMQuHzmA7py9kPy9vGjGSu+RaFRKcaeV5ddUtqsyPgJlLHtlxSVlE5557aTp5cvTV/+TSovyKSiq0f53JvKC7No0e0/p6b6CjqzbyPVsWATmTCJpix6UNWRefAVCo5IUpo21Ddt6dcoL3tnt/Lz1z9Jpfmnadbq76g+9NV+SMQIpbnKzvg7FV05TJ7evjQq/RYW3FbwmLZQe3sLjZl2h6pr36YnVL2ZB1+i9tZmOrbjGYpLmU2T5n+REtLmU2HuYaPAhwK5WR9RXdV1Sl94vyp/6dR71NHRpoSpazm7qKO9jZLGLKEJczZQQ00xZR58mby8/ZQWa97NP6Kr57ap++WFmZR99G8qT2hUquLmFxCu6gS7rMOvMvsASl/0EEXEjlXXtT8NtSU9WHr7Bmq35VUIuCwB+crislMrAxMC7k0AsfuwlDhr9bdp8oL7ycOz+9sdhKeacoO9UVnBWco+/AYLGvewoOBPWK6MS5lF4TFjKDZ5Bgsw95Gnpzftf/8HFBQaTzO5zsqSHMrk5crWlnoWZD5kLdM1mrL4Icq/sJuu5XzSozza6+xsp8CQODUxfbWPTBC6IORAw5TG2rkjHz3Nwk8Ot5VHteVXjRNckneM2lobaMz0O5WgOGrqbSxorVL30d/6qu6Bx4PDEinn2D+4TKPKk3PsLQoIiqKmhkoWGr+hBEcIkzXluTfGt5Vam+towtx7uUwTlVw7ocpBeEubfDNBqISAdvHkJmOfCi8fZMHuQQrk9g9tforH3mm8hwNzLLtlkBMh4KIEur8TueggZVhCQAi4HwEIUL7+oWzM/k8VdBsapN7SjJWPKi1R6qR1rA0qoIDgGPIPjGDBIY6iEiZTY10pYRkTWpnS/JOqTmh8kHBtztrHKXbEDFVHfXXP8i1NNVwmXAlG5vph2j7yFFzcR+Nnf56iEifTyAmrlRBYnJdhrri6BkHRw9OLtUvjKCTCECzaPyia6muKupWJSkxXY4NwBEEOtmgJoxbQxLn3sAavRmnDfP2DecxlqpyXtz/NXvsYa7kWs1bMw1hXysS15M8CW0VRNvno8iMDtIYxydNoMmvd6qqvU3NDhbFcbyyNmeRACLgoAVlqdNGJlWEJAXcngKWx1Ruep/MZb9L2Nx6mueu+T8ljl1rEotkseXr5GI3T9Zmh6UHC0hnyxqfMVdocXMO5JpB4WSgPgUjTMKGMaTLXfitrsXx8g4xZvXjJ1GA479GrcbuxAB+0tzUZ+6ZdR18hyMHYHwJp8thlagzb/vqAWo6NjJ9EpFNQYbnVi5c6TdPpvc9TweX9qi4sT+oLaePxYl5Ieo1XbyxVZvkjBFyYgGi8XHhyZWhCwJ0JKHcGLGBAk5QycQ2VXT/VbxwQwmCLhB18WCKEEBQQHE2jp91OaenreSlydK91di8fw0JQc792SYZHj1G2YhBa0A8s8UH75hcQxkudF5QQdpXttWDvpSVPTx+lndMEHZRDn03TyAlrqIhtv1B+JPOpYy0dljChuQOv3nYtanUVXjmkNHITeQkSAqk+YYkUwlg+L7tC0+cfFGm8PRCWxsJyIAScnIBovJx8AqX7QkAImBC4oX3CMtknbz+qhJTWlgZafPsvumdUS2aGZTNogDQNjV57BcP0/R/8UNlt3fbVTTRrzXcpY/uv6NSe59jmqZ4mzruX4kbOJi7dVTd2+6m6SRm2a+Vv/cq7aumzqvSiWpI05Om9/fRFD9CB939I7z13qxKEYEwfO3ImhUSOoIunNtGmP99CEXHj1Ri5UdWHpNGLaN97T1DymKUEQ/jq0ksUGT+xq383jrDRICx6FC8BVvKS4HSuv52ik6bSlpc2kI9foDKmN2TF6HTjU2eG89TJ6+jEzt9SFtuD+fGyLJZ2kcATAt+7f7qZbeO8WJh7zMD3BnNoz8yxHDfzbkOT8lcIuDABD/5WpFMou/BIZWhCQAg4PIHT5/LpJ7/fTV4BBvukgXTYsDvPS33447ilkW2rAsMNH/y6CpVGh9/+sAQIzQyW07SkP1fLYqzx0nbc4S0TNlG+fsFcxkcV0edXS4E6QU5fHrsnUWbmqv8yaJSsaB8NQMjDMiMM/LWEfrSxQOnjF9Sj/9D2efsaNFAfPP9pWnjrT5VwpZXVXtHXTv7R14tNCRCgIIhp1/XjQ1n9OZZPPTy8DCyYk54n7MXATatHzxz1mGOJ6wNJ7Y359OQjy2jqxIE/OwNpV8oIgf4SkKXG/hKT/EJACDg0AXzIa/ZWOMYSl6bN0ndcabZY6ELSC12m5zDS14Qu3EPdMLrXhC7T/BA89O3py4+Z8Wl2ObEfRVQe5EXqrX3ch3ClCS84R0I/cB3JtLyvf4jKX8buK7BJABotcwntm9aLZUzUrb9uWr/+HEuM0GChjOl4IMDp69EzR3/MsTTXT7kmBFyJgAherjSbMhYhIAQcmgB2Ha5/6K1h6yOWJdfc+8KwtScNCQEh0DcBEbz6ZiQ5hIAQEAI2I6DXhtms0l4qGu72eumK3BICQoAJiOAlj4EQEAJCQAgIASEgBIaJgAhewwRamhECQkAIWEMALiNMg1qX5p/qlxsKtFNRdE7Zk8EQXpIQEAKOQ0AEL8eZC+mJEBACQoD2vftYjyDfx3b8WsVJtBYPwhbt5XrgSwte4iUJASHgOAS69iY7Tp+kJ0JACAgBITAIAog9iXA+CNsjSQgIAcciIIKXY82H9EYICAEnIoAg0Wf2v0AL1j+leo3wRAEhMZQ4ahGd2v1Hqig+T2FRaSpcEXyKZR95gwqvHGYXFxEcuPvLKgg3vNmf2beRyguzlDPWDvafZS4VXT1KWYdfVR7i0xc9xPEYx5K5OqvLrtB11nixbwcV2Ho2O31FsO0ibteT3T6MSr+FA2ivUEGtMw++rBylVnI/l939Ow6c/WaP/pnri1wTAkJg4ARkqXHg7KSkEBACbk6gtbmOA2Z3hSKqLr9C9RxgG0t81eW5tOi2nyvv9cCUk/EPFaIHglBoZArtZ4/0cCCaffRvVJJ3nKYu+YpaYjTEYuwJFgGt0xc+qOJDHtr8lCprrk747EKQ7Bj2Qj92xl1K6EJ/pi75KqVN/hQd+ehpFRi7taWecrO2KuFsAof8uXDibbP969kTuSIEhMBgCIjgNRh6UlYICAEhYIZAUGg8VZddZs3THopPnadyFFw+oOI9FudlKC1TQ00RNdWXK6FrDAtIEJjm3PQEO0PtGYwaFWDZMCZ5Gk2e/0WOq3idQ/1UcIDqnnUqp6RBUcpxajhrxQou7lPxFKMSJ6tg1rHJMwh9QPLy9qfZHM4nacxigmCHGIqm/VMZ5Y8QEAI2IyCCl81QSkVCQAi4I4HOjo4ew45PnUsLb/kpFVw5SFtfvY9DDFUTQutgqc+LBSsEjZ616tsqxiKu+3BYHSTl/b1HbYYLmj8urxvBqFXIIAt16qtobeWwQhzcW0sIPaRp1eCBHl7nkSz1Tysnr0JACNiGgNh42Yaj1CIEhIAbEoAAhXiE9dWFKrYhlgxDwpOptiJPaadiR8ygDzZ+mmorryl7rk527TBq6m1KwKpnjRfCDoXwsiPCCI0Yv5LysndQe3uLWZJYLoRWLD/nEyW4IRQSPOGbq1NfQXj0GK53J2u1lqodjnBXMWbanfos6tiaunoUkgtCQAj0m4AIXv1GJgWEgBAQAgYCgaFxSmDa+uoXyY/jEgaFJ/IND7UECNstaLfCokcpmysY0x/44Ee0eeNdKqZhcFgiLf/s72gi21ftffd79N6fb6WwmNEcBzJS1aFnDE1YQ20Jvfunmzn2oRfN4eVBaMAs1YmyKIOUvugBOsD2ZO89dysLhx0sdN1BCCUEI3yOrqjy4E9vdRkzyYEQEAKDJuDB6urOQdciFQgBISAEbEDg9Ll8+snvd5NXQLINahu+Klqb6zmQdoCxQQhFbS0NvOuwnRCwWp9a+TpLQMYA17inLRtiyREOT/VBqHFfuwbtGgJ26wNP475pnWopEUGruR9aQh+xzKgvq9Wr5cGraV36e4583N6YT08+soymTnSuZ8eRmUrfhoaAaLyGhqvUKgSEgBsR8PHrsqHShg0ByVzS7Ln096Cd0q6bCl3Ip13zZa2auaSV1e55sFbMNJnro1avPq9pXfp7ciwEhMDgCXR9HRp8XVKDEBACQkAICAEhIASEQC8ERPDqBY7cEgJCQAgIASEgBISALQmI4GVLmlKXEBACQkAICAEhIAR6ISCCVy9w5JYQEAJCoD8E2lqbqPiqwTlpXVW+2jnYn/KOnhe7IuEqAzssJQkBITAwAmJcPzBuUkoICAE3IdDR3moI68P+ryB4JLM/LHia19w16DHUVxfQwX8/RXd8fTNdzdpGTexdftbq7xB8Z2UfeV05Uo1OnELTV/yn2qnY3FjF3uJj9VX0OEYeDw+vHrsje2QcggumbW977cvKFQY87oexD7Eld/yf0fB/CJqXKoWASxIQjZdLTqsMSggIAVsROLD5x5TPQafHzbxb/eZf3EMt7Ine2gTBbf973+eYjQuUEAbv9XDjUJp/Uvnv6queM3s30sWT7/SVbUjum7a95NO/orX/8RJ96st/o+rSSxxQ++CQtCuVCgFXJiAaL1eeXRmbEBACgyJQUXSOiq4coU/d/wYh/iJS0pgl6vXiyXfpWs4uJUTh2oQ5G9R10z/wn4VwPFGJ6RQZP0H91nEg7bMHXqSGmmIlfI2f/QUVugdOV3EtNCpVxWYsvHyIiq4eVVql8sIsWnT7z6k49ygHtP4ne7hvpdRJN1Fa+npVJvPgK+zANUF5wYfH/IS0hZTJbXj5+NOMFY9QcHiSWiI8s28j1VXmU2TCJJqy6EH2vF9LKBsckcRlD6j+TVv6NeXt3rRtTTsH1xT+HA8SS6uShIAQ6B8B0Xj1j5fkFgJCwI0IVJZcoNDIkUahSz/0poZKmrb0G/z7NSW41JTn6m8bj/0Cwyl57HLa/a//pqxDrxIEsYDgaBo5fhUvH4bSxHn3qdA/dVXXKW3yzTR//ZNKkLp4chPFpcxS9xDYetL8+6ieBbZDH/6Mg15/QQl6Jz7+A0E4bG2pp9ysD1XooskL7qeLJ96hI1t/TuPnfEF5us888JLqz/73f6DGMnP1t6myJIcy0Z8bZRHWaMrih5R27xqHJTJtW3O8Ck3d8Z3PcvihMs4z2zhOORACQsA6AiJ4WcdJcgkBIeCGBFqb61hj1OWRXo9g4tx7VJxGCEy+/sFKENHf1x/PX/9jmrH8ERaOPqKPXvuS0jJBqwVv99GsCYN3+5SJa5UWqaIom3xu1BcQHMMhhCIIoYmiEiZTYe5hCmBNU3X5FRX/EfEaywsyVVNw2Dp7zfdY0zWPwuPGqRBACWnzacSEVVTHsSQb60qpigVJ5IPw5BcQRuWFXWXnrH2coCmDMAVbNdO2tfHkHH9bxZO86b6XVN+06/IqBISAdQRkqdE6TpJLCAgBNyQQxPEUayvzqL2tmZcC/YwEYLe1/fWHeEkwhZfmJnHMH+MtswcI3ZM6eR0lj1tO21jwun5xNy/9dQ9tc3rv8xzjcT+NnLBaLV+aqxRLltA8IQYk0vhZn1NxF9EftKEZ/COPh6fhe7Wnpw9X1WFcFvRmQRJ541PmskBnWD7Vl/XiwN0q5JDZkZBqO3bETCUkWsgil4WAEOiFgGi8eoEjt4SAEHBvAvGpc9VS3cndf1J2WohjeD7j71RRnKMEMmiJUiauUbsdLZGC+4XCK4dUPMZ2tomCbZYva5s8WcBpqq9UQhZiNSLP+NmfV0GzIRxpCfngvgE7KsN5J2EzG/Ynj11Go6fdzoLcMrVsqeXt7TUwJI7DEgWp/CgL27BwDsrdW9K3reWDAInA35KEgBAYGAHReA2Mm5QSAkLADQggbuGi256mjB2/ok1/Wk+sKiIIY2lTbqPopKm05aUNHOw6UKcN48DU/KMS5+UCSuA6vuu3aidkR0cbjRi3gkawzRe0V168w3HTn2+huTc9rjRiJ3b+lrIOvkJ+vLyoxWXEcuH+D36obK9u/cq7lDBqAW15eYNa5mtraaRln3lWtWNsF2fcNrRYSEoLxudoa9aa71LG9l/RqT3PKVuzifPupbiRs7v6rApwOdV34mXLrrZv++ompW3LOvQaxYyY3qfQphqXP0JACPQg4MHftPpQkvcoIxeEgBAQAkNC4PS5fPrJ73eTV0D3ZbghaayflbaxtssDy3wswGgJ2icISJ2d7UoowXW4ikDwaWio+I/ye4XrzQ1VyqZLv2SJJb2W5lq2twpHFiWMwWcXNE1YHtSCXavdg3yuBd5ub2sh9AeaM215UWsX9UDAQz3Ge3yuGcfjLR/+uXz9gg3tIP+NPqOsWmbUCW6mbatlTQ7CrQl2KOMIqb0xn558ZBlNneh4z44j8JE+OA4B0Xg5zlxIT4SAEHBgAprQo+8iDNSRPDy63kohdBmuQXOkDtUf7G40TRCsNKEL9/RLjMSCk5a82SWEPkH40wuAuKe1q45ZQNQnTejCNQhjMNjXJ31ZTdjT7pu2rYRC7aa8CgEh0G8CBl10v4tJASEgBISAEBACQkAICIH+EhDBq7/EJL8QEAJCQAgIASEgBAZIQASvAYKTYkJACAgBISAEhIAQ6C8BEbz6S0zyCwEhIASEgBAQAkJggAS6W2AOsBIpJgSEgBCwFYGODt4NyLv2JAmB/hBQz01/CkheIWAnAiJ42Qm8NCsEhEBPAsFB/hQb4U3tHaU9b7r5ldYOP2KHEuRFbeTt2ezmNHoO3yvQm/D8SBICjk5A/Hg5+gxJ/4SAEHBrAnUNrbTrcBFNSAulcalhlJNbTdmXa2jlvHgWNNjflyQhIAScioAIXk41XdJZISAE3InA8axyKihpoJsWJ5GPd5dJbmtbB23bX0AJMQE0c1KUOyGRsQoBpycggpfTT6EMQAgIAVcjUF3bQjsPFdKMiZGUlhxicXhX8mvpxLkKWjk/gcJDujzqWywgN4SAELA7ARG87D4F0gEhIASEQBeBw6dLqaK6hdYuTCQvL53r+64s3Y7a2ztp+8ECJXjNnxbT7Z6cCAEh4HgERPByvDmRHgkBIeCGBMqrmunjI0U0f2o0JccH9ZtAfnE9HTpVRivmxlNUuF+/y0sBISAEhoeACF7Dw1laEQJCQAiYJYCg1ftPlFJjUxut4iVDT8++tVxmK+KLHR2dyhDf39eTFs2MNQbJtpRfrgsBITD8BETwGn7m0qIQEAJCQBEoLm+kvRnFtHhWHMVHB9iMiqr3WAktZuHLlvXarINSkRBwYwIieLnx5MvQhYAQsA8BaKb2HCumTvYVu3xu3JBopqBJ281CHdpYNiduUJo0+1CSVoWAaxIQwcs151VGJQSEgIMS0GyxlrMwFB0x9A4/B2s75qAYpVtCwGkJiODltFMnHRcCQsCZCGD3IYznYX+FpcXhTvuPl1Bjcxsb3ydYtVtyuPsn7QkBdyEggpe7zLSMUwgIAbsRgL+tjMxyWsMuIuzpbwv+wbYfLGSnq5E0qhf/YHYDJQ0LATcgIIKXG0yyDFEICAH7EICH+V3sCDWS3TvMSY+2TyfMtJqRWUZlFc20akFCN4/4ZrLKJSEgBGxMQAQvGwOV6oSAEBACIJCTW0NncirppkWJDhlTETEgtx0ooMmjw2l8WphMmhAQAsNEQASvYQItzQgBIeAeBJpb2lW4n8TYQJo+IdLhB33qfAXlFzUoH2L+fl4O31/poBBwdgIieDn7DEr/hYAQcBgCmRer6MLVGqXlCvD3dph+9dUROG/9iINujxkZQuljI/rKLveFgBAYBAERvAYBT4oKASEgBECggQUX2HLBYH3SmHCnhZJ1qYou5tXSavagHxjgPIKj0wKXjrslARG83HLaZdBCQAjYisDJcxWUV1SvtFx+vs6/VNfCS6XQfiXFBfLuxyhbYZJ6hIAQuEFABC95FISAEBACAyBQW9/KcRELaRIbp49NCR1ADY5d5CIvmZ7lpdOV8xIoNNjHsTsrvRMCTkRABC8nmizpqhAQAo5BAO4YisualJbL29vTMTo1BL1oY3cY2PkYE+nvUO4whmCoUqUQGDYCIngNG2ppSAgIAWcnUFXTorRcWIJLTQp29uFY3f+rBXWUcbacVs6Pp4hQP6vLSUYhIAR6EhDBqycTuSIEhIAQ6EHg0KlSguf31QsS3TLkDgJ77+ANBMFsdL9wRmwPPnJBCAgB6wiI4GUdJ8klBISAmxIoq2yiT44W04JpMcrg3E0xGIddUNJAB06W0rLZcWoJ0nhDDoSAELCKgAheVmGSTEJACLgbgc7OTtrHgaVbWjs4sHQ8eXp6uBsCi+MFGwT89mImS1kA8/AQNhZhyQ0hYEJABC8TIHIqBISAECgqbaR9J0po6axYio0KECAWCJRUNNGejGJaOD2G4KlfkhAQAn0TEMGrb0aSQwgIATchADum3bys6MkbFZfNiXeTUQ9+mHuPFYtmcPAYpQY3ISCCl5tMtAxTCAiB3glcYyeoh0+X0UpeVowMl517vdPqebeyppm99xex24koGpnoPjs+e5KQK0KgdwIiePXOR+4KASHg4gTa2jvo48NFFCS79Wwy09j9WVPXyo5X48mVfZzZBJZU4pYERPByy2mXQQsBIQACl6/V0nEO+bNmQQKFhfgKFBsRgOC142ABTR0fwYG3Xc+rv40wSTVuSkAELzedeBm2EHBnAtipiKDW0ZF+NHtytDujGNKxH88qp6KyRhV029cF4lgOKSyp3G0IiODlNlMtAxUCQgAEzl+ppsxLVbR2YSIFB0oMwqF+Khoa21TYofFpoTRxVPhQNyf1CwGHJyCCl8NPkXRQCAgBWxBoam6nnazlGhEfyEtgkbaoUuroB4GzFyop93odrZqfQAH+3v0oKVmFgGsREMHLteZTRiMEhIAZAvjQv8T2XDctSiJ/Py8zOeTScBCA8Iug26mJQSL8DgdwacMhCYjg5ZDTIp0SAq5BoK2tna5er7DbYPBBf+h0KaUkBNHoEaGUNlLsuew2GbqGsdybzb/QfmG5t7CkmhoaW3Q57HcYGx1CIUH+9uuAtOzyBETwcvkplgEKAfsRKCmrofv+6zUKDg4b9k60tXUQ+0MlH29PDmlDVF9XTR/+9ZvD3g9p0DwBbHDYztqvuGh/eumNHVRY1sTBx+2rjWxsbKBvPbCU1iyZaL7TclUI2ICALLTbAKJUIQSEgGUCQUHB5Bkw0nKGIbpj6hzCt+X8ELUk1Q6EgK+PJ61flkyX82uprKqZPP0TydPbvo5rfTqLBjIUKSME+kWAA2NIEgJCQAgIASFgHwKjkkPEh5p90EurdiIggpedwEuzQkAICAEhYCDAK8GShIDbEBDBy22mWgYqBISAEBACQkAI2JuACF72ngFpXwgIASEgBISAEHAbAiJ4uc1Uy0CFgOMR+OaGCfTmM0s5bE+UsXMzJ0aqaw/fPdZ4TQ6EwAT2fP/q04to41MLKCk20AhkTnoU/e2XS2jmJHGKa4QiBw5NQAQvh54e6ZwQcG0CB06WkKenB921NsU4UBzj2sGTpcZrciAE4O8LHu/DQ33pi7ePNgKBuxBv/sWrJCHgDATEnYQzzJL0UQi4KIHjWRXKo/zoESE0bXwEtbPjrbEpocq55pkLVRQa7EOLZsRSXJQ/lVQ00YETpVRVa3C0GRLkTSvmxlNUuD9VVjfTriNFVFPX6qKkZFh6AtNZKzp1XASdzqnUXzYeBwd604JpMZQUF6ieiVPnDZELjBnkQAjYkYAIXnaEL00LASFA9PZHufT4g1Po9pUjlOAFJm9tzaXoCD96+tGZSsPRwQIZtGB3rhpJ330mQ32Y/vyRmRQfE6AEsfAQX/L08qB3tucJUhcncOhUKc1noereW0fRY7851mO0eG5+9p8zWCDv8gn22XWp9Nyb52l3RnGP/HJBCAw3ARG8hpu4tCcEhEA3AprWK31shLqefbmazrK26+G7xymha+NbOfTJ0SLasD6Nblk+glZymJl9x0qU0HXkTBk983ImjeSQQK3sqV6S6xPAnEPQnjAqjJbNjiN4wNenu9akKKHr3R15SoCfMi5cCfb3sKAmgpeelBzbi4AsituLvLQrBISAkcDbrOHS0lusAUMaPSJYvY7iZcj7Pz2GUpMM5wnRBi1XY1ObMsqHgb43a7sKSxtVfvnj+gRee/8SdXZ20uc+lUbwgK9PWKpGjE5oUrF0fTK7ks5erFLCWhgvXUsSAvYm0P2JtXdvpH0hIATcksDxcxVqybCssklpuwABxtRISXEBylbHi4Wrc5er6Ep+ndJy/OKFs5R7vY6Wstbjf/97Fq1bnKjyyx/XJ3Axr1bZ+2E5cd2SpG4Dhu1fQ2MbtbVzoM4bqb29QwlqLKtJEgJ2JyBLjXafAumAEBACIICg1vrlwrKqJrVk9Lu/nqOKaoNBvZ5U9pVqevzZ4zRlbDj94CtTae6UaNq6r0CfRY5dmMDft1yhuVOjCSGH9Kmc4z7iWgzbepVWcgxIVi8kxwVRB69I1rNAJkkI2JuACF72ngFpXwgIAbMEjmWW08RR4fTEQ1No+4EC5S4gjT9Q99wwkP7SnaNp16Eidd2DY87AAF+S+xDALtete6/TrStGdBt0xtlyGjMylL7/8FTazbaBU3j3Y0ykv3pusPQoSQjYm4AIXvaeAWlfCAgBRQDLQPqloC17rrMbiQBaMS+eHvzMOJWngt1GbGMhDEtJWIq874Y/J3wI/+3fV4SkCxPQng3YdmnpX9uv0jzWesXyc9LY1K4ub96dr56bJbNjacMto3jJsYOwE/Lldy9qxeRVCNiVgAc/xF1PsV27Io0LASHgagRKymroaz98h7wC0/ocGgzk8W5kqpXAUlFUmB818+41Uz9dsPFpZ1sezbdXb400V5+n9158uLcscs9OBB5+7O9U3hhFXt5dLiDMdQWG9Ka7GJEPzwiWEvXJi92PRIb5UmVNSzd7L30e0+OWhiL6xj1Tac2Siaa35FwI2IyAaLxshlIqEgJCYDAE9MbQ+nrwgQpbHXMJ9jyS3IeAOaELozcVunANAryl5wb3JQkBexGQXY32Ii/tCgEhIASEgBAQAm5HQAQvt5tyGbAQEAJCQAgIASFgLwKy1Ggv8tKuEHADAlVsX9Pc0k4BAWJK6gbTPegh2t3kWB7TQc+hVNA3ARG8+mYkOYSAEBgAgX3Hiqmsso4C/Tqpvf7CAGqwbZGwkN4Nt23bmtTWHwIjEsOpPPMqmdjH96eKfueFjAWbMfZEYvR+z/s7eLesPCf9hikF+kVAdjX2C5dkFgJCoC8CJeWNtIdjKS6aEUMJMYF9ZZf7QsCuBOCKBL7h5Hm16zS4VeMieLnVdMtghcDQEYADU+XclLUGCF7sAa+mkoSAkxDYyxpaaMBWzI1n9xTy7DrJtDllN0Xwcsppk04LAccicL24gQ6yk8rlc+IoOsLfsTonvRECVhKAg96PDxfRHA4/NTIhyMpSkk0I9I+ACF794yW5hYAQ0BGA89KPjxSSv583LZ4Zq7sjh0LAeQnA0311bQutWpBA3l6y+d95Z9Ixey6Cl2POi/RKCDg8gdzrdYR4iqvmJ1B4qK/D91c6KAT6Q6CmroV2HCykaRMiafSI7oG4+1OP5BUCpgRE8DIlIudCQAj0SqCtrYN2HCqkSBa25k6N6TWv3BQCzk7geFY5FZU10uoFicbdj84+Jum/fQmI4GVf/tK6EHAqAheu1tCZC5W0hj+EQoJ8nKrv0lkhMFAC9RyUfTsHZ5+QFkYTRoUNtBopJwQUARG85EEQAkKgTwIt7AR1Oy+7JMYG0IyJUX3mlwxCwBUJnMmpJCyxr1mYyHaNXq44RBnTMBAQwWsYIEsTQsCZCWRdqqKc3BpauyiRAv3F57Izz6X0ffAEmprbaRtrv1KTgmnquIjBVyg1uB0BEbzcbsplwELAOgKNTby8wlquUcnBlD5WPmCsoya53IVA9pVqyr5crbRfQQHyhcRd5t0W4xTByxYUpQ4h4GIETp2voLyCeqXl8vOVJRUXm14Zjo0IwOHqjoMFFBcVQLMmyxK8jbC6fDUieLn8FMsAhYD1BOrqW9WOxUmjw2hcqhgRW09OcrozgcvXaukkf1lZza5VQoPFtYo7PwvWjF0EL2soSR4h4AYEMs6WEeLWwXDYx1ucRrrBlMsQbUigrb2DdvLSfFiIL82fJm5WbIjW5aoSwcvlplQGJAT6R6CKPXTvOlxIM9hRZFqyOIrsHz3JLQS6E7hWVE9HTpepmI+R4X7db8qZEGACInjJYyAE3JjAwZOlVMvLi/A+7+UlgYHd+FGQoduQAALG7+KYj36+nrRkVpwNa5aqXIGACF6uMIsyBiHQTwLlVRwM+EgRzZ8aTcnxEgy4n/gkuxCwikBRaSPtO1FCS2fFUiwb4EsSAiAggpc8B0LAjQh0dnbS3mMlhLA/y+fGk6enaLncaPplqHYggP+5PRnF1NFBtGxOnPzP2WEOHK1JEbwcbUakP0JgiAgg3ty+4yW0eGYsxUfLt+8hwizVCgGzBMoqm+iTo8W0gA3vk+ICzeaRi+5BQAQv95hnGaWbEYDBfDjvrkKCvcknvKzozTsVl/CSh4eHaLnc7HGQ4ToQgQO89IjYjyvnddlVwo1LIDthFQ20A03UEHZF9owPIVypWgjYg8Dh06X065czCUsc+cX19M6OPJo6PoKWzo4TocseEyJtCgEdgYUzYmlOejS9tytPxX3Erb+8laNsLnXZ5NCFCYjGy4UnV4bmfgTgSfu//vcIlVY2qyXF2elRtHB6rPuBkBELAScgcORMGZ3mwNvb9hdQaJAP/f77c5Xmywm6Ll0cBAHReA0CnhQVAo5G4P2PrymhC/06yg5Rx4wMdbQuSn+EgBC4QWDSqDA6fKpUndXwcuNbH+UKGzcgIIKXG0yyDNE9CMB4d9POPONgW3nn4jvbrxrP5UAICAHHIrCJlxshcGlp677ryjxAO5dX1yQgS42uOa8yKjckcPFqjQr5E8XesqMj/Cki1FeMdd3wOZAhOxeB9vZOqqhuprKqJipnE4Fw/r9NHxvhXIOQ3vaLgAhe/cIlmYWAEBACQkAICAEhMHAC3gMvKiWFwPAT+Ofm4/T2lpPD37C06PQEgoN86cVf3ev045ABCAEh4NwERPBy7vlzu94XldVSY3sE+QWEu93YZcCDI1BanjO4CqS03Qicyb5OzS1tdmtfGrYtgSkTkjiOpfuKH+47cts+R1LbcBJgB6AenrIvZDiRu0Jb4jjWeWfxx8/8mzx9Qpx3ANJzI4HG+krWPN9DCXFhxmvudiCCl7vNuIxXCAgBIeBsBDjYgldAorP1WvprhkBAZ4uZq+51SdQG7jXfMlohIASEgBAQAkLAjgRE8LIjfGlaCAgBISAEhIAQcC8CIni513zLaIWAEBACQkAICAE7EhDBy47wpWkhIASEgBAQAkLAvQiI4OVe8y2jtQGB0vxT1NJU2++a2lqbqPhqRr/L2aLAQPtsi7aHo46a8qvUUFM8HE1JG0JACAiBQREQwWtQ+KSwoxGAcPPJ29+i1uZ6Y9dyjr1Fl89sNp7396C5saqboHVsx6+psvh8f6uh+uoCOvjvp/pVrr2thRpqS/pVxlzmgfbZXF0DuZZ16FU6vvPZgRS1qkx2xt/o6rltVuWVTEJACAgBexIQwcue9KVtmxPo7Gij0vyT1NHeFXi2piKP6qryB9zWmb0b6eLJdwZcfjAFMZa9735vMFU4RNnE0YspdfKnHKIv0gkhIASEgD0JiB8ve9KXtoedwMWT79K1nF0smLVR0pglNGHOBoKW7NTuP1IFa7HCotJo7rrvG/uVm7mViq4eJU8vbyovzKJFt/9c3Su5dpyyj77B131p+vJvUkjECKWZOrNvI9VV5lNkwiSasuhB8vYNNNalPygvzOTyf1PLY6FRqaoOeOO/fOYDunL2Q/L28aPxszfQ2QMvqjwQvsbP/gLFjpihqsnN+oiFyeuUvvB+dX7p1HvUwUJnZPwEs/VqbaPMmf0v0IL1T6lL5zPepICQGBo5fhUVXj5IF078k9pZaE2ddBOlpa/XiqlXa/o8Y8W3KDA0rgfP6rJLSmuI/hXlHqHzGX+n9rZm8vELpujEqRTIfWhqqKSq0ktKMzh62u2UMnGtatdSv64yA2gy/YOiCFrJkPDkbv2VEyEgBISAIxIQjZcjzor0adAEMg+9Qqf3/kX9VhSdM9aHD/dpS7/Bv1+jzIOvUE15rlqiqubXRbf9nBLS5hvz4iAuZRaFx4yh2OQZNGn+feTpafiukp+zm4W2e1hA8ldtIO/+939AQaHxNHP1t6myJIcyeXnNUoIAlDb5Zpq//kklWF08uYmFh2q1HDeLy09ecD8FBEcpgcjXP5QmzrtP9UOrLzgskXKO/YOFxkZ1CcupASyAmKtXK4PX1uY61gieMl6qLr9C9VUFVMtawUMf/kwJdxBGT3z8B9JzQwFzdZv2GREFsORnyhPCaA23BYH34OYnadysz9GYGXcpm7ekMYtV3Wf2vUDRSVMohYW+jO2/otaWBov9qi67rPKMmX4nC6PTqazgjHFMciAEhIAQcGQCIng58uxI3wZMwMc3iLRfT08vYz0T597Dmpca9UHv6x9MjXVlSljCB/n1C3soPnWeMS8OAoJjyD8wQmlxohImG+/NWPkoC2WzWTO0jusq4HpKqarkgtJwYXnQLyCMNWSZxvymB9DmQFNTUZRNPjf6ASEOQha0TigfFj2KoA3z9g1grVA63+sKmRLF5+gXtEGVxTlK45MwaoHSEpnWa9q2ufPC3MNKcIMgVlt5jfsWSeUF3ftvTZ+h+YPwaYknBEX8YmxxI2dRZ2eH4oA+pUxaS6On3qZ+PTw8qbG2lCz1q+TaCYphgWvE+JU0etodNGLcSnPDkmtCYMgI4EtbEf/fDFe6cOJf1NnRPlzNSTtDSEAEryGEK1Xbj8C4mXezlug/1G947DjVEdh9bX/9IbWc19RQRdRp6F986lxaeMtPqeDKQdr66n1K89RXzyEYIHl6+ag3QyxXInn7BJAXLz/Gp8yliXP/Q10z9+f03ufpyEdPU31NodICoTNe3n60esPz5O3tT9vfeJjyWRC0lBB3cOSE1ZR3fhcvnX5MyWOXqfLm6jWto7Ojw/SSEoagzUPf8TueNVLxad2FUHN1m+tzbzyRH0uq2//6AH302pcJ86QJlHoBWXHtbLfYr7aWRsVaG4jE7tRIuN8rNrp8+PI9Soi3NPrBblIxVx7/D7AftaZ9S/3q7brppp7cLIPZQ29lhutefXWhCIGDgC2C1yDgSVHnIlDHuwprK/NoztrHWTO0xvhGjWW2mORptPTOX/KbSZvS+OhHBiEAOwuhnbGUAkPilIYtIDiaNTC3K/uo8JjRlrJT4ZVDvKz3eRbO7jUKEMpFBQtU0Kahf2XXTynBromDymKJrrPzhqR4o9aRE9aob9ywdRrJ+ZHM1Xsju3qB0AONH944seGgJO+4uo7lVCwbQoBD/5PHLWNtX7S+qNm6zfW5N55oE+OAXdycNd+jsSx49ZYs9Ss0KoX5nFF2YxhLKWvAJLkngWC27Zu65KukfRkyR2Gwm1RMyzfzF7eiq0dY07qCrGnfXJ/6uma6qWcka3evnN3SV7Fhub/t9Qf4fXLgG5aGpZMO3IgY1zvw5EjXBkKAo+ki3XhRhyzM4EJweBLbEE2lLS9tYKPuQKUhwv2CyweUQTo0PVgCi7ihIcM9JNh97f/gh6yB2k23fXUTv8F7GN/k8WaPcy9vX5q15rvK7ujUnueUO4uJ8+5VGh1DLfjL5W50LHXyOjqx87eUdfAV8uMlQywxYtnzk7cfVcuMsG9afPsvuM+Jqu5Nf76F5t70OAtEy43VQfhAf5vZbi0mebq6bq5e3ND6DMN3LM9tffWL5MdtBnH96FdC2gLCUuWWlzeoJUxolJZ95lle6kxR9eKPubrN9dkcz2LeoIB2sIQJ4RZ5oIEs4WXZGcv/Ex1U99EOkoGT5X6hvxFx42nzC3crXkGhCaqUKix/3IoA7BZhV4jNMvgSYrpJIyohvccmFdgSZh95g79MHOZnMoJtKr+sbCgztv2SopLSKe/cduPGGQ8Prx7lm+rL1f8evpzAf5zWPo5hOxockUQFlw6ozS6wJ8WXt6Lco7w7+l/8BadG2SVOmv9F9R50ZOvTyrYyLDpNmR5cydxCUfGTemzqiU+dr+o2nVzDmCvYrvSi+kKF9x18+YEmHCYKU7l9/D+f3f//lN2mD5ssTGKbUXzZNJZlc4WG2mJlqoCl+6rSi4SNQvgyNnoqvkjebGwW9pftrc10bMczytwCXx6zebNMEbP05PfBUem38HvMCmN+OehJwIO/fXb/Gt0zj1wRAg5D4I+v7KZthyqVcGCpU9AOYReiljRNlfaNGG8mEHQ6eSlLM5ZvY0Gng+0ntGUvraz2qpYSWeOFXYqm9evP8e+EJQJf3q2HN1vTpM8LWye8qat8XLcH26JhZ2ILvzH7BYbzPYNCGnYdLc21aonOtD7c6+QfbRy4b7ZeEybwcwbbMS1pbWFJBSx82cYMwpppMlu3mT6b8lRzwGywXIIdmKvv2aiqxps42p656r94tbVTMcANPSecW+qXYRyBnMPwNqaNA2VMU3P1eXrvxYdNL8u5ExC486GN5BMy3mxPYU/48VuP0B1f30yZB16icyxQQWuMdPKTP9D6h/5JeSyQwUZq3s0/otDIFLp8+n0W/vfTrNXfpbzs7WrJ/ub7/04f8RcS/E/hecQOY/w/zr/5SX5mN3Urj125EG4W3vY/yp5Rax992fbX+9UGEdh/Hv7wf5Q2LpK/JGx7/UGaveY76gsgnvvEUYtoyuKHaMuLn6c5Nz2hBCHYbGLX8ZI7/48Fm9+o97m0KesJ9qX433v3j5+iWx/+l9EuEmNUY+Yd1rNW/bcSArMOv0ZJ7L5lNG88ObzlpzzG7/Cu65FKO44vV9dgnsC/N33x1a6yvKHH2ztA9XfVF55TG4ZiR8xUAhQ0yrBn1RKEsl1vfkPVGxk/kb+QfqIEzzlrHlOmE0e3/R+t/Nyf+IuRwcRDK6e9tjfk0h9/cgclxIVpl9zutevTye2GLgN2VQJ6oQtjNP0whuG64XrX42/J7YPKyH9g+K4l0/r15xBWYPRuKenzwh7MmFgAQ4IABa2QPkEgwxKhuYR7puKR2Xp1gijq8fELMled0q5Be2cpma3bTJ9Neao54I7iW3bW4b8qmxwvtmVrZ9s4uOjQ7mvt6jnhGvpkrl9d4zCloNUkr+5GQNukgXGf2v0nauFlQf0mFVyHxhXmAcV5GUrr1FBTRNBiIWkbZ6CRPc1aHzx3puXx5c3fZCleFeY/ePZhzoD3AggscJyMurH7VnORMm7mZ5UwB8HLXDK3qQf/e9gwVM9aNWyg0SfUC/cvjXXl/P/1Gs391A/VexY0/BCcoA2E65bywrOqGDTVWlJleYc10sVT76gdwtggA4EqPHZMjw1HWP7H+w5WBkIikqng4j5lNhGVOJnwezVrm+JqSfDS2nXn165PHnemIGMXAkJgWAjAHgaaBewChaavNyF1WDokjbgcAXObNEwHCe0RlsXUZpIANhNY9W21ZI182hc1PJ+WdhHiCxK+NJhLKK9pi71u1AENMIQmLXmxnz5o2FViAU3Tymv3zb1Cm97WZr5NbcyeXoYvcMYxcD9RN3Yo7930mBLONHMHrQ2tLM7BA5pnaPwusVYQ0SawLDuPBTlLqbW159gscbNUh7tdF+N6d5txGa8QsDMBfCgFhsSK0GXneXCn5iFE6TepQGvTycvvo+C+hDeTxKXOMWsaoDEyLQ+nw/0J5RUeO5bgdBmaLwgl17J3Ku0Q6vfzD1M7I7GcDsfIWkKb+k09zQ0VqiycDfc3QbMHuzHYm0GLpU/FecdYi1ak2oKT6DDeFITdmmPZz97std/jfvfcuOLp6aO+PEEYDI8ew8u1O1le61R1IL/e9Y6+LTk2EBCNlzwJQkAICAEh4MQEujatsKqJx9G17Kxt0ohgwQdLhtomFRjTH/jgR7R5411q2QwOiZd/9ndKU6Vpi/SaK9PysG26cPyfNzRVuvbVtpCu9rlyqNAocfQiun5xr9rYA4EKgt8s7gMSnAkf+egXaonQEJnCUN50Uw+iOmCJEcuQ3VK3MRvKaho3ffsXTryjNqNgg0335KHs0mBXiQgW6MPOv3+dNylUKHtPOFQ2TUk8nn3vPUHJY5ZS+qIH6MD7P6T3nrtV8RjDxvmxI2eaFpFzHQExrtfBkEPHJ2CNcb0tRwGj+vKCs92MS21Z/0DrstQvS9cttQMv9tgZaWlTgaVyjnBd+2ZtzvbLXP/EuN4cFee41ptxPUagbcbQNnHABkl/HcfQNJluUsHuYSytabaCWj2qMP/Rn+vL4/oHGz9NC275iRJU9Pn0x2rJjQUjTZhDmCxcM7WBhLYLfYctqb68flMPdlxieXTmym9p3VOvfY0ZwhcEMWwUwO5G/K/jGMulMMyHgDWddxZj6dNHF+IMLjOwAQe+98wluJLBfW1jDza6YAlVOzdXBtfEuJ5teS3BketCwBUImDohtGZMMEZVb5icGYaxB//9lDXFbJoni8MNwb7CUrLUL0vXLdVzbMev1TKHpfuOfH3fu4/x0kaxI3dR+jZMBLTNGEpLdUPoQtPadRyb26QCQUMTukzzm57ry6NeuFmAFss0n2mbmtCFfBBiTIUuw3Vf4wYefXkIYsiPZTzswhwz7U5k75b6GrOm/YJApH3BMhWO0C+90IUGsLPaktCF+6hLXw846s+RR5J5ArLUaJ6LXHURAnBCCNU6fOZYm+AccNXnn+vmw8rasrbKl8jbwbGrSpIQEAKOSQBLbErbNAzdg/B068PvKOHRls2NYyfO0PhJGl4CIngNL29pbRgJ5GYaQmzgGySMRuG2oCTvhFknhlq3TJ0DYhs23lzPHXmdHSLuZ4eIE5WBKuw04HMHcRXbWUBK5cDO2M6tJThSzGAHg4vYzw++NdaUX1VOGMfP/pxy1or72KIOD+5wFYFlhJDIEcqfELxwwwgXqvzI+Anc33fZGeIutQSB/mg2F+gXnDUWcqgjbO2etuzrWvPqFcsJ5pxEdsvEJ0Xs3DTr8Kv8jTuA7TUe4rrGKiNZOFBEcOvIhEk0ZdGD6ps3jH3NXTfneBJxG7WEANvwT7Rg/VPq0vmMNwkGyrApgb+kK2c/5Pb9aMaKbynnk+b6jWUatI25jBs5mzrYD5skIWBPAnpt1lD3Q1s+tWU7plouW9YtdVkmIEuNltnIHScnEJcySxmxxibPYI3XfVRfVUD73/+B8tw+ffk3lC+frEOvdRvlGHY6CEENu51GsFCAhK3gCBw9ZTHiJ+5mIegT5Tzx0Ic/Ux6nIQid+PgPyiu0VhmECgTRLWDhDAmerRFPEAJIGvvMmb/+SeXs8OLJTep+GduRwfh18vwvcZDpBCXw1HDAaiR44p629BtK4IOghXqR0C+4ZYB9RlnBGTrH/rH0KSfjH8pp4mz2qA+nkfvZABZLFqYJAmT6wgdZMxhPhzY/pfKAE3z5zGTHipUlOZTJS59Ilq6j/9mH32Ch8B61ZHJ671+6NQPv4rAn0xKCcWM+4A8JS6qzuJ3JC+5XjCz1O/vo31SIo6lLvqKWGLXlYK1OeRUCQkAIOAMBEbycYZakjwMiYOqEEE4TNSeG2O4MJ4aGUDZd1Zs6B8QdzSEidvtoDhELcw9TAO8wggABoQxOT+ErR0v4JgxtzrXzO9UlhO9ImbBWOVDEzqSKomzy8Q9mwanLkeGMFY+o3U8IE6RPE+feo+IrQmjz1ZVBv+CVGmFBRk25VcUu1JfrzUmkPh+0bnBsOpmXY+uqr3O4kAtUVXJBjRsx6uBwtrwwUwl55q5rdWmOJ+Gxu46FKmsSbFgQRQCaQ7QDLZmlfiOu5Bje4o7wSPD07QmfQ5KEgBAQAk5GQAQvJ5sw6e7ACfTqxLCXapXxqtqyDQeDBqeKygEjG6sqB4wsAIznLeHxafO61TJy4moVCw6776DxiU+dy6E4nuet40+r0BrYvcQGFsYy3bzC37gKO6/trz+kluOaeJeRLrvaKaUZzmI5E6GD9EnvJBLLmXonkfp82nKJ1w1P+m0tBieN6A/GF58yl4N5/weHLDF/XatLqwfLsOa0UZ0dPYOMo9+rNzzP4Ur8afsb0CjuUaFRNOeW+n5jPNrSCMZt2DivtS6vQkAICAHnICA2Xs4xT9LLARLQOyGEE8NLp99T9lP4QNc7MdRXrzkHDIkcqb/c7RiasUu8TJg8dpna/YPdk6Y7gJAHgbkRu2zEuBVqCbPwyiEVXgNaoYO8rNdXquNdlbWVeYT4aRA8co79w1gE27ex7Ik+XL+4hx0ZjjbewwHa15xEQlCBk0TwME1YBoUWKZ/rAheE+oCXbQQAhk0ZBEQVf5I1U+aum9Zn7hz1tjTVqPAliJEJ7VUIe7GHHRv8HEFbBpu0suunLPY7hJdLYWeHIN952TvYtq7FXFNyTQgIASHg0ARE8HLo6ZHODZaA3gnhrV95R8Ud2/LSBiWAQDDRnBjq29E7B5ww917lEtF4/4ZDxIS0BYSAs1te3qA8sMM/zrLPPNtjJ2TqpLVKy6XFaEudvI5O7PwtZbGtlh/HdMQyG5LS4KBuLSkNm4cS3BBvDX328QvUCXceSuDLPPgSHd36NAWGxatlRwhjmi7IkpNIrQm8ol0YzL/7p5t5K7gXx5h7TNlozWK7MGw0OLXnOdbW1dPEeffy0uzdZOm6vv96DaHWFnaWQmDaykGI/XjMQWo51UMttX7y9qNqmRE+lRbf/gu1Td2cc8uJPBd73/0evffnW5V3bf9AxLQUvZfGWF6FgBBwDgLiQNU55kl6eYPAQByo6p0QohpLTgz1kPXOAfUODdUSGgsr2rIaHB9iCdOX7ZMgfJhLWC7Ua5qgufLgoNjqGu9MxG4lfRuow9QpIozQIaRBW6T5yoGGCP1AX7XA3yhrWpepk0jk0ZKWF9oo2Ixpj7JZdQAAQABJREFUdeM+DPGVpouD6+r7b+66Vo9pvdq59gohDk4XtYT+YxwtjTVKkNS44r65fqNtbcnRtE2tTkuv4kDVEhnHv37ngxvJIyDF8TsqPeyTQEfTdXruf+6ihLiwPvO6agbReLnqzMq4jARgwK1PpkuC+nvaseZoEOd6h4amW7rhNb0vz+l6oQX1dbPlYgEMSd8GzpUAopPjNMHKw6PrX1YTkrR7KIdkWpdmF2W42/2vllfTvOnvQpA0F8Ta3HWtHq286bl2Xe+sUruGcWBzgmky12+0rV231IZpPXLu/ARmTxtJRaU1zj+QXkbQ3uFJzW1+1NbhRd5ebRTg3cTvA70UcNJb3l5h5O/f0+TBSYczoG53vYsPqLgUEgJCQAgIASEwtAR+8J/rhrYBO9aee72OzuRUUliILy2YHkM7DxXS4pmxtCejmPx8vdQxXiW5DgERvFxnLmUkQkAICAEh4AQEsGR+KruS8grrKSUpiG5d0eVsGN0PDvShm5cmU11DqxLEfH0MApi/nwhgTjC9fXZRBK8+EUkGISAEhIAQEAKDJ9DS2kGHTpVSVU0LzZgUSdMn9lxi17eiCWD1jW308ZEi8vH2VBowEcD0lJzvWAQv55sz6bGLEIDRfzl7fIdTVmdOjXXlbAhfR8FhST3sy5x5XNJ3IWArAtW1LXSQBS4EjsByYjgvK/YnBQV406eWJFGXAObBAlgciQDWH4qOk1cEL8eZC+mJixLAzkfsDgwMie02wnr20XXw30/RHV/f3O36QE/qqwtVG6YbAAZanzXlMg+8RFcyEWfRn4Wvelpy5y+VHy5rykoeIeDqBPKL6unEuQoKCfKhlXPjyXeQtloigLnGE6NzHOQaA5JRCAFHI4CwO/A/NdRp2+sPsLPV/KFuplv9iGm5/sG3aN2X/qoCV2cf/Xu3+3IiBNyRAIzl3991jUoqmuiW5cm03AZCl56jJoAtnB5Ln/AS5I6DBdTULEHj9Ywc+Vg0Xo48O9I3pyIAf1pn9/8/FSzbxz+EJs27j72/x9DZAy+qgNgQvsbP/gLHi5xhdlwIVo2Yhe3s9yt10k2Ulr5exUhEcOiGmmJ2zprKAbG/qbzLXz7zAV05C02TH81Y8S3KOf4Wtbc207Edz6ily0kcd1FLiAd5dv+LHFfyMi8HJtLkhfermIhXsz5SAbirSi+xR/kCGj3tdhVLEuXgEf/SqU3Kb9j4WZ9X4ZCyj7yhQiD5B0VwQOsvK80WvNtrCXEWK4qztVN5FQJuRaCtje23TpdRRVUzTRkXTret7G4wPxQwAnkJch0vQTawDRgEMC8vD1oyS5Ygh4K1LesUjZctaUpdbk2gqb5CeZqfd/OPKIa9zR/f+RsVdgfBsuEnayILYvCWby7VVuTRoQ9/pgSzCXM20ImP/6AEOATGTpt8M81f/6QSvi5ymCI4Uz2+81n2VP9tFoDuZwesnjRm+p3KvgoaqBHcnpawe2rfe0+oPAioDYFw36YnWKDq4EDW1+nMvhcoOmkKpbCgB0/1cFoKQezI1p+rMEcT597H5xcpJ+MfVMSBwWezR/tQDt2z//0fKgeraAee76HpgtAI7/SShIA7Eairb6VtBwrU76RRYUrgSksOGVYEmgC2aIZBA7ad+9PYhFiwkhyRgGi8HHFWpE9OSSA0KoXD+gSzluqs6j80TXCuCk0VvLVHJ6ZbHFchCzUBQVGslbqi8sChaHlBJo2d+RkWwLLVr49/sAqxA3sqCHIQdCawBg2aJiTYdkXEjuPzZHWOPw21xVRVcoGW3/075Xh06pKv0iYOD1RfXaTypHBIo9EsrCGd2v0naqwtpeK8DBYQxyoNGK7Hp86hXW9+g+3H4tQ9OKBt4LiPTfXlSrAszT9FuVkf0uI7/o8i4yegiCQh4PIECksb6FhmOQX6e9NSB9EyaQJYAwtdu9kPmKcna8DYJ1gA91GS4xCQ2XCcuZCeODkBCEp7Nz2mlgi1eInWDglhcODB3cvLsNtp/KzPUezImSrOY8Hl/TRywmoVCogD+ah4jas3PE/nM96k7W88THPXfZ8DZS812xTCGSE8kea9X/Oyj9BDSIjPqCV42Md1hPUJ4tiK+qT6By/93D+vAF+aterbxjBFqBPCnwhdemJy7KoEzl2uogu5tRQfE6B8bUG4cbQEYXDdYl6CFAHM0aZG9UcEL4ecFumUMxKApigqfhJNW/o1ysveYRwCBJqm+kolOEErZS6mI5YgL/EyYvLYZSpmIXZBQrNUeOUQLz9+nm2+1tHBzU+pOmFLhlgiM1Y+quIcll0/pQQvT08f1oiVUkjkSGMbQWzTBcHoWs7HhCXPvHM7OAxQJAtWCcb+mR6ERaXRlTOb1U5MCFpFV6EBG0Od7W2EpUz0v541XloopLDo0ap/pvXIuRBwFQLt7Z105EwZG8s30qTRw2O/ZQt25gQweMXHdUn2IyD07cdeWnYxAomjF/Hy3zu0+YW7KVCnMYqIHauEn01/voXm3vQ4JY9bfmPk0IsZvi0npC2ghFELaMvLG1R8xLaWRlr2mWcpdfI6OrHzt5R18BUWyCLUEiOWMD95+1GlcYJN1uLbf6HqS+L2Yc+VPGYpwc4MCZou2IId3/EbOsl2YxD8oCFTcQ5VILiub+uGvnhQ0tgllHd+J/37hc+q/GNn3q2M6Q988CPavPEudQ1G+ss/+zvVRhELhxfZED9pzBJ1Ln+EgKsQgNH6gZMl1NTSQfOmRCsfXM44Nk0Ag90XQhHhy9PiWSKA2WsuPdj4ll26SRICzkHgj6/spm2HKs0Gb3aEEXR0tBGEJgTZxrEWyLqzo51ammvVjkR9PztYi6QP9gyfX1ge9A0IM2qtsMyH5UKlYWKjeAhPqLulsUZpx1RA7RuVQhsGezKtXa0t/Ju3NHF+rldLMLDntUVVH66Z9gX94IZZeAvQiijje5TRB7tG3Z0YK2v2HDk1V5+n91582JG7KH1zEAJwA3GUNVx+vp60kA3Wh1NDtHXfdbVMOJQoRAAbSrp91y0ar74ZSQ4hYDUBCDwQupD0wg+EJb+A8B716IUu3MSyoGaHpWXWCz7EAhgS6oYBvmnS2ja9jm+4eqEL95XA1qXw6iYA4r63byBeuiUfM9dQt4eDC13dBiEnQsACgZzcGsq+Uk0xEf5K+IF7BldMMLa/iW3AIIDtPVaihqiWINk9haShJyCUh56xtCAEhIAQEAIOSqCjo5MyeHdiUWkjjU0NodtMAlY7aLdt0i0IYGsXJSrnq1iChPYafsCwO1LS0BEQukPHVmoWAkJACAgBByUAT++w36pvaKM56dE0l2243DUh5qMIYMM3+yJ4DR9raUkICAEhIATsTKCcPcsfPl1K3l5sv8UBq4M5jqIkA4FuAtixYrYlNWjAEKJIku0ICE3bsZSahIAQEAJCwEEJXM7nkF4XqigyzI/WLkwkb28J3GJpqpQAxoygFdwjApglTAO+LoLXgNFJQSEgBISAEHBkArBZOnGugvKLGigtOdit7LdsMS/mBDAY4QcHipZwMHxF8BoMPSk77ASwg66zpZw6POuHvW1p0LkJtLS0OPcApPdWE2hpYfutU6VUU9dKMydF8m+U1WUlY08CegFsL2vA4FAWfsBEAOvJyporInhZQ0nyOAyBu9dPp2XzxzhMf6QjzkPAk4V2Sa5NoKqmhQ6xwIW0cEYMhQYbQnC59qiHb3QQwNbcWIIUAWzg3EXwGjg7KWkHArHRoYRfSV0E6tm7dsbZMpo3NYbwxihJCLgbgbyCOjp1vpLCQnxp5fwE8vUR+62hfAY0AayZNYsQwNraWAOGJUjZqGAVdhG8rMIkmYSAYxI4ca6crrH9yvLZcQSP12NGhlD62AjH7Kz0SgjYmMCp8xV09Xo9jUwIoluWJxujPdi4mWGtzpn0sn6+XrR6QSJpAlgrC2BLRADr83mRkEF9IpIMQsDxCNTWt9LHh4s4YG8YjUnp0gCeu1xFF67W0mr+1i9OEB1v3qRHgyfQ2tahlhMrq1to2oQISkkMHnylDlIDbKd2HS5Uy3kO0qV+dcMggJUQ5kgEMMvoRPCyzEbuCAGHJJCRWUbFZU10E3ucNrclHobFH+0voKS4QDEqdsgZlE4NhAAM5Q+yw9N29i21gP1vRYT6DaQahy4DgQUe5FfxFydnTngP2sOhiDAeLEGGyBJkt+kUwasbDjkRAo5LoLKmmXYdKqLZ6VFWfcu/mFej/BatnJfARsay/dtxZ1Z61huBgpIGOsYhfbCDDgbzWN5y1QSBZf+JUloxL94lhqgJYC2t7SoUkQhghmkVwcslHm8ZhKsTwE6t6toWtQTh6Wm9FUhbewdtY+1XNAf9deeQKK7+fLji+DIvVtGlvFpKjA1Qmtv+PPfOygMOS+FVf9kc1xC8tHmAALb3eImyBVs8M87tvwiK4KU9GfIqBByQQFllE31ytFiFNkmMDRxwD7Hr6+jZcvVNGp67JQkBRySALwpHTpdRWWUzTR4bTqNHhDhiN4esTw28Q/lYVrnSDg1ZI3asWAQwA3wRvOz4EErTQsASAXjc3sffEFtaO2jF3Hiyxbd9xF3bcaiQgjnu2sIZsZaalutCYNgJwCXKgROG533e1GiloR32TjhAg3W8aQZuMRaxXZQrJ7yv7WM3FE2sCXNHDZgIXq78dMvYnJJAYWmDsvNYyi4iYiP9bT4G2MwcOFlKQ1W/zTssFbosgeLyRqWJDWD/cwhYHeDv3h6OaupaKPNitdo84LKTrhtYdwEs1m0c3orgpXsI5FAI2JMANFK7eVnRk30/DrWNBzRqHx8pIi+2F4MAhlBMkoTAcBHIvlJNOVdqKC7an+akR9tEoztcfR/KduB5H2zmT4sZymYcrm4lgB1nDRjbuGEXpKtHHBDBy+EeQemQOxLIK6yno2fKht0Gq7SiiXbz9nVoGwZjQ+aOcyZj7h8BfLE4ws94SXkTjU8L5d+w/lXgBrkrqprp4rVat90IoxfAFrE5BCIRuGISwcsVZ1XG5DQEYEwMR6hBdra7QtgPvOnZyp7MaSZAOjrkBBqb2H6Ll7bxOmdKNMVFBQx5m87aADbT5PJGmNmTo511CDbpN/x/4T2pscmgAXM1AUwEL5s8JlKJEOg/gUv8zfbEuQpauxB+tuz/za6/fsL6P2Ip4U4EIEQc5h2KiJuIzRz4ciGpdwIlrIHOL6oXx8c3MEEA28eOWBtYaMeGg3AX0YCJ4NX7/4HcFQI2JwDN0i7eXRgb5e+Qb7DwGQYv4SvZiaM5z/g2ByIVuhQBOO7NYgPx6Ag/mss7FL29JGC1tRNcVNZI+J0+IdLaIm6Rz9UEMBG83OKxlUE6CgEYzmZdquJwP0kOrQGA4LX9QAFNGx/RLRako3CUfjgWAdhvHWf/UwUljTSaA7VPHhPuWB108N5A+/3yuxepjTU8bRyvMZRD7Ny6IplmTIxy8J4Pb/cggO1nNztwP2JOA4b7Pt6OL+iL4DW8z4205qYEsFtnJ2u5RiQE0dRxEU5D4cS5ciosbVRBt31dOFSL00yInTt6Ob+W4yWW0j23jFI9wXON87qGVpo1OUo2aAxwfrDL+LvPHCNsskEKD/GhP/xgnkuHRxogKlUMAir8HNaxALaYl7HDQ30JPtCefuEM/fhr08if3ZM4chLBy5FnR/rmEgTO5FQSvtGuW5zk8G8I5oDDm/Y21n6NSw2lSaNFk2GOkTtcq+KQVU88e5zqWch6+lsz6TQ/13BHAvsticE3+CcADmR/+9dzqqIv3TGabl6aPPhKXbwGJYAxt7qGNipi/4fbDhQq9zjf3DDBoUfu+Do5h8YnnRMClglAHf7+x9eU6vuOVSOdUujC6ALZKBr9x3LS5k+uqd1plkctd1yRAD7gnnk5k8rZ3UFTSwe99dFVFTf0Jv4yIUKXbWYcvrsSYgIoMsxXsbVNra5dC2xQl3NcS2i9EJUDaQ+7x9l12HDsqKOXbSaOOjPSL6cmYLB3aVBaLuzqcoWUPpbtvUaGqqDbKUlBbP8lBsCuMK/WjOGFf16gnNwaY9ac3Gp2ums8lQMbEEBYsDtXj6RW3nzjDHZKNhiyzarYuu86fzHsqu6ldy6q96qRbNrhiEmWGh1xVqRPTksAIT92sV+uKWzH5coBfvHBe+5yNa2an0DBgT5OO1/S8b4JNHM8PSwrNrM9F7RdOMfv4llDE9Kq7x65bo52NqzHj+wE7d8cZ/N7EewNSfdlICrcj0bEi+DVP5KSWwg4GQF45YbvorWLEt3ijRM7iLbtL6D46ABlWO1k0yXdFQJCQAjYhYBovOyCXRp1JQIV1c3K+zy8cjuqansoeV/hnW5wBLuStV+u4uBwKHlJ3UJACLg3ARG83Hv+ZfSDJICdSNjSvJqFDthouGvCEsn2gwVK8HK3AL/uOucybiEgBAZGQASvgXGTUm5OAKE9sHtm0QzsRAp0cxpdw0e4k0McJgYxH2FjIUkICAEhIAS6ExDBqzsPORMCvRKAo0MIXO3sWgHChYds7erBC24nsMHAz9eTFnN8NWHUA5FcEAJCwI0JiODlxpMvQ+8fgYKSBjrAXrqXzY6jmEj//hV2w9yIOQfv0hC+YIAvaXAEDh6/TC28m1CSgcD0yckUFjLw56q1tZ0OHLssOHUEFs0ZPaCNQZeullJ+YZWuJjm0RGDOtBQSwcsSHbkuBG4QgAbn4yNFBH9cS3gLvSTrCWgaQvjYWTYnzq3t4KynZj7nbff/hbx8JXIA6LQ0VdP/Pn4LTZmQZB6WFVerahroC998hfwDxR8dcDXWl9E7Gx9mh8m+VtDrnuWZ53fQJ4fzycdXvpB2J9P9rKWxiv70P3eTOFDtzkXOhEA3AlcL6ijjbDnv2IuniFCxWeoGx4oTLDMuY8/S8Hj+zo48mj81mpId1LeOFcOxaxZPT0/yCUywax8cpXEvT9to/gL8/clbmBqmtb1uwNPLFhjk5RdJPgFhA67DHQp6ebSqYbqGS213mDEZ47ASQIgU+KhCgOi71qaI0DVI+jC0/wxzRBDg7Rz3EbsgJQkBISAE3JGAaLzccdZlzL0SuHi1hk6dr1Tx0kKDxSt7r7D6eRMBlRFs+d2deTRrUiSlJYf0swbJLgSEgBBwbgKi8XLu+ZPe25AADJe37Mmn2oZWpeUSocuGcHVVwckqtF9Yfty69zrBA74kISAEhIC7EBCNl7vMtIyzVwLnLldR9uUauonD/QQGyL9Fr7BsdHN2ejTVsZD7wSfXKH1MOI1LFfsQG6GVaoSAEHBgAqLxcuDJka4NPYHGpjbazB/8sDm6c/VIEbqGHnm3FhBg+9OrU6iRA9xu3p1vCHTbLYecCAEhIARci4B8tXet+ZTR9IPA6fMVlHu9XgW19vfz6kdJyWprAtPGR9K4lFD6aP91Gj0ihNLHRti6CalPCAgBIeAQBETwcohpcL9OFJfW0CM/fpva2EfWcCf4lmpmey5vL0/y9vakTVv86KVn/mO4uyHtmRAI8Pem21eOpKxLVfT+rmu0ekEC/fK5j+jM+UKTnMN/igAFj31tNc2Zljr8jUuLQkAIuBQBEbxcajqdZzCtbe3U1ulNnoEpdul0YFBXsxWVOV0ncmR3ApNGh9MY1nptY7cT5y+XEfmnsONV++4ubWssoobGFruzkQ4IASHg/ARE8HL+OXTqEUgcP6eeviHrvK+vF92yfAT9/R1WNZGHxHscMtJSsRAQAsNNQIzrh5u4tCcEhIDVBBCmSZJjE6gpz6Wi3MM26eSFE/+izg7beKW3SYccoJKO9lYCF2tTweUDVFt5zdrsLpvPls+lNZD6w13e1awhKnmEgBAQAg5OoLL4PH348j3U2WnZL1p7Wws11JYMeCTmyp/e+zzVVOQNqM5mjl3X0lRrLJubtZWKrh41njvaQdahV+n4zmd77ZbpmHrNbOZmfXVhN+Ez7/wuusa/SNa0D4Ej+8gbZmq2zyVrnkv0zHTc/eltX8/ljjce5i8HR/pTZZ95TdvsD3cRvPrEKxmEgBAQAo5PIDg8maYu+Sovy1p+Wy/NP0l73/3egAdjWr65oYoFpSM0YtyKAdV5Zu9GunjyHWPZkeNX0pWzW4znjnaQOHoxpU7+VK/dMh1Tr5nN3Nz2+gOssco33rnKwugI5oJkTfuYi/wLu6m1pcFYhz0PrHku0T/Tcfenz309l5Pmf4kiYsf1p8o+85q22R/uYuPVJ17JIASEgBBwfAKtzXV09dw2ShqzhK5mfURNDZVUVXqJNQkFNHra7RSVkE5nD7xIDTXFSvgaP/sLFJ00RWlHCq8cJv+gCJq84MsUHjOGMrb9kqKS0inv3Hby9PKl6cu/yQKdV4/yTfXlFBY9igKCoxWgotyjLEj9i5obayh2xHSaNP+L5OXtR0e2Pk1oLyw6jSqKsulK5haKip+ktFueXt5UXphFi27/OcWnzqfMg684LOzqsktKQxcZP8Eso/KCzB5jKmYmF078k30FtlLqpJsoLX29mgOMMzgiiQouHSDUN23p1+j4rt9Se2szHdvxDMWlzGZmn6fS/NM0a/V3FJO+2g+JGEFBYQkUGBJLZfmnKGHUAruz1D+XePasGfeEufeYfS6tfa5Nn8uCS/soMDSW2tuazbbv6eVDjXVldHb/i1RdfpmCwxJp8sL7CTzNPbvjZ32+x/9C7IgZVnO3/NXI7tMlHXBnAt/cMIHefGYpzZ4cZcQwc2Kkuvbw3WON1+RACExIC6VXn15EG59aQEmxgUYgc9Kj6G+/XEIzOSakO6TWlnoquXZCDbWu6jqd2feCEqxS+MM+Y/uvyNsviEaOX0W+/qE0cd59SsDKyfiHss+avea7FBqZQvvf/yEvVXZSWcFZyj78Bk2Ycw95+/jT6b1/UcKVafnqsssUFBKn2qzl5cb97/9AaWemL/8GweYl69Br6l7Z9dMssNSo42YWCMu5/riUWaoPsckzWEC7j3euerPQEK8+HPHB6YipjjVRNeVXDGMyw8h0TPVVBXTow58poXPCnA104uM/sOB5jrVR9ZSb9aGyxZqy+CGlobqW8wmNmX4nC7reNGrqbcxxFbd1leejnT/QDYz7al9jFhgaT3UscDtC0j+X1o7b0nNp7XOtfy7BAM8ztLOW2sczv++9J8jD01MJuT7+IbRv0xNq2d7cs4svGqb/C2jHWu4ieIGWJIcjcOBkCb8Re6iYiVrn7uL4frh28GSpdklehQDB+z18gIWH+tIXbx9tJOLDPtrgpw2v7phSJq2l0fwBjl8sP7bwB09oVCp5+wZQdGI6C2AhSjjCh3pxXobSTDXUFJEm9MxY+ajSuqROWkd1LEB4efv2KN/cWE3+N7RdELSg5UqZuJa1a5Np3MzPUnEv9loBwTHkHxjBH1ZxKj/myNsngHx8g6ieNSPOkEwZmY6pkDcdBARFsRblihKy/IMiWejMVEPz9g2kOWsfZ2YzFGdoJqFt9PD0UstiIRHJSlj1CwhXwpg5Hqbta3kgGGAuHTFZM248S5aeS2uea/1zacrAXPsNtcVUVXKBpi37BrMfq5bs66ryWVtsnqG5/wW0Yy13WWo0nRU5dwgCx7Mq6NK1WuXFfNr4CGpnR6tj2bN59pVqOnOBP0CCfWjRjFiKi/KnkoomOnCilKpqDX6WQoK8acXceIoK96fK6mbadaSIaupaHWJc0omhJTCdtaJTx0XQ6ZxKsw0FB3rTgmkxlBQXqJ6JU+cr1XNmNrOTX/TkD3AtYSkFmhPT1NbaSJ4sUHnxcqJXgC/NWvVt8gswxMzUbMVUWQs7DaGlam9tUtW2sU0RhCYtefn4UYdWjj3Q9mb0r5WB5qGtzVCfds2RX/tipPgyI/BFGj/rcxQ7ciZhpyLKau50vDA/GivdgCGEoQ5LyVL7bTwn+rmwVN4e160Zd2/PpTXPtf65NB2jufbx7GIpHdpdJAhWSOp/xspnF/mt5S6CF2hJckgCb3+US48/OIW9mY9Qghc6+dbWXIqO8KOnH52pNBwdLJBBC3bnqpH03Wcy1Ifpzx+ZSfExAUoQCw/x5W+LHvTO9jyHHKN0ynYEDp0qpfksVN176yh67DfHelSM5+Zn/zmDBXI/473Prkul5948T7sznEPDYuz4AA8gRDXVV/IHf5vSrEDD0snHWNqCEFDPWhLksZRMyweExFBJ3nGVPZw1BZdOv6c0ZtDSXMveSVGJk9U9P/8wwu42aMJy2f5MS6gPuywhlOEDsbmhQgkggVyvsyb9mMD30slNlDx2GfkFhrPtW5XSLGIHn6UEZ8GNdaUUEsmxY5kD7JKw8xMaSmtTIzONjBtvbXaHyKcfty2fS2sGF8Q2XRC2ruV8rJYQ887tYG1sJAWFJlBvz67+fwn/P9Zyd08dvDUzIXnsTkDTeiFuH2L5ZV+uprOs7UJQZSwrbXwrh+59bK8Kch3GAtbK+QkslPkroevImTJ6+MmD9J1fZcjSpN1ncng6gDnHM5KaFEzLZhtsYvQt37UmRQld7+7Ioy98Zw89vfG0un0PC2qukdjRLP+oxB8CcDyrJcN1D7WMgg+YTX++ha7zzjcY09dUXKXNG++izS/cTUe3/uJGcTitNXw86DUEWIbRl4+Mn0iwp4HglDh6ERvHz6MtL22g9/5yu9pVh/qRxrGm5+yBl+j95+9gLRi0z4a+JaTNZ0FsK7333G18vU1tBvDnpTks2Tlk0nHFB605RvoxxaXMUQbuW17eoFx9bHvtfl4ChDsPzEjX/LAUzJcM50nMEfZGRz78H7Z5S1I2eVWlFw04rGgfHOHaAHPjGEk/Vv0xMJgft6Xn0sCoi5uBYc/nWv9cgkHXXJlvH5quWau/Tcd3/Ibe/8sddGb/CzR33ffVEq+lZ9f0f6E/3D1YtTv8wfIc42mQXtiRQH5hJT36k/fJKzC1117AoP7xh6aoPD997pQSvP7vv2dSWnII7TiIb42dFB8doIIq7z5aRC/88wK98JMF5Meez/cdL6Ete/Lpcn5dr220VJ+nTS8+3GseuWkfAl/+9utU0xbPSzWWtTDYgPG9B9Lp96+fo6KyRvr5ozOoorqF/vHhFfr6FybQr1/JpMOny+iZ786m2Eh/uv+H+6mt3fC298OvTlVLkw/9+ABV97Ic3dpQSN/60kxaNn+cfUBwq3c8uJF8Q3vXYkCTBeNstazHb+1YqkLSruMYS1otzbW8pBiOU5WU6wHO78MG+Ej6/Kbn+vLI98HGT9OCW36ibJWQFxoa5IEtjT7B7xH6hQ85ff1YnuECKj92U2Lpc+bKb+mL9jjuaMqnJx9ZTlMmJPW4Z+2FqpoGuv87b5J3cJddYF9l9Vz1Y0A5/bl+TLiHsWM5y5eXcSEEIOnzq2VGnSAHDRds8bBkppjw8z9z1X91m1d9eX192Fl69KNf0C0P/5PbMgjPqsE+/rTWXqA3fn8fBfKSc3/Tr/6yg/adajAuU5uW1/dVf9zbuFGH6XOp54/7pnVpzzWu659LfT79sWn7EIewCURbbkcbSJaeXZTX2rSGe0djHj3z/ZvJ+lkxtC9/hcCwEjh+rkItGZZVNimhC43DmBopKS5A2ep48VLiuctVdIUFrJbWDvrFC2cp93odLWWtx//+9yxatzhR5Zc/rk/gYl6tsvfDcuK6Jd0/lGH719DYZhS6QKO9vYM/zDr51zXYQOhCUlqqbjZeXVYlEMb0Qhfy+7CQpAldONfqwTGS/lxfHtdHT72drl/ca8jIf+E+wlTowk1oyjQbGn19uIb8mIeCy/tpzLQ7jXU52oGeq34M6Kf+XBuT1n+MHUuNmtBlmh9M9UISlhUhdCGNmfFpdjmxXx1b0/71i3to9PQ7utWnCtvxj56N/ri3caO7ps+lfvy4b1qX9lzjuv651OfTH5u2j/kxFbrQjqVnV/+/0B/uXf+NqF2SEHBAAm1tHdTKv1oqq2pSS0a/++s5pdnQrmuvMMB//NnjNGVsOP3gK1Np7pRo2rqvQLstry5O4O9brtDcqdE0irWi+lRe1ayuxbCtV2llM3+wESXHBfESF3vNZoFM0sAIpC96wKCJGVhxYyl86N368DtGLZ3xhpsfwN5p/UNvWU0BmjG9EGd1QRfLaKvn0los/eEugpe1VCWfwxA4lllOE0eF0xO8BLn9QIFyF4Clxz03DKS/dOdo2nWo6P+3dx7AcR5Xnn/IOefADDGAmWAOoiiSClbWeh0oZ1s+p7LPJ3trHe6uzj7ZVV7XhvKWg1ySk7w+B2WLpEiKCsw5gSDFBBJEzjljcO812MCHwURgwjcz/2YRX+r46+5v3vf6dbe6L1p9McCHCx0CMst194EqemTLtHGFPlnaREXTk+m7X1xCMiy9mGc/ZvHQo7QbmTULN3kCnvqhFw0C3EQC7vB1x+/ElILrji9ZuJMWBK/gamdBWRoZBjIOBe18v4qXkYijLWty6QsfHrG5aeZlI/awECZDSTIU+ak76znJj/B/vVkelFxQqBECum0YzVVf2nuL1rDWK5vbSU/vyDIKf3+vUrWbTSuzacfDs3nI0UIyE/I3r9wxXAZQEAABEPABAQhePoCMJKZG4Bs/Pj5O8BLDaDGif/7lq5SREkN9bNdlXKdLZjOKjc8Q+9Nre00tBwhtZgKnyprU7Fax79Oum4Wtrz17XA0nylCiOHn+iz9/QM/99Qqlp0RTSzsbPN8xsh/xgb8gAAIg4H0CELy8zxgpTJGAvR9H+UEVWx1bTux54EKHgFHoMpZaC13GezKsaK/dGP3hHARAAAS8QQCzGr1BFXGCAAiAAAiAAAiAgA0CELxsQMEt3xAYHIRBs29IIxUQAAEQAAGzEMBQo1lqIoTyIWtyyfIOvb2dFBVV4feSDwxiKQG/V4KdDMgabcOdVWSRtR985GQW7ADbfkXz5toyK1Zcf2/XyIkf/w5Lvvr8nw8/IhhN2jLgmb1XBweHaBhMFVdhMRUni8bqtcemEk8wh9XtFoJXMNeyycoms84OnKrnTXAt9MnH5tGWVdmmyKHs9QhnTgI/eOYh6unxzI+sOyW0cFuVLYiio8JpOe+eIBuN5GQluxOFx/1uXD2Hmlu7PR5vIEYYEZFBqSnjV8Z3txzRUZG0tDiP30f48BJ2UVEFvEPE5D5wlhYX3GmbYOmoHUZGZFNiQgxhyyBHlPDMYwRkKxfZwmdTSbaa0u+xiBERCHiRQG0Dt9szaLdeRIyoQSDkCEDwCrkq922BZdjm3eO1FMnDNiJ0GbfM8G1OkBoITI6AaGplkVWZIbl5VQ4Pp0BDOjmSCAUCICAEIHihHXiNQGVtFx3lzYm3rM5V62p5LSFEDAI+ICC2ie+eqKO1SzPVVkM+SBJJgAAIBCEBCF5BWKn+LpKsCL7/WC2vIB9J65eZw47L30yQfvAQOMxDj7K3471r8tgmBtqv4KlZlAQEfEMAgpdvOIdMKjcqO+jspWbaujaPUpKiQ6bcKGhoEZAdEd4+UkMlCzNoZkFiaBUepQUBEJgSAQheU8KHwJrAAM9U3Mc/RFnpMbRyYaa+jSMIBDWBE6WN1Mi7J2xbl6c2ZQ/qwqJwIAACHiEAwcsjGEM7kg/K26jsehttX5+nNqgObRoofagR6OwaoL380bGwKJXmzvTvkhOhxh7lBYFAJADBKxBrzSR57u0bYi1XNU3PS6Al89JNkitkAwT8Q+Ds5WaqrOum7az9iomO8E8mkCoIgIDpCUDwMn0VmTODpVdb6MbtTqXliovFOrzmrCXkytcEenoHac/haiqanqw0YL5OH+mBAAiYnwAEL/PXkaly2M2zufayluuuGclUPCfVVHlDZkDALATKrrXStYoO2sbD7/H4MDFLtSAfIGAKAhC8TFENgZGJM5eaqKq+h+7joZRoDKUERqUhl34j0Nc/pGy/CrPjaRlvOwQHAiAAAkIAghfagVMC7Z0D9PbRGlp8VyoVsaYLDgRAwHUCV2+1U+nVVjXzMSkhyvWA8AkCIBCUBCB4BWW1eq5Qx883UHNbv/rRkG1/4EAABNwnIBvDy8zHjNQYWr0Yy624TxAhQCB4CEDwCp669GhJWtr7aP/RWlq5KINm5GOBSI/CRWQhS+BmVSedutikFhhOTcYCwyHbEFDwkCYAwSukq9924Q+drqdunp0lq89jQ2DbjHAXBCZLYGhomLfUqqGEON5Sazm21JosR4QDgUAlAMErUGvOC/luaO6l907W8f6KWZTPBsFwIAAC3iNQxWt+HTnXQPesyqHMtFjvJYSYQQAETEUAgpepqsM/mRkeHlYC17CFaDP/CEDL5Z96QKqhR8Bi4b53oo77HNHdK3MoLAybbodeK0CJQ40ABK9Qq3Gr8tY0dNOhMw3qpZ+djq9uKzy4BAGfEKhv6qH3T9XThuVZlJcFbbNPoCMREPATAQhefgLvj2Qr67roMAtZH3lgJsmX9v5jtRQbHU4bS3L8kR2kCQIgYEXgwKk66uu30L1rcpXm+bX9FbR8fjpNxwQXK1K4BIHAJYC9XgK37tzO+W9fuU6l11ooPyuO6pp6aQu/3NNTYtyOBwFAAAS8Q2ATfwQ1t/XRK/sqqCAnnv686yadvdxC//srS72TIGIFARDwOQEszORz5P5J8PiFRjp/pYU1XUR/2llOj2+dDqHLP1WBVEHAIQH5GHpi23TVTwd5BuRF3n7oKBvhw4EACAQHAQhewVGPDksxwIs3/v6166N+Glr66LV3KkavcQICIGAuArsPVlFNQ89opn7/+nXq5y2I4EAABAKfAGy8Ar8OnZZAvpbf52UiMtNi1LT1TF49OzczjmZPS3IaFh5AAAR8T+BaRTtV876oTa191NjSq44bV2TDHtP3VYEUQcDjBCB4eRwpIgQBEAABEAABEAAB2wQw1GibC+6CAAiAAAiAAAiAgMcJhPysxjffvkBVtW0eB4sI/UMgnBeg3PHEKoqPwz54/qkBz6a6c38pVda0ejZSxOY3AtI/P/bYSkpMwGxqv1UCEvY7gZAXvP7y97PU1BVH4WERfq8MZGDqBIb66umx+5dA8Jo6SlPE8Nc3z1JDeyyvaYX+aYoKmWImLP319Mj2xRC8psgRwQObQMgLXlJ9sXGpFB4RFdg1idwrAkME7UiwNYWY+FSKQP8MimodCsPoQlBUJAoxJQKw8ZoSPgQGARAAARAAARAAAdcJQPBynRV8ggAIgAAIgAAIgMCUCEDwmhI+BAYBEAABEAABEAAB1wlA8HKdFXyCAAiAAAiAAAiAwJQIQPCaEj4EBgEQAAEQAAEQAAHXCUDwcp0VfIIACIAACIAACIDAlAhA8JoSPgQGARAAARAAARAAAdcJQPBynRV8ggAIgAAIgAAIgMCUCEDwmhI+BAYBEAABEAABEAAB1wlA8HKdlc98WoYG6OqZl3yWXkdLJVVfP+yz9JAQCAQyAfTPQK495B0E/E8AgpeTOig7+js6/fa/OfTV19NK/b0dDv04etjVVkPDlqFRLxUf7Kfb/F+cK+mPBnTjxJhmWFg4nXjrxzQ02O9GDN7xOlWW3skVYjUrAVf6x1TblLGvCAf0z8m/68zajpAvEPAlAQheTmjnz9lIMxc+6NDXhQPP0bWzLzv04+jhnhc/T6J10u5W2W6aNu9edelK+jqcO0djmomp+ZTA/6uvH3QnCq/4nSpLr2QKkZqWgCv9Y6ptythXBAT65+TfdaZtSMgYCPiQADbJdgK7rfG60mal586nk3t+QhkFi6ji0l7eVDualt3zNWqqvki1t07wdSQ11ZTRhseepbqbJ3io8G80xEOGM4vvp1mLHqLu9jq6eOS3lJhWoIb1JL6ld3+ZTu//dxoa6KNT+35KOTNW0ryVH6OGyvNUsu1bKmfO0k9Km6a0ZZdP/olqy49ReGQ0zV70MAtuW6i8dCfnoZ+Klj6u4jr46ndUvBePvDAuzeK1n6a8WWup5uaxUYFPAug8J6TmcZ4PUfa05exvPV08/DxFRMXS8i1fp8TUAhY6X6HbV/aTZWiQCoo20fxVO1TYsmO/p7jELKopP0KpWXfRss1focjoeLpx4Q3O2y6KjIrhOP47JWfMUPm7eXH3BJZ93a1Ueuh5amu6QYkp+bRw/edIygwHAkLAWf+w1T97u5rpwsHnqJM/dtLzimnxhi+oPo7+if6JXgUCviAAjZcTyvJybm8qV74aq0vp8rE/smDxFAsNsXT+wC9ZWCphoaKIsguXU/HaT1FXazUd3fVDFqA+rgSQM+/8jJprL9FAfxfdLNvFmq3btHjj01R59T0WVt6lomVPKKFt9pJHWejZymndouHhIYpPylFpOktfPInQdevSHlqy6Us0i7Vzx9/6EbXUXeG0KqiD49OuvuIUDQ50T0hTnick56q8a79y1HmWoZaF6z5H1868TMd3P0vzVn2cwsMjWAB7QXnv7W5hIfKrSpCUH6/2ppsqbHnpm9TTUU/L7/k6C6UXqezYH6ivp00N3ZZse0bFGRY+1gStWYaFRdDB175D4kcE0ajYJBLhcXjYYswmzkOYgLP+Yd2mwsMj6dDr31PtfQW3wZb6K3SRzQl0W0f/RP8M4e6EovuIwNivno8SDPRklt/7DaWZmln8AHWykCUandj4NIpPzqGMvIVKaxSXkMEamnIlZMUmpCutmJRbtD2r7vtnpTkS7VZXW7US2sJYiEnLnsuanEL+8m6nmLhUJYzZYmWdvvipvnZQacoy8hfS9PnblBBYV3HSVnB1TwRFY5pyMzYhk7raayeEkTyv3P5PrOlaQ6k5c1lY+qzSjk2bv5U6WSATt2D1Uyrfna1VFB2bSD2djeq+hC3Z/m2SfM1Z8ghzKFUCa3RsstIIxsSljNNeWbPs7qij1vqrtHTzV5nPXUqw7GytZG4T86kSxJ+QJ2DdP6zbVE9ng2pT0jYbKs9yX0tRHwUCDv0T/TPkOxAA+IQABC83MYshurjwiKhxBvE6msGBHtYGRVIED0XK/3klH6VcFlrESdiwsDB1HmEnvAhEEoc9Zyv9AdZiRUUnjAaJ4CG8EWP9MJe1Q0ODvaN5G42IT4x5lnJpDVV4eBRxIjy8OEB7X3xaDR/28rAgDY+FHheWWQzzv4jIGNq241cUGRlLe//4Rdb8vT8WwOpssL+b049Qwpo8iuBhVHGiEYQDAVsEbPUPo7/BgV51GRkVp/pn7ozV/OHwSXXP2F7RP9E/je0G5yDgSQIQvDxAU4Swbh5SkyEw0SbJcFrhXZtpztLHqHDuZtaKZTpMRYQY+RIfHh7mIcYsnl3Yp2xOHAYyPEzNLKKKy2+r8JKP+ttnlPZNvuZbWGMkQtitsreUvZcOZkxT7kk4Z/nUYY3HTtbayZCmaPJmLNiuGOjnA31dajhVuFSxgJWaOWekXCx8imZC/DdWndPe1dHIMoFtukTYun3lHfWs4tI+1i6m8zBR3rgwuAABRwSMbUqG8OUjRdq69E+xv0zNmuMoOH9IoX9qQEaW6J+aCo4g4B4BGNc746U0VCNaKtFW6S9q49exGKYfeuP7ym7rkf/2CuXNXkc7f7NDDUEO9vfQ5g/LchQclv+NOtGc3dF+FczZoGyZCovuptUPfp+H65KpteGaGpIc8eM4/UUbPk+HX/8+vfaLR5TgI8b02dNXUFL6NLp27lV69ecPU1rOPDWsIvkQZ0xzzYf+J7U1XKf03AWj2Rs5GZ/n8eXneDj/YlyfWbCEdr6wg6Ji4pVGS0ci2rGyo7+lE7t/RAkpeTzs+C01DPnuX7+h8jLAGq2Nj/1Ye1dHI8tHv/Qq23Y9Q6f3/SudZVs50QaufuC7dodhx0WEi9Ag4Gb/VG2Kh79P7v0XOvf+L0g+Dhas+QTlTF+J/on+GRp9BqX0O4Ew1rIYBof8nh+fZ+DT3/wDdVny1NChrcSVITcjkh99mbUnsxe1M16rIQzW7IidiDhZE0uGyqJZ66SHF43+1VCgQZCTdcAio+PUMKXMnpQvyxVbvzmiQXIhfUlTfkRkmFGGBLWT6pV8RMUkTMi/TlP8vvGrJ2n9Iz+grMJlOqg6GvNssQxyWSLGysPXOi3R8onAKMOAcq+t8Qa985ev02Nffl1puUT7pp3E09/DtmzxqRzXRKWrNUspw4jt21gcOi7r41DXDfrljz5MWRlJ1o9wHYAEPvvMi9Q+mMvDgjy0bcNNtn9Km5L1vaJjEkf7vrGto396qX92l9PPf/gk5WQl26hN3AKB0CAw8VcvNMrtcimVZouFLnFGocv6WmY5aqFLnskQ2YhgMablMoYXQc4odETzjD0txBQtf1It3yDxuJq++BXhSsch1+JE6JP74ozpy7VOs5GXrxAjZGuhyzqMxK2FSPXMIOCJYCXPJqYffkfTJiFGnPiRSQfG8utncrRmKfEaBTejX5yHNgFX+4etNiWTYuQDRztj/0D/RP/U7QJHEPA0AWi8nGi8PA3c1fjkS96eYOJqHO7483R6ojGQZSYmYzfmTr6t/ULjZU0ksK+dabz8VTpP9xdn5fB0en7rn9B4OatqPA8BAtB4mbSSfSl0CQJPpycaA18LXSatSmQrCAl4ur84Q+Tp9NA/nRHHcxDwHgEIXt5ji5hBAARAAARAAARAYBwBCF7jcOACBEAABEAABEAABLxHAIKX99giZhAAARAAARAAARAYRwCC1zgcuAABEAABEAABEAAB7xGA4OU9togZBEAABEAABEAABMYRGFtpc9zt0Lro7W7mWX0ja3WFVsmDr7SW/r7gK1SIl6i3q5nXh0P/DIZmgP4ZDLWIMkyVQMgLXp98ciXV1rdPlaNpw7d0WKipzULt3RZKjA+n1MQwyk4N3h+xsLBplBAfY9r6QMbcI/DUE9w/69rcCxRgvmubh6irZ5gsvIfI7PwIiggfW3Q5wIriNLvSP5MSY536gwcQCGYCIb+AajBWroXf4KfKmqimvoeKpidRcVEq7T5YRQ9sLKCbVZ109nIzzSpMpKXz0oOx+CgTCAQEgaGhYXrrUBXNnpZE82elUHfPIO08UEUbl2dTblZcQJQBmQQBEHCfAAQv95mZNkRv3xAdOdtAnd0DtHJRBuVljewbKRnWgpfOvBbAZhYk0rL5EMA0FxxBwBcEWtv7ac/harpvQz6lJkWPS3LfkRpKTY6ilQszx93HBQiAQHAQgOAVBPXY3NpHR883qCGKDfy1nJgwtv+cLp614KXvQwDTJHAEAd8QuHSjlcorO5UGOtzOsOKVm2109VYH3b8xnyIjMAfKNzWDVEDANwQgePmGs1dSKa/soAtXWyk9OZrWLs2iyEj7L2h7gpfO2KgAls8asAXQgGkuOIKAJwnsPyrarGhaUZzhNNr2zgE1FLlldS5lpsEuyikweACBACEAwStAKkpnc3h4mM5caqbK2m6ayXZaS+am6UcOj84ELx34VnWnin9GfgItX+D8x0GHwxEEQMA+ge5ett96v4o2lWRTTobr9lvS3986VE35bPO1BDaZ9gHjCQgEEAEIXgFSWf39bL91roHa+Ct4BWukCnMT3Mq5q4KXjrSCBbDTLOBBANNEcASByRGQj5nTZc300OZCio6yr5V2FHvp1RaqrOum+9bn89IawTvr0REDPAOBYCEAwcvkNdna0U9H2WCeZ5rT+mVZlGJliOtq9t0VvHS8WgCbnpfg0vCIDocjCIAA0eGz9WSxEG1ckT1lHC3tfSSG99tZ+LI2yJ9y5IgABEDAZwQgePkMtXsJVdR00Tle9iE5MYrWLcue9JeyTnWygpcOL/k5zUtUQADTRHAEAfsEBgYtPLRYqZZskZnDnnKyVIwsOTFnWiItmJ3qqWgRDwiAgA8JQPDyIWxXkjr/QTOvtdXFQ4nxbGOVzivqe2ZYYaqCl8777douOnURApjmgSMIWBOob+6l90/U0oN3F1JCnHfWqD5zqYmaWvtp69pcj70jrMuBaxAAAe8QgODlHa5uxSpfx8fYfqu5rZ8NaNPIk1/IOiOeErx0fFoAm8a2ZiULYYSvueAY2gRkceIGFry2rcvzukAkAt57IuDxwsi2lpAJ7ZpA6UHAvAQgePmxbjq6BtSCp4NDFrUcRHqK97a68bTgpbFVsgbsJGvARABbUew5DZ2OH0cQCAQCMgS4h2cfylC87BThKzfIH21v8pDmQk6zaHqyr5JFOiAAAlMgAMFrCvAmG7S6vlvZS8XzMMR6tt+KjfH+3oneErw0Ay2AyRBpCa9R5KkhUh0/jiBgVgLtnf1qyYeta/PImx9Pjsp//EIj9fCSFZtX5TryhmcgAAImIADBy4eVUHatla5VdFBedpwSTnw5LdzbgpfGWFnHGrDSJirMYQGMhyAhgGkyOAYjgSs320lWmX9wUyFFRHjGHnOynOSDTrYM+9DdBRQX6x3bssnmDeFAAATGCEDwGmPhlTMZRpSvUbH78OdwgK8ELw0RApgmgWOwEniX7asSWWu9cpF59lSU9f7+zkOPonWewbtQwIEACJiPAAQvL9VJV88gHT5TT30DbL+1JNPvW374WvDSWKt40ccTpY1UwBqwldCAaSw4BjAB2Yz+zfcqeZmXLMrPHtuI3kxFOnS6nrXNvPYf790KBwIgYC4CELw8XB91TT0saDRRbHQEbVieZRqVv78EL41XhkFE8wcBTBPBMRAJiCb3+PlGtQp9DPdxM7vRFfN56DHa5Hk1M0fkDQQ8TQCCl4eIip3H5fJ2yk6PpdWLM023rYe/BS+NWQtgoilYtQg2YJoLjuYncPx8A/WwtiuQDNjF4F72iDSzds78NY8cgoBnCUDwmgJPmUIuw2i1jT00b1YKzef/ZnVmEbw0HxHAhF1eZhytYkEVRviaDI5mIyB2mrtYeFkwJyVgl2x451gtJcRHqo9Cs/FFfkAg1AhA8JpEjctX5GGePSRHERpyMuImEYtvg5hN8NKlhwCmSeBoRgJNrX20/1gNPcCLlCYlRJkxiy7n6dqtdrp0Q2ZgFlBk5OQ263Y5MXgEARCwSwCCl100Ex80tvQqOyV5aW1go1VvbQcyMeWp3zGr4KVLVtMwYgOWyxowGaqFBkyTwdFfBEqvtlAlTw65jzel9uXSL94sbycv2rzrYBXdw+t9ZbFZBBwIgIDvCUDwcoH59dsddJHX4MrgleXXLM2kyIjA+1o0u+Clq8EogK3iafrB8oOny4ej+QkMDw/T3iM1JB8BS+ammT/DbuZQly87LZaW8X6wcCAAAr4lAMHLDm+x3zrNG9FW1/XQ7GmJtOiuwH4BB4rgpaujtqGHjl1oUMO4ZpysoPOJY3AR0BqhLatz/b4EjLfJll1vpZtVnWoYFR843qaN+EFgjAAErzEW6qyPFyCU1Z9lH0VZed2s6/RYZdvpZaAJXrpAEMA0CRy9TeAGa7ZLr7aqld9DxQaqtaOf9h6uVpt6pyV7b69Yb9cd4geBQCIAwetObbW099HRc40jiw7y/onJiYFtSGvdCANV8NLlkJmjx3g6v0xkgAZMU8HRUwQOnKqjKLbdXLs0y1NRBkw8ot2X94OsdC+7a8CBAAh4l0DIC16yyOC5D1ooNSlarXUjL99gdIEueOk6kQVqj7GALIbBa3hHAAyRaDI4ToaAaLjf5C12xJ5wWm7CZKIImjDnPmimuqZe2r4uD5NbgqZWURAzEghJwUuMS89dbqGKmi6anp9Ay+YHv4FpsAheuhNBANMkcJwsAZnIcfgMNpU28pOZ2+8crw2K5TOM5cI5CJiJQEgJXv28b+LRcw0kdg3L5qWx0BU6m8gGm+ClO1E9a8BkiDgzPYb3xMyCBkyDwdEhgZMXG6m9c4DuXZPn0F8oPtQLxsqi0HNnJociApQZBLxKICQEr/bOfrXgKSu6aB3bcKQmR3sVqhkjD1bBS7OGAKZJ4OiIwNDQiD1T0fQktduEI7+h/uwk7yzR0TVIW9bkhjoKlB8EPEogqAUv2dD2TFmzWncj+kwAABUVSURBVHF6/bKskN4oNtgFL90r6pt76SjPSs1MYw0YC9mwAdNkcJQJNPt4fS5ZEDWFbTrhnBOQWcUHz9TTh3i1+/i4SOcB4AMEQMApgaAUvGTF6Ru3O6kgJ55WFKfDUJSbQagIXrrFKwGMh5UzUyGAaSahfMSaVZOvfTHR2MkTEMQWdmZB6JhnTJ4YQoKAYwJBI3gNDrL91vlGaua91RbNTaXZhUmOSx5iT0NN8NLV28AasCMsgMmuA+tY6wkNmCYTOkfRcmWkRtPyBRmhU2gvlPTw2Xqy8FDtxpIcL8SOKEEgdAgEvOAlK00f5h9WEbzWsHF1Bms44CYSCFXBS5OAAKZJhM6xu2dQaWo2rcwJiI3sA6Fmbtd20Qm2/Xro7kKKiY4IhCwjjyBgOgIBK3iJ7YHMTIqPjaT1vGF1bAxeAo5aV6gLXpqNTJc/zDZg6awBE7s/aMA0meA6ylY4Zy838yr0hRQdFZxr8/mrxnr7hpRAu5rX0SvMCe21z/xVB0g3sAkEnOB16UYrXb3ZwRvYxtJKbKLscuuD4DUelVEAk5muERFh4z3gKmAJHGZjcJnBvGFFdsCWIRAy/t6JWqX1CsXV/gOhfpBH8xIICMFLpoCLerueV1WePxtry0ymOUHwsk1NBDDZmzONlxhZx1tFQQCzzSkQ7g6wucGb78EI3Jd1pfe3fPDuArXlki/TRlogEKgETCN4dfcOqmFDI0i5J1+vvf0WtT9fNm8TA+c6gS62cfnqD49SDw8NiD5HhIpHt0yjjz44y/VIQsSnFsBkjbf1VgKYzJBE2zNfQzhd1kTSxjexsbes4/b+yTo1tIhlD3xbV1IHu3jW491sS5fNe6mKCcjg4HBI7nvpW/JILVAJmGJhFrHH+M//ukw/eaZE2dyIIfTxC42sxg5XP4J4kU6ueSXwujsPbCygl/dVEI+8UHR4GD24qXBykQV5qMy0WHqEhdImnhUrU+e1ADbEGwj/r5+doa/tmE+L7koLcgqBVTxp1/LuECN6+aj4h/tmYOkYP1ShvGeE/dtHa5l/K734xg01yUn2Ug0LwxC+H6oESZqcgN+tTmVV+Z+8UKr2TXz17Qp6ff9tulbRoQSGbevysWjfFBuQGBeLACtOzpMTo6YYY3AHl1mxIoAVz0lVAtiv/3qFmtv66T/+cIla2/uDu/ABVDpZq+/KzXaSNabeeLeSNvAEG/zI+68Chf09q3Jo14EqpYWUfXBPlDb5L0NIGQRMTMCvgpfsCfbT35RRY0ufQiT7KD567zS13hJsbTzTakTQ2s4rdcfHRiiBwjOxBn8sIoDdz9rC81daVGHbeF+//3jxEllYAwbnfwIv760YzYQMBf/iz1dGr3HiHwK/e+26+oDWqb+055Y+xREEQMBAwK9Djc+/dJUul7eNZudmdRddu9VORTOwMesoFA+cPHrPNErlLVJkSADOdQJvH62hFoOW6+K1Vvob/5h85IGZrkcCnx4ncJXfEY2tvWrf1VmFibxYciLNwoLJHufsboQy3FhSnEE3qzvVEHA5DwOfudSEhWvdBQn/QU/Ar8b1Hbz4aV//EBvPD/HRQn1sBJ7OmobczLigB48Cmp+AtE2x8RKnLVVkSAVrxvm37oZ5rQgMK/q3DlxNHXXlKin4CyUCfhW8Qgk0ygoCIAACIAACIAACfrXxAn4QAAEQAAEQAAEQCCUCELxCqbZRVhAAARAAARAAAb8SgODlV/xIHARAAARAAARAIJQIQPAKpdpGWUEABEAABEAABPxKIPL1PefoSnmDXzNhpsS3b5pPS4untrr78386zMsQdJupWH7Li8w++9ijJVSQm+p2Hq7cqKM39pbyqvtYO8sxvDB6ZNsimjcnx7G3KT7d/W4ZlX5QPcVYgif45jVFtGrZTFMW6NiZcjpw/Lop82amTMn76ZNPrqLsTCxhZKZ6Cfa8RO5+7zLdboig8AisaN7X007TC9KmLHi9vu8C78+TG+xtx6XyDfc3073r505K8Kqoaqb9xyopMsZ9oc2lzAWJp4HeVlo8P8/rgtfbh67QpZv9FBEZEyTkJl+M/t5OSkmKM63gdaa0kt4+VkfRMYmTL2QIhBzub6IPbSmG4BUCdW2mIqoVNaNikigyChtQDw0OeKRuwnlPxKg4CAsC0xLWNSWmUdwuo8HSMUNLr+PnHnwq74qo6HgPxhiYUVksQ6bPeFRUPMWg7zisJwt1OHyOhyDgDQKw8fIGVcQJAiAAAiAAAiAAAjYIQPCyAQW3QAAEQAAEQAAEQMAbBCB4eYMq4gQBEAABEAABEAABGwQgeNmAglsgAAIgAAIgAAIg4A0CELy8QRVxggAIgAAIgAAIgIANAhC8bEDBLRAAARAAARAAARDwBgEIXt6gijhBAARAAARAAARAwAYBCF42oOAWCIAACIAACIAACHiDAAQvb1BFnCAAAiAAAiAAAiBgg4BpBa/2pptUe/OYjSy7f6v6xmHqaLntfsAgD1F17QB1tdW4VEowHMFkGRqgq2decomZJzyBu/sU3Xl3dLRUUvX1w+4nghBuE3CnXtyO3EYA9B0bUHDLFARcErz2/fGLLAQdd5hh+QEfnuQ2GkOD/dTdUT8u/vMHfkXtzRXj7rl6YR2fdPjLx//oanCf+ys7+js6/fa/OUzXukwOPdt42NfTSv29Y9tj9Pe207Fdz1JYeAS11H1Au37zFA0PW2yEHLllRobebpdScut2XfHBfrrN/8W5Um/Koxt/rOvZjNxdLY4r7cq6vK7Grf3ZCq/fHa6kHxYWTife+jFJPKHkvN13HNWLcHYlfXfrwzrNQO477pYd/gOLgEuCV/Haz1Ba9lyHJdvz4udZq1Tp0I+9hw2VZ+nAK/80+rivu5Vqbx2naXO3jN5z58Q6Pomn8up7NNDf7U40PvObP2cjzVz4oMP0rMvk0LONhxcOPEfXzr48+uT2lXe5Tu+i+KRsSkwtpCWbvkTyI2TPmZGht9ulsLBu17fKdtO0efcqTK7Umz2e9u5b17MZudvLu/V9V9qVdXmt43B2bR3e+O5wJf3E1HxK4P/V1w86Syqonnu77ziqFwHpSvruArdOM5D7jrtlh//AIqA2yXaWZXkpxSdn81dhH1088ltKTCtQ6vn03Pm09O4v0+n9/05DA310at9PKWfGSpq/+imlYaopP0axCWm0cN1nKTWriG6VvUW93S3U2nCdNQnVNGfpY5SRt4hKDz9P3e11Sviat/Lj1NvVRCmZsykuMVNlraezkUoPPU9tTTcoMSWfFq7/HCWlTaPju39E4j8lcxY1116m8os7aV7JxybElz1tuRIwGivPUd7sdc6K6/PnbY3XlTZKeJ7c8xPKKFhEFZf2UnhENC2752ssEEVMKFNiagFdOPgcdbKwm55XTIs3fIEiefNiW+Gbqi+yIHuC44ukppoy2vDYs1THGsy8WWtVWQf6OunWpT1UULTJZh3NWHAfJaTkmY6hu+2yeO2nqebGER4q/BsN8ZDhzOL7adaih1Tbc6Vdz1v5MWqoPE8l276luDmrN2mj9tpueelOzkM/FS19XMV18NXvcL/5xIR6NnvbddRZnLUrW30/s2CxzXeHrXZtq18Y3x3yTnHWriX/0g9q2KxBC9SOyhQszzzVdyb7TneWfnhElN2+Eyzv/WBpSyiH+wTsqzgMcTVWl5J8SQ70d9HNsl3KXmrxxqeVFkk0J0XLnlA/6rOXPMovr6105eSflX3Wyu3fpuT0GXTo9e/zMNYwdbZWsbDwa5KX6wz+0Tu5918oMiaBpnOY6NhkWrDmU0pAa2u8QQlJOSoHEu7ga9/hIbFw9YMXFZtE8iMlw2KNVedZYGlX/vpYoGvifIqwZh2feIhPzqVOFvbM6ER4am8qV1kT1peP/ZHmr3qKIqNi6fyBX9os06HXv0cJXKYV256hlvordJGHK8XZCp8zo0RxzS5czl+an6Lw8EhqZcbxKbkqjNRr/e0z6txWHWlNodkYutsuO3jo+uiuHyphff6qHXTmnZ+xwH7J5Xbd3nSL290QC6AjbdNZvTlqux0tFdTB8WlXX3GKoqLjAq7t6vzbOjprV7b6vr13h612bauvG98dztLX7Vr6UVerOd8Ntrh64p6n+o6t94WtejXWi+TfWfqO+k6wvPc9UY+IIzAJuCR4GYsmWpVV9/0zyZe4aLdEcyXaLLEVkuHIpLRCEqNG+XGqqzhJEZExrFGoVVosiWdG8X00hwU0+S9DW/0s0CVnzGRtTRxl5i9iASyJ+nraKPaOtqu7o45a66/S0s1fVUNjMiTW2VrJ6dYaszV6HhEZPSE+eSgvaclHILjl935DsZ1Z/ACXtZoZji/T0GCvYiJ1Ier1mLgU1mRdHC2adfi4xCyKjU9j4TOHNYwLlb9+ZhyXMKJRHA1458S6jno6GtQTMzN0pV2KViMuIYM1p+Xq4yE2IZ2F9RFuroQXIT8mLlV9ZFgzk2tr7u62XfnKt+4LEq+ZuUv+XHXW7cpW33f07rDma90vrN8d1vmyTl+361juB10B8m6wLpMnrl1p+476jjVXW/VqfKdb59lW+u72HVttQdIJlr5jzQzXgU3AbcFLhKWwsDBV6gj+obBlUD840EPhLCxE8FCZ/FCVbH1GCQcSKJwFNO3kh0Y0CNZONDJDA73q9iDbZcmQgmh/xEkHE6fCcT4cGYQrj3f+DKr4RvJtvG/Gc21rpfjYmLAwUhZiJnGKce6M1bRg9SdHi+IsvHiUYUepJ1vOXh2ZmaHL7ZLblrRL+T+v5KOUO2uNQuBKePm4sMdMIrHm7rDtUnC2XVvtSd+z1670czk6endY8zWG0+fGd4e+p4/20pcPGf1O035D6ehK21f1Yqfv2ONqZOioXmyl77DvBOl738gL58FNwG3Byx6O8HAZk29gQWhYacCGhwZJhh7Fjitn5ir+oY+yF1Q96+1qIQuHkfBxSVmjsxwT2KZLhK3bV95R4Ssu7WPtTToPs+VRTGyKmpEns1lusv2YdpKWMT6538OzJuXrJ1CdsUxxidk8LJWgyiN8xU4pNWuOw6JJeJk5qgVV0YJZzyR1GAE/DESG1u1SvrwL79qs2mXh3M1O24QxfDy3S7FzNM4OdcTMYdtlLWULa3Llw0XsZMTeS5yxnqUviAtE7irjLvyxLq9ozz317nAheeVF+kEgvxtcLae7/oxtX+rFnb5jXa/Gd7or+XDYd0Love8KK/gJPAIuCV7yNTjytclH/jfqZBbcHe1XwZwNyhbr+K7/q4zp25tv0d+f+wf6+6//kU7s/vFIEOV3LPxIXGFqCFGEq1d//jBV8ezD9NwFJDYBIiSIpquE7ZhO7/tXev2Xj9OFQ7+m1Q98V2ls5rLGovTwC/T6rx4ni2WA0xiJW2brGeOzWAbZhuqminc072Y6MXAZYz2iQdFf4sYy1ZYfoRK2nxMbuZ0v7KA3mLMWTO2FFwPimzwj77VfPMqsBpnFfGrjSQ4jzlCvhrzIM11HZmQ4VlZD/lWmbbfLvFnr1OSKnb/ZoZbP2PP7z/Hwsyxj4lr4hJQCZYvY2nBNUpEKkj93TjkO6Q9y545W2FHbnT5/K080aVZtvvzirjsa4Yl9wYzcVSFd+mPgamClGCluE8srE3FsvTvG6nqMr8Rj7BfW7w6pG/mnnJ305Zn0A3nnhJIb42lgJADsvNPt9h07XB3Xi9Qhp6v6i+30HfWdoHnvh1KDQ1nHEQj78nf/33Bte+roUN64p3cuRBMlQ1PijOdqmHG0A5HSBIitlqiVxSnjVf5qj2IDenFK28LXMmQjzjqu/r4ONTQp99947kla9/D/UbZk4le+/kdsbFLkctSJtksLaPbiq715Qq3V8/AX/zb64zgageGkm22ZPvXYLPrIwyWGu+6fPvH0cxSVNM/lgEYuxjJIBMZr4a0ZyTNhIutzRcckKk2JtX/razVUKMIs24bJumzHef2iR774kmKi0zHmxRjeVYYSxugsvVX0va9souWLphlvu3S+78Al+s8Xz1N0wsgkAOtAOs9y33jurF1Km5GhjGjWOskPgDvhZXadfM2v2PrNce3ZmP6E+Oy0Xak/yYf0D2N4Yz27wr2vq5a+smMx3b+5WJXFW3++/eyrdK0mhrWt8S4noctlr11JRMby6oit3x06Hv3ceG0ML/eN7w7tz176Iti+8asnaf0jP6CswmU6eqfHHp55/ejmHHp6xwanfv3h4Zd/OEA7DzbyrPJ0m8lrLvLQeO5u37HHVeJ1pV6cpe/t976l5zb98H9spQV35UlW4EDAJwRc0nhpoUtyZDwXAUp/5cszMW7VQpdcywtaC11yrTQB42y8xlazkLjEHkycpDFnyWMkK6trJz+QYkRu7USzpe2/rPOm46u69j7NWfb4uLxax+PPayMXYxkkT8ZrIyN5JkzEaF4EAe2M/uWe8Vo4idAlLmfGKhbYkkaNy7U/Y17En75vRoY6b8Z8yrmzdiltJiY+VfET/+KMcTkKX7T8SV5K5ZAKY2RlDD8hPjttV+pP9w9jeGM9m5G7KryLf3S5jKwm8DH0fR2t9btDx6OfG6+NvOS+8d2h/dlLv5GXB5Fhd3eELp2HQD5qLlIG47mjti9+rfuOPa7i15V6EX+O0g/m976UHS40CYxJPiYr/6INnx/RKHggX6KdkBcE3BgBeaHd/+nfuswFDEfYia3LQ0//ZQykl8/A3X3A7rw7sqevoO2f+LX7iSCE2wTcqRe3I7cRAH3HBhTcMgUBU0sjnhKWPBWPKWrMg5lwh4s7fj2YRVNG5UsWvkzLlLAnmSl3uLnjd5LZQbA7BHzJ2pdpoYJBwB0Cpha83CkI/IIACIAACIAACICA2QlA8DJ7DSF/IAACIAACIAACQUMAglfQVCUKAgIgAAIgAAIgYHYCELzMXkPIHwiAAAiAAAiAQNAQgOAVNFWJgoAACIAACIAACJidgFpOoq+7iQbuLHpq9gx7M38DfZ0eid5iGeZtXuo8ElegR2IZ6JpSEfp6O2nIApaOIA72e6bdOkpDP5N3xWB/h74M2eNAH7frsBxTl7+/t40XMZUdPeDsEbAMdNt7hPsg4DUCkZ/5x9VU24AXqSa8aF6+Pp308WufuZt6evHC0wCn5afpU7eO84ty6cufWOVWmFD1XDzX+ytvf/zRFVRZ2xqqiCeUe/4c8wpeW9bPpfzciQtOTygEblBeNjihGfiWwP8HuIad4qd/EeMAAAAASUVORK5CYII=",
      "text/plain": [
       "<IPython.core.display.Image object>"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "fig = Image(filename='gfx/intent_inout_map-crop.png')\n",
    "fig\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "15545c2e",
   "metadata": {},
   "source": [
    "You may be wondering why `intent(out)` has been included as a permitted value for the rightmost tree of the above flowchart. It is to account for the following possibility: an `allocatable` variable is allocated in subroutine A, and passed as an argument to subroutine B. Subroutine B must therefore declare the variable as either `intent(inout)` or `intent(in)`. Subroutine B then passes the variable as an argument to subroutine C without using it first. In subroutine C, the variable can correctly be of any declared intent."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a2320a8a",
   "metadata": {},
   "source": [
    "## Checking `intent` consistency across function calls"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "112d9adb",
   "metadata": {},
   "source": [
    "The code below gives an example of how a `visit_CallStatement` method can be implemented:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "ae85e899",
   "metadata": {},
   "outputs": [],
   "source": [
    "intent_map = {'in': {'none': ['in'], 'lhs': ['in'], 'rhs': ['in']}}\n",
    "intent_map['out'] = {'none': ['out'], 'lhs': ['in', 'inout'], 'rhs': ['in', 'inout', 'out']}\n",
    "intent_map['inout'] = {'none': ['in', 'inout', 'out'], 'lhs': ['in', 'inout'], 'rhs': ['in', 'inout', 'out']}\n",
    "\n",
    "def visit_CallStatement(self, o):\n",
    "    \"\"\"\n",
    "    Check intent consistency across callstatement and check intent of\n",
    "    dummy arguments corresponding to allocatables.\n",
    "    \"\"\"\n",
    "\n",
    "    assign_type = {v.name: 'none' for v in self.in_vars + self.out_vars + self.inout_vars}\n",
    "    assign_type.update({v.name: 'lhs' for v in self.vars_written})\n",
    "    assign_type.update({v.name: 'rhs' for v in self.vars_read})\n",
    "\n",
    "    for f, a in o.arg_iter():\n",
    "        if getattr(getattr(a, 'type', None), 'intent', None):\n",
    "            if f.type.intent not in intent_map[a.type.intent][assign_type[a.name]]:\n",
    "                print(f'Inconsistent intent in {o} for arg {a.name}')\n",
    "            if f.type.intent in ['in']:\n",
    "                self.vars_read.add(a)\n",
    "                self.vars_written.discard(a)\n",
    "            else:\n",
    "                self.vars_written.add(a)\n",
    "                self.vars_read.discard(a)\n",
    "        if getattr(a, \"name\", None) in [v.name for v in self.alloc_vars]:\n",
    "            if not f.type.intent in ['in', 'inout']:\n",
    "                print(f'Allocatable argument {a.name} has wrong intent in {o.routine}.')\n",
    "\n",
    "IntentLinterVisitor.intent_map = intent_map\n",
    "IntentLinterVisitor.visit_CallStatement = visit_CallStatement\n",
    "routine.enrich(source.all_subroutines) # link CallStatements to Subroutines\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "83a0eaa7",
   "metadata": {},
   "source": [
    "In the final line of the above code-cell, we called the function `enrich`. This uses inter-procedural analysis to link `CallStatement` nodes to the relevant `Subroutine` objects. Also note that in the above code-cell, `intent_map` has been declared as a class-attribute because it will be the same for every instance of `IntentLinterVisitor`. \n",
    "\n",
    "We can now finally run our intent-linter and check if any rules are broken:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "1baca9f0",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "All rules satisfied\n"
     ]
    }
   ],
   "source": [
    "intent_linter = IntentLinterVisitor(in_vars, out_vars, inout_vars)\n",
    "intent_linter.visit(routine.body)\n",
    "intent_linter.rule_check()\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3.8.8 ('loki_env': venv)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.8"
  },
  "vscode": {
   "interpreter": {
    "hash": "5b6429b76fde06fc4400bf3c27b3ae893ffb7a047f8b8ee9418a3bc77878d107"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
