diff --git a/fast/2d5pt_bench_grid_size.csv b/fast/2d5pt_bench_grid_size.csv
deleted file mode 100644
index 970df1d115..0000000000
--- a/fast/2d5pt_bench_grid_size.csv
+++ /dev/null
@@ -1,3 +0,0 @@
-GridSize xDSL Devito
-256,0.0,0.01
-1024,0.0,0.01
diff --git a/fast/2d5pt_gpu_grid_runtimes.csv b/fast/2d5pt_gpu_grid_runtimes.csv
deleted file mode 100644
index a836ee05a4..0000000000
--- a/fast/2d5pt_gpu_grid_runtimes.csv
+++ /dev/null
@@ -1,3 +0,0 @@
-Grid Size,Devito/xDSL,Devito
-((2, 2), [0.0, 0.0, 0.001, 0.001, 0.001, 0.001, 0.0, 0.001, 0.001, 0.0], [0.00017300000000000006, 8.599999999999999e-05, 8.499999999999999e-05, 8.4e-05, 8.4e-05, 8.299999999999997e-05, 8.499999999999999e-05, 8.4e-05, 8.3e-05, 8.4e-05])
-((2, 4), [0.0, 0.0, 0.0, 0.0, 0.001, 0.0, 0.001, 0.0, 0.001, 0.001], [0.00010099999999999997, 8.699999999999999e-05, 8.6e-05, 8.4e-05, 8.6e-05, 8.3e-05, 8.299999999999997e-05, 8.3e-05, 8.4e-05, 8.199999999999999e-05])
diff --git a/fast/2d5pt_grid_runtimes.csv b/fast/2d5pt_grid_runtimes.csv
deleted file mode 100644
index c05d1940b0..0000000000
--- a/fast/2d5pt_grid_runtimes.csv
+++ /dev/null
@@ -1,7 +0,0 @@
-Grid Size,Devito/xDSL,Devito/GCC
-2048,2048,0.109,0.125764
-2048,4096,0.318,0.27019499999999996
-4096,4096,0.674,0.6884169999999998
-4096,8192,1.454,1.4310340000000001
-8192,8192,3.089,3.011858999999999
-8192,16384,6.1370000000000005,6.9759579999999985
diff --git a/fast/2d5pt_grid_runtimes.svg b/fast/2d5pt_grid_runtimes.svg
deleted file mode 100644
index e1f1c2bd6c..0000000000
--- a/fast/2d5pt_grid_runtimes.svg
+++ /dev/null
@@ -1,776 +0,0 @@
-
-
-
diff --git a/fast/2d5pt_threads_devito.csv b/fast/2d5pt_threads_devito.csv
deleted file mode 100644
index bde5309368..0000000000
--- a/fast/2d5pt_threads_devito.csv
+++ /dev/null
@@ -1,7 +0,0 @@
-Threads,Devito
-(1, [0.002208000000000001, 0.0015280000000000005, 0.001472999999999999, 0.0014539999999999993, 0.0014550000000000001, 0.0014470000000000006, 0.0014360000000000002, 0.0014630000000000003, 0.0014350000000000005, 0.0014530000000000003])
-(2, [0.001522, 0.0015039999999999995, 0.0014729999999999997, 0.0014929999999999998, 0.0014839999999999999, 0.0014829999999999997, 0.0015129999999999996, 0.001486, 0.0014979999999999995, 0.0014999999999999998])
-(4, [0.0015759999999999997, 0.0015019999999999999, 0.00148, 0.0015100000000000005, 0.00151, 0.0014810000000000001, 0.001476, 0.0014740000000000003, 0.0014750000000000004, 0.001494])
-(8, [0.0011560000000000016, 0.0010660000000000018, 0.0010360000000000015, 0.0009800000000000013, 0.000964000000000001, 0.0009510000000000009, 0.000979000000000001, 0.000983000000000001, 0.001011000000000001, 0.0009460000000000007])
-(16, [0.001254000000000001, 0.0010400000000000016, 0.0007709999999999986, 0.0007799999999999987, 0.0007919999999999987, 0.0007839999999999987, 0.0007859999999999987, 0.0007809999999999985, 0.0007969999999999987, 0.0007849999999999986])
-(32, [0.0025570000000000007, 0.002603000000000002, 0.0027170000000000015, 0.002355000000000001, 0.0023100000000000004, 0.0024140000000000016, 0.0023169999999999996, 0.0030670000000000007, 0.002312000000000001, 0.002300000000000001])
diff --git a/fast/2d5pt_threads_xdsl.csv b/fast/2d5pt_threads_xdsl.csv
deleted file mode 100644
index 77b81d7aae..0000000000
--- a/fast/2d5pt_threads_xdsl.csv
+++ /dev/null
@@ -1,7 +0,0 @@
-Threads,Devito/xDSL
-(1, [0.003, 0.006, 0.003, 0.005, 0.005, 0.003, 0.002, 0.003, 0.005, 0.003])
-(2, [0.002, 0.002, 0.002, 0.003, 0.002, 0.002, 0.002, 0.002, 0.002, 0.002])
-(4, [0.002, 0.001, 0.002, 0.002, 0.003, 0.002, 0.002, 0.002, 0.002, 0.002])
-(8, [0.002, 0.001, 0.002, 0.002, 0.001, 0.001, 0.002, 0.002, 0.001, 0.002])
-(16, [0.002, 0.005, 0.002, 0.002, 0.002, 0.001, 0.005, 0.002, 0.002, 0.002])
-(32, [0.005, 0.005, 0.003, 0.006, 0.005, 0.005, 0.005, 0.008, 0.004, 0.006])
diff --git a/fast/3d_diff_grid_runtimes.csv b/fast/3d_diff_grid_runtimes.csv
deleted file mode 100644
index dc8531e346..0000000000
--- a/fast/3d_diff_grid_runtimes.csv
+++ /dev/null
@@ -1,12 +0,0 @@
-Grid Size,Devito/xDSL,Devito
-((25, 25, 25), [0.0, 0.0, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.0], [0.0006849999999999996, 0.0006689999999999996, 0.0006749999999999996, 0.0006829999999999996, 0.0006769999999999995, 0.0006759999999999995, 0.0006739999999999998, 0.0006859999999999994, 0.0006749999999999996, 0.0006759999999999994])
-((25, 25, 50), [0.001, 0.002, 0.001, 0.002, 0.001, 0.001, 0.002, 0.002, 0.001, 0.001], [0.001180999999999999, 0.0010940000000000017, 0.0011140000000000015, 0.0011060000000000015, 0.0011060000000000013, 0.0011080000000000013, 0.0011040000000000017, 0.0011100000000000014, 0.0011160000000000013, 0.0011050000000000012])
-((25, 50, 50), [0.002, 0.003, 0.002, 0.003, 0.003, 0.002, 0.003, 0.002, 0.002, 0.002], [0.002446000000000001, 0.002274000000000002, 0.0022900000000000017, 0.002264000000000002, 0.002266000000000002, 0.002286000000000002, 0.002274000000000002, 0.0023020000000000015, 0.0022940000000000018, 0.0022840000000000017])
-((50, 50, 50), [0.005, 0.005, 0.005, 0.005, 0.005, 0.005, 0.005, 0.005, 0.004, 0.005], [0.004731999999999996, 0.004684999999999995, 0.004616999999999998, 0.0046279999999999984, 0.0046570000000000005, 0.00463, 0.004628, 0.004627999999999999, 0.004647000000000002, 0.004647000000000001])
-((50, 50, 100), [0.008, 0.009, 0.009, 0.008, 0.008, 0.008, 0.009, 0.008, 0.009, 0.008], [0.007850000000000008, 0.007606000000000006, 0.007662000000000002, 0.0076719999999999965, 0.007662999999999997, 0.007671999999999997, 0.007662999999999998, 0.007637000000000001, 0.007644999999999998, 0.007646999999999998])
-((50, 100, 100), [0.016, 0.017, 0.017, 0.017, 0.016, 0.017, 0.018, 0.018, 0.018, 0.017], [0.015632999999999994, 0.015381999999999988, 0.01534899999999999, 0.015382999999999983, 0.01538599999999999, 0.015383999999999988, 0.015349999999999987, 0.015371999999999988, 0.01566700000000001, 0.015753])
-((100, 100, 100), [0.033, 0.032, 0.032, 0.032, 0.032, 0.032, 0.033, 0.033, 0.033, 0.033], [0.03150999999999999, 0.03113500000000001, 0.031101000000000004, 0.03109400000000004, 0.03116200000000003, 0.031159000000000027, 0.031241000000000015, 0.031170000000000028, 0.031285000000000014, 0.031254999999999984])
-((100, 100, 200), [0.053, 0.054, 0.053, 0.054, 0.052, 0.054, 0.055, 0.054, 0.054, 0.054], [0.05675999999999998, 0.05593, 0.056949, 0.05753000000000001, 0.057545000000000034, 0.05740799999999999, 0.057413, 0.058486000000000024, 0.05747000000000001, 0.05757399999999999])
-((100, 200, 200), [0.128, 0.128, 0.125, 0.131, 0.126, 0.126, 0.125, 0.126, 0.123, 0.128], [0.152539, 0.14891100000000007, 0.13001499999999996, 0.13894499999999996, 0.14290999999999998, 0.14114400000000002, 0.14652800000000002, 0.14664700000000003, 0.14234200000000008, 0.142064])
-((200, 200, 200), [0.394, 0.40900000000000003, 0.394, 0.39, 0.396, 0.388, 0.404, 0.406, 0.40900000000000003, 0.389], [0.44038599999999994, 0.3770539999999997, 0.37931899999999985, 0.405373, 0.40441799999999983, 0.37735299999999977, 0.3893460000000001, 0.402881, 0.3689360000000001, 0.3869070000000002])
-((200, 200, 400), [0.8140000000000001, 0.804, 0.805, 0.8, 0.805, 0.806, 0.803, 0.803, 0.804, 0.803], [0.8724449999999997, 0.787226, 0.7972509999999997, 0.8083279999999999, 0.808991, 0.7839999999999998, 0.821152, 0.78316, 0.8320400000000006, 0.8136529999999996])
diff --git a/fast/Dockerfile-SC b/fast/Dockerfile-SC
deleted file mode 100644
index 40e228222e..0000000000
--- a/fast/Dockerfile-SC
+++ /dev/null
@@ -1,19 +0,0 @@
-FROM ubuntu:22.04
-
-# Install dependencies
-RUN apt update \
- && apt install --yes --no-install-recommends git cmake build-essential ca-certificates ninja-build clang lld python3.10-dev pip
-RUN git clone https://github.com/xdslproject/xdsl.git \
- && git clone https://github.com/devitocodes/devito.git \
- && git clone https://github.com/llvm/llvm-project.git
-RUN cd llvm-project \
- && git checkout 89996621de073e43de7bed552037b10d2a0fdf80
-RUN mkdir llvm-project/build \
- && cd llvm-project/build \
- && cmake -G Ninja ../llvm -DLLVM_ENABLE_PROJECTS="mlir;clang;openmp" -DLLVM_BUILD_EXAMPLES=ON -DLLVM_TARGETS_TO_BUILD="X86" -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_ASSERTIONS=OFF -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DLLVM_ENABLE_LLD=ON
-RUN cd llvm-project/build \
- && cmake --build . --target install
-RUN cd xdsl \
- && pip install -r requirements.txt .
-RUN cd devito \
- && pip install -r requirements.txt .
diff --git a/fast/Makefile b/fast/Makefile
deleted file mode 100644
index be7c2123ca..0000000000
--- a/fast/Makefile
+++ /dev/null
@@ -1,67 +0,0 @@
-NIXOS_CLANG_PREFIX ?=
-CC = clang
-
-# Add flags for C
-CFLAGS = -O3
-
-# MODE decides if we want to compile for gpu or cpu
-# might be extended to omp and others as well
-MODE ?= cpu
-DUMP ?= 1
-
-ifeq ($(DUMP),0)
-CFLAGS += -DNODUMP
-endif
-
-# handle gpu flags for clang
-ifeq ($(MODE),gpu)
-CFLAGS += -lmlir_cuda_runtime
-BENCH_OPTS_EXTRA += --gpu
-else ifeq ($(MODE),cpu)
-else ifeq ($(MODE),openmp)
-BENCH_OPTS_EXTRA += --openmp
-else ifeq ($(MODE),mpi)
-BENCH_OPTS_EXTRA += --mpi
-COMPARE_FLAGS += --mpi
-endif
-
-MAIN_MLIR_FILE_PIPELINE := "builtin.module(canonicalize, convert-scf-to-cf, convert-cf-to-llvm{index-bitwidth=64}, convert-math-to-llvm, convert-arith-to-llvm{index-bitwidth=64}, $(MEMREF_TO_LLVM_PASS){index-bitwidth=64}, convert-func-to-llvm, reconcile-unrealized-casts, canonicalize)"
-
-.PHONY: %.bench
-ifeq ($(DUMP), 0)
-BENCH_OPTS_EXTRA = --no_output_dump
-.PHONY: %.stencil.data
-endif
-
-.PRECIOUS: %.stencil.data %.input.data
-
-# this creates the devito data. afaik devito requires gcc for this on my machine. Probably nixos related :S
-# it calls the example script with the bench options, meaning it runs normal devito
-# Can just do DEVITO_ARCH=gcc or DEVITO_ARCH=clang to pick up compiler
-%.devito.data %.input.data: CC = gcc
-%.devito.data %.input.data:
- $(DEVITO_ENV) python3 fast_benchmarks.py $* $(BENCH_OPTS) $(BENCH_OPTS_EXTRA)
-
-# this calls the example file with the `-xdsl` flag so it dumps the mlir files
-%.mlir %.main.o %.interop.o %.kernel.o %.out %.stencil.data: %.input.data
- $(DEVITO_ENV) python3 fast_benchmarks.py $* $(BENCH_OPTS) $(BENCH_OPTS_EXTRA) -xdsl
-
-ifeq ($(DUMP),0)
-%.bench: %.stencil.data %.devito.data
- @echo "Done with no dumps, skipping output comparison"
-else
-%.bench: %.stencil.data %.devito.data
- python3 compare.py --name $(patsubst %.bench,%,$@) $(BENCH_OPTS) $(COMPARE_FLAGS)
-endif
-
-
-#python3 compare.py $(BENCH_OPTS) --name $(patsubst %.bench,%,$@)
-
-.PHONY: %.bench clean
-
-# remove all intermediates and results
-clean:
- rm -f *.mlir
- rm -f *.o
- rm -f *.data
- rm -f *.out
\ No newline at end of file
diff --git a/fast/auto_benchmark.py b/fast/auto_benchmark.py
deleted file mode 100644
index edc10de842..0000000000
--- a/fast/auto_benchmark.py
+++ /dev/null
@@ -1,125 +0,0 @@
-from runner import run_benchmark, PerfReport
-import csv
-
-dims = {"2d5pt": 2, "3d_diff": 3}
-
-def thread_scale(name: str, qos: str = 'standard'):
- flags = '-nt 100 --xdsl --devito --openmp'
- shape = [20000, 20000]
- env_base = "OMP_PLACES=cores"
- runs = 10
-
- raw_results = []
-
- result_lines = []
-
- for num_threads in (1, 2, 4, 8, 16, 32, 64, 128):
- env = env_base + f' OMP_NUM_THREADS={num_threads}'
- results = run_benchmark(
- ranks=1,
- cpus_per_rank=num_threads,
- name=name,
- shape=shape,
- flags=flags,
- runs=runs,
- env=env
- )
- raw_results.extend(results)
-
- for res in results:
- res.report()
- assert len(res.times) == 1
- result_lines.append((
- num_threads, res.impl_name, res.times[0]
- ))
- # write csv file
- with open(f'{name}_grid_runtimes.csv', 'w') as f:
- w = csv.writer(f)
- w.writerow(['num_threads', 'implementation', 'time'])
- w.writerows(result_lines)
-
- # write raw data as json lines
- with open(f'{name}_grid_runtimes.json', 'w') as f:
- for r in raw_results:
- f.write(r.to_json() + '\n')
-
-
-def mpi_scale_2d5pt(qos="standard"):
- flags = '-nt 100 --xdsl --devito --openmp --mpi'
- cpus_per_rank=4
- env = f"OMP_PLACES=cores OMP_NUM_THREADS={cpus_per_rank} DEVITO_MPI=1"
- shape = [2000, 2000]
- runs = 5
-
- raw_results = []
-
- result_lines = []
-
- for ranks in (1, 2, 4, 8, 16, 32, 64, 128):
- results = run_benchmark(
- ranks=ranks,
- cpus_per_rank=cpus_per_rank,
- name='2d5pt',
- shape=shape,
- flags=flags,
- runs=runs,
- env=env,
- qos=qos,
- )
- raw_results.extend(results)
-
- for res in results:
- res.report()
- result_lines.append((
- ranks, res.impl_name, sum(res.times) / len(res.times)
- ))
- # write csv file
- with open(f'2d5pt_mpi_runtimes.csv', 'w') as f:
- w = csv.writer(f)
- w.writerow(['ranks', 'implementation', 'time'])
- w.writerows(result_lines)
-
- # write raw data as json lines
- with open(f'2d5pt_mpi_runtimes.json', 'w') as f:
- for r in raw_results:
- f.write(r.to_json() + '\n')
-
-def mpi_thread_scale_2d5pt(qos="standard"):
- flags = '-nt 100 --xdsl --devito --openmp --mpi'
- ranks = 16
- env = f"OMP_PLACES=cores DEVITO_MPI=1"
- shape = [20000, 20000]
- runs = 5
-
- raw_results = []
-
- result_lines = []
-
- for cpus_per_rank in (1, 2, 4, 8, 16, 32):
- results = run_benchmark(
- ranks=ranks,
- cpus_per_rank=cpus_per_rank,
- name='2d5pt',
- shape=shape,
- flags=flags,
- runs=runs,
- env=env + f' OMP_NUM_THREADS={cpus_per_rank}',
- qos=qos,
- )
- raw_results.extend(results)
-
- for res in results:
- res.report()
- result_lines.append((
- cpus_per_rank, res.impl_name, sum(res.times) / len(res.times)
- ))
- # write csv file
- with open(f'2d5pt_mpi_threads_runtimes.csv', 'w') as f:
- w = csv.writer(f)
- w.writerow(['cpus', 'implementation', 'time'])
- w.writerows(result_lines)
-
- # write raw data as json lines
- with open(f'2d5pt_mpi_threads_runtimes.json', 'w') as f:
- for r in raw_results:
- f.write(r.to_json() + '\n')
diff --git a/fast/compare.py b/fast/compare.py
deleted file mode 100644
index bae1c3889b..0000000000
--- a/fast/compare.py
+++ /dev/null
@@ -1,106 +0,0 @@
-import argparse
-import sys
-
-import numpy as np
-
-parser = argparse.ArgumentParser(description="Process arguments.")
-
-parser.add_argument(
- "-d", "--shape", type=int, nargs="+", help="Number of grid points along each axis"
-)
-parser.add_argument(
- "-so", "--space_order", default=2, type=int, help="Space order of the simulation"
-)
-parser.add_argument(
- "-to", "--time_order", default=1, type=int, help="Time order of the simulation"
-)
-parser.add_argument(
- "-nt", "--nt", default=10, type=int, help="Simulation time in millisecond"
-)
-parser.add_argument("-n", "--name", type=str, help="benchmark name")
-parser.add_argument("--mpi", default=False, action="store_true")
-
-args, unknown = parser.parse_known_args()
-
-bench_name = args.name
-
-
-def prod(iter):
- carry = 1
- for x in iter:
- carry *= x
- return carry
-
-
-dtype = np.float32
-shape = args.shape
-
-devito_file = bench_name + ".devito.data"
-stencil_file = bench_name + ".stencil.data"
-
-devito_data = np.fromfile(devito_file, dtype=dtype)
-stencil_data = np.fromfile(stencil_file, dtype=dtype)
-
-try:
- assert prod(devito_data.shape) == prod(shape)
-except:
- raise AssertionError("Wrong shape specified to the compare script!")
-
-# find halo size:
-# this assumes that halo is equal in all directions
-ndims = len(shape)
-# number of elements that are "too many". We have to divide them equally into the halo
-total_elms = stencil_data.shape[0]
-
-for halo in range(0, 20):
- if total_elms <= (prod(shape_elm + halo for shape_elm in shape)):
- break
-
-assert total_elms == prod(
- shape_elm + halo for shape_elm in shape
-), "Could not correctly infer halo"
-
-assert halo
-
-# set to the number of "columns" of nodes
-# this is a bit weird, but trust me.
-nodes = 4
-if args.mpi:
- print("Unmangling MPI gathered data")
- # load data and re-order
- stencil = np.zeros(args.shape)
- local_dims = args.shape[0], args.shape[1] // nodes
- for i in range(nodes):
- for i in range(nodes):
- local = stencil_data[(i * prod(local_dims)):((i+1) * prod(local_dims))].reshape(local_dims)
- stencil[:,(i * local_dims[1]):((i+1) * local_dims[1])] = local
- stencil_data = stencil
-else:
-
- # reshape into expanded form
- stencil_data = stencil_data.reshape(tuple(shape_elm + halo for shape_elm in shape))
- # cut off the halo
- if len(shape) == 2:
- stencil_data = stencil_data[(halo // 2) : -(halo // 2), (halo // 2) : -(halo // 2)]
- if len(shape) == 3:
- stencil_data = stencil_data[
- (halo // 2) : -(halo // 2),
- (halo // 2) : -(halo // 2),
- (halo // 2) : -(halo // 2),
- ]
-
-
-# reshape into normal shape
-devito_data = devito_data.reshape(shape)
-error_data = devito_data - stencil_data
-
-print("Max error: {}".format(np.absolute(error_data).max()))
-print(f"Mean Squred Error: {(error_data**2).mean()}")
-abs_max = np.maximum(np.absolute(devito_data), np.absolute(stencil_data)).max()
-print("Max abs value: {}".format(abs_max))
-
-devito_norm = np.linalg.norm(devito_data)
-stencil_norm = np.linalg.norm(stencil_data)
-print(f"Norms (Devito/xDSL) : \n{devito_norm}\n{stencil_norm}")
-assert np.isclose(devito_norm, stencil_norm, rtol=1e-6)
-assert np.isclose(stencil_data, devito_data, rtol=1e-6).all()
diff --git a/fast/interop.c b/fast/interop.c
deleted file mode 100644
index 3471217ae4..0000000000
--- a/fast/interop.c
+++ /dev/null
@@ -1,239 +0,0 @@
-#include
-#include
-#include
-#include
-#include
-
-typedef float f32;
-typedef double f64;
-
-typedef int32_t i32;
-typedef int64_t i64;
-
-typedef int8_t i8;
-
-#define MEMREF_STRUCT_DEF(dtype, rank) struct dtype ## _memref_r_ ## rank { \
- dtype *allocated; \
- dtype *aligned; \
- intptr_t offset; \
- intptr_t sizes[rank]; \
- intptr_t strides[rank]; \
-}; \
-
-#ifndef OUTFILE_NAME
-#define OUTFILE_NAME "result.data"
-#endif
-
-#ifndef INFILE_NAME
-#define INFILE_NAME "input.data"
-#endif
-
-// define memref rank 1 to 3 for f32, f64, i32, i64
-// these will be named f32_memref_r_2 for example
-
-MEMREF_STRUCT_DEF(i8, 1)
-MEMREF_STRUCT_DEF(i8, 2)
-MEMREF_STRUCT_DEF(i8, 3)
-
-MEMREF_STRUCT_DEF(f32, 1)
-MEMREF_STRUCT_DEF(f32, 2)
-MEMREF_STRUCT_DEF(f32, 3)
-
-MEMREF_STRUCT_DEF(i32, 1)
-MEMREF_STRUCT_DEF(i32, 2)
-MEMREF_STRUCT_DEF(i32, 3)
-
-MEMREF_STRUCT_DEF(f64, 1)
-MEMREF_STRUCT_DEF(f64, 2)
-MEMREF_STRUCT_DEF(f64, 3)
-
-MEMREF_STRUCT_DEF(i64, 1)
-MEMREF_STRUCT_DEF(i64, 2)
-MEMREF_STRUCT_DEF(i64, 3)
-
-
-// code for packing/unpacking memrefs to/from args
-// please don't look at this too closely here:
-#define REP0(X)
-#define REP1(X) X ## _1
-#define REP2(X) REP1(X) , X ## _2
-#define REP3(X) REP2(X) , X ## _3
-#define REP4(X) REP3(X) , X ## _4
-#define REP5(X) REP4(X) , X ## _5
-#define REP6(X) REP5(X) , X ## _6
-#define REP7(X) REP6(X) , X ## _7
-#define REP8(X) REP7(X) , X ## _8
-#define REP9(X) REP8(X) , X ## _9
-#define REP10(X) REP9(X) , X ## _10
-
-
-#define UNPACK_REP0(X)
-#define UNPACK_REP1(X) X[0]
-#define UNPACK_REP2(X) UNPACK_REP1(X) , X[1]
-#define UNPACK_REP3(X) UNPACK_REP2(X) , X[2]
-#define UNPACK_REP4(X) UNPACK_REP3(X) , X[3]
-#define UNPACK_REP5(X) UNPACK_REP4(X) , X[4]
-#define UNPACK_REP6(X) UNPACK_REP5(X) , X[5]
-#define UNPACK_REP7(X) UNPACK_REP6(X) , X[6]
-#define UNPACK_REP8(X) UNPACK_REP7(X) , X[7]
-#define UNPACK_REP9(X) UNPACK_REP8(X) , X[8]
-#define UNPACK_REP10(X) UNPACK_REP9(X) , X[9]
-
-#define UNPACK_NO_COMMA_REP0(X)
-#define UNPACK_NO_COMMA_REP1(X) X[0]
-#define UNPACK_NO_COMMA_REP2(X) UNPACK_NO_COMMA_REP1(X) X[1]
-#define UNPACK_NO_COMMA_REP3(X) UNPACK_NO_COMMA_REP2(X) X[2]
-#define UNPACK_NO_COMMA_REP4(X) UNPACK_NO_COMMA_REP3(X) X[3]
-#define UNPACK_NO_COMMA_REP5(X) UNPACK_NO_COMMA_REP4(X) X[4]
-#define UNPACK_NO_COMMA_REP6(X) UNPACK_NO_COMMA_REP5(X) X[5]
-#define UNPACK_NO_COMMA_REP7(X) UNPACK_NO_COMMA_REP6(X) X[6]
-#define UNPACK_NO_COMMA_REP8(X) UNPACK_NO_COMMA_REP7(X) X[7]
-#define UNPACK_NO_COMMA_REP9(X) UNPACK_NO_COMMA_REP8(X) X[8]
-#define UNPACK_NO_COMMA_REP10(X) UNPACK_NO_COMMA_REP9(X) X[9]
-
-// oh god, this is unholy:
-
-#define MEMREF_AS_ARGS_DEF(prefix, dtype, rank) dtype * prefix ## allocated, dtype * prefix ## aligned, intptr_t prefix ## offset, REP ## rank (intptr_t prefix ## sizes), REP ## rank (intptr_t prefix ## strides)
-
-#define COLLECT_MEMREF_ARGS_INTO(prefix, dtype, rank, name) struct dtype ## _memref_r_ ## rank name = { prefix ## allocated, prefix ## aligned, prefix ## offset, REP ## rank (prefix ## sizes), REP ## rank (prefix ## strides) }
-
-#define MEMREF_TO_ARGS(ref, rank) ref.allocated, ref.aligned, ref.offset, UNPACK_REP ## rank (ref.sizes), UNPACK_REP ## rank (ref.strides)
-
-// dumping memref macros:
-
-#if NODUMP
-#define DUMP_MEMREF(fname, name, dtype, rank) \
- { \
- printf("Skipping output dumping!\n"); \
- }
-#else
-#define DUMP_MEMREF(fname, name, dtype, rank) \
- { \
- FILE *f = fopen(fname, "w"); \
- fwrite(name.aligned, sizeof(dtype), 1 UNPACK_NO_COMMA_REP##rank(*name.sizes), f); \
- fclose(f); \
- }
-#endif
-
-// linearized accesses:
-
-#define LIN_ACCESS2(ref, x, y) ref.aligned[(x) * ref.sizes[1] + (y)]
-#define LIN_ACCESS3(ref, x, y, z) ref.aligned[(x) * ref.sizes[1] * ref.sizes[2] + (y) * ref.sizes[2] + (z)]
-
-// dumping methods:
-
-#define GENERATE_DUMPING_FUNC(dtype, rank) void dump_memref_ ## dtype ## _rank_ ## rank (MEMREF_AS_ARGS_DEF(my, dtype, rank)) { \
- COLLECT_MEMREF_ARGS_INTO(my, dtype, rank, my_memref); \
- DUMP_MEMREF(OUTFILE_NAME, my_memref, dtype, rank) \
-}
-
-// generate function defs:
-
-GENERATE_DUMPING_FUNC(f32, 1)
-GENERATE_DUMPING_FUNC(f32, 2)
-GENERATE_DUMPING_FUNC(f32, 3)
-
-GENERATE_DUMPING_FUNC(f64, 1)
-GENERATE_DUMPING_FUNC(f64, 2)
-GENERATE_DUMPING_FUNC(f64, 3)
-
-GENERATE_DUMPING_FUNC(i32, 1)
-GENERATE_DUMPING_FUNC(i32, 2)
-GENERATE_DUMPING_FUNC(i32, 3)
-
-GENERATE_DUMPING_FUNC(i64, 1)
-GENERATE_DUMPING_FUNC(i64, 2)
-GENERATE_DUMPING_FUNC(i64, 3)
-
-/*
-This file provides the following functions for MLIR:
-
-func.func private @dump_memref_i32_rank_1(memref) -> ()
-func.func private @dump_memref_f32_rank_1(memref) -> ()
-func.func private @dump_memref_i64_rank_1(memref) -> ()
-func.func private @dump_memref_f64_rank_1(memref) -> ()
-
-func.func private @dump_memref_i32_rank_2(memref) -> ()
-func.func private @dump_memref_f32_rank_2(memref) -> ()
-func.func private @dump_memref_i64_rank_2(memref) -> ()
-func.func private @dump_memref_f64_rank_2(memref) -> ()
-
-func.func private @dump_memref_i32_rank_3(memref) -> ()
-func.func private @dump_memref_f32_rank_3(memref) -> ()
-func.func private @dump_memref_i64_rank_3(memref) -> ()
-func.func private @dump_memref_f64_rank_3(memref) -> ()
-
-You can call them using:
-
-func.call @dump_memref_f64_rank_3(%ref) : (memref) -> ()
-
-or any other signature as provided above
-
-The output file will be outfile
-
-*/
-
-const struct i8_memref_r_1 load_memref(char* fname, size_t length) {
- void* ptr = aligned_alloc(64, length);
- struct i8_memref_r_1 ref = {ptr, ptr, 0, length, 1};
- FILE* f = fopen(fname,"r");
- size_t num = fread(ptr, 1, length, f);
- if (num != length) {
- printf("WARN: file read failed! Only read %ld bytes!\n", num);
- }
- fclose(f);
- return ref;
-}
-
-struct i8_memref_r_1 load_input(size_t length) {
- return load_memref(INFILE_NAME, length);
-}
-
-void print_i32(int n)
-{
- printf("%d\n", n);
-}
-
-double timer_start() {
- // return a number representing the current point in time
- // it might be offset by a fixed ammount
- struct timespec t;
- clock_gettime(CLOCK_MONOTONIC, &t);
- return (t.tv_sec) + (t.tv_nsec * 1e-9);
-}
-
-double timer_end(double start) {
- // return time elaspes since start in seconds
- return (timer_start() - start);
-}
-
-#ifdef MPI_ENABLE
-
-extern int MPI_Comm_rank(int comm, int *rank);
-
-void print_halo_send_info(int dest, int ex, i64 x0, i64 y0, i64 h, i64 w) {
- int rank;
- MPI_Comm_rank(1140850688, &rank);
- i64 x1 = x0 + h-1;
- i64 y1 = y0 + w-1;
- printf("MPI send ex%i [%li:%li,%li:%li] %i -> %i\n",ex, x0, x1, y0, y1, rank, dest);
-}
-
-void print_halo_recv_info(int src, int ex, i64 x0, i64 y0, i64 h, i64 w) {
- int rank;
- MPI_Comm_rank(1140850688, &rank);
- i64 x1 = x0 + h-1;
- i64 y1 = y0 + w-1;
- printf("MPI recv ex%i [%li:%li,%li:%li] %i <- %i\n",ex, x0, x1, y0, y1, rank, src);
-}
-
-void dump_memref_per_rank(MEMREF_AS_ARGS_DEF(my, f32, 2), i64 index) {
- COLLECT_MEMREF_ARGS_INTO(my, f32, 2, my_memref);
- char name[512];
- int rank;
- MPI_Comm_rank(1140850688, &rank);
- sprintf(name, "result-rank-%i-buff-%" PRId64 ".data", rank, index);
- DUMP_MEMREF(name, my_memref, f32, 2)
-}
-
-#endif
diff --git a/fast/mfe_2D.py b/fast/mfe_2D.py
deleted file mode 100644
index 42e0ec213b..0000000000
--- a/fast/mfe_2D.py
+++ /dev/null
@@ -1,73 +0,0 @@
-# A 2D heat diffusion using Devito
-# BC modelling included
-# PyVista plotting included
-
-import argparse
-import numpy as np
-
-from devito import Grid, TimeFunction, Eq, solve, Operator, Constant, norm, XDSLOperator
-from examples.seismic import plot_image
-from examples.cfd import init_hat
-
-parser = argparse.ArgumentParser(description='Process arguments.')
-
-parser.add_argument("-d", "--shape", default=(11, 11), type=int, nargs="+",
- help="Number of grid points along each axis")
-parser.add_argument("-so", "--space_order", default=2,
- type=int, help="Space order of the simulation")
-parser.add_argument("-to", "--time_order", default=1,
- type=int, help="Time order of the simulation")
-parser.add_argument("-nt", "--nt", default=40,
- type=int, help="Simulation time in millisecond")
-parser.add_argument("-bls", "--blevels", default=2, type=int, nargs="+",
- help="Block levels")
-parser.add_argument("-plot", "--plot", default=False, type=bool, help="Plot3D")
-args = parser.parse_args()
-
-# Some variable declarations
-nx, ny = args.shape
-nt = args.nt
-nu = .5
-dx = 1. / (nx - 1)
-dy = 1. / (ny - 1)
-sigma = .25
-
-dt = sigma * dx * dy / nu
-so = args.space_order
-to = args.time_order
-
-print("dx %s, dy %s" % (dx, dy))
-
-grid = Grid(shape=(nx, ny), extent=(2., 2.))
-u = TimeFunction(name='u', grid=grid, space_order=so)
-
-# Reset our data field and ICs
-#init_hat(field=u.data[0], dx=dx, dy=dy, value=1.)
-u.data[:, 2:3, 2:3] = 1
-
-a = Constant(name='a')
-# Create an equation with second-order derivatives
-# eq = Eq(u.dt, a * u.laplace, subdomain=grid.interior)
-eq = Eq(u.dt, a * u.laplace)
-stencil = solve(eq, u.forward)
-eq_stencil = Eq(u.forward, stencil)
-
-# Create boundary condition expressions
-x, y = grid.dimensions
-t = grid.stepping_dim
-
-initdata = u.data[:]
-op = Operator([eq_stencil], name='DevitoOperator')
-op.apply(time=nt, dt=dt, a=nu)
-print(u.data[0, :])
-print("Devito Field norm is:", norm(u))
-
-u.data[:, : , :] = 0
-u.data[:, 2:3 , 2:3] = 1
-# Reset data and run XDSLOperator
-#init_hat(field=u.data[0], dx=dx, dy=dy, value=1.)
-xdslop = Operator([eq_stencil], name='XDSLOperator')
-xdslop.apply(time=nt, dt=dt, a=nu)
-print(u.data[0, :])
-
-print("XDSL Field norm is:", norm(u))
diff --git a/fast/nd_nwave_devito_nodamp.py b/fast/nd_nwave_devito_nodamp.py
deleted file mode 100644
index 5860575b51..0000000000
--- a/fast/nd_nwave_devito_nodamp.py
+++ /dev/null
@@ -1,140 +0,0 @@
-# Based on the implementation of the Devito acoustic example implementation
-# Not using Devito's source injection abstraction
-import numpy as np
-from devito import TimeFunction, Eq, Operator, solve, norm, XDSLOperator
-from examples.seismic import RickerSource
-from examples.seismic import Model, TimeAxis
-
-from devito.tools import as_tuple
-
-import argparse
-
-parser = argparse.ArgumentParser(description='Process arguments.')
-
-parser.add_argument("-d", "--shape", default=(11, 11, 11), type=int, nargs="+",
- help="Number of grid points along each axis")
-parser.add_argument("-so", "--space_order", default=4,
- type=int, help="Space order of the simulation")
-parser.add_argument("-to", "--time_order", default=2,
- type=int, help="Time order of the simulation")
-parser.add_argument("-nt", "--nt", default=200,
- type=int, help="Simulation time in millisecond")
-parser.add_argument("-bls", "--blevels", default=2, type=int, nargs="+",
- help="Block levels")
-parser.add_argument("-plot", "--plot", default=False, type=bool, help="Plot3D")
-args = parser.parse_args()
-
-
-def plot_3dfunc(u):
- # Plot a 3D structured grid using pyvista
-
- import matplotlib.pyplot as plt
- import pyvista as pv
- cmap = plt.colormaps["viridis"]
- values = u.data[0, :, :, :]
- vistagrid = pv.UniformGrid()
- vistagrid.dimensions = np.array(values.shape) + 1
- vistagrid.spacing = (1, 1, 1)
- vistagrid.origin = (0, 0, 0) # The bottom left corner of the data set
- vistagrid.cell_data["values"] = values.flatten(order="F")
- vistaslices = vistagrid.slice_orthogonal()
- # vistagrid.plot(show_edges=True)
- vistaslices.plot(cmap=cmap)
-
-
-# Define a physical size
-# nx, ny, nz = args.shape
-nt = args.nt
-
-shape = (args.shape) # Number of grid point (nx, ny, nz)
-spacing = as_tuple(10.0 for _ in range(len(shape))) # Grid spacing in m. The domain size is now 1km by 1km
-origin = as_tuple(0.0 for _ in range(len(shape))) # What is the location of the top left corner.
-# This is necessary to define
-# the absolute location of the source and receivers
-
-# Define a velocity profile. The velocity is in km/s
-v = np.empty(shape, dtype=np.float32)
-v[:, ..., :] = 1
-
-# With the velocity and model size defined, we can create the seismic model that
-# encapsulates this properties. We also define the size of the absorbing layer as
-# 10 grid points
-so = args.space_order
-to = args.time_order
-
-model = Model(vp=v, origin=origin, shape=shape, spacing=spacing,
- space_order=so, nbl=0)
-
-# plot_velocity(model)
-
-t0 = 0. # Simulation starts a t=0
-tn = nt # Simulation last 1 second (1000 ms)
-dt = model.critical_dt # Time step from model grid spacing
-print("dt is:", dt)
-
-time_range = TimeAxis(start=t0, stop=tn, step=dt)
-
-# The source is positioned at a $20m$ depth and at the middle of the
-# $x$ axis ($x_{src}=500m$),
-# with a peak wavelet frequency of $10Hz$.
-f0 = 0.010 # Source peak frequency is 10Hz (0.010 kHz)
-src = RickerSource(name='src', grid=model.grid, f0=f0,
- npoint=1, time_range=time_range)
-
-# First, position source centrally in all dimensions, then set depth
-src.coordinates.data[0, :] = np.array(model.domain_size) * .5
-
-# We can plot the time signature to see the wavelet
-#src.show()
-
-# Define the wavefield with the size of the model and the time dimension
-u = TimeFunction(name="u", grid=model.grid, time_order=to, space_order=so)
-
-# We can now write the PDE
-# pde = model.m * u.dt2 - u.laplace + model.damp * u.dt
-# import pdb;pdb.set_trace()
-pde = u.dt2 - u.laplace
-
-# The PDE representation is as on paper
-pde
-
-stencil = Eq(u.forward, solve(pde, u.forward))
-stencil
-
-# Finally we define the source injection and receiver read function to generate
-# the corresponding code
-print(time_range)
-src_term = src.inject(field=u.forward, expr=src * dt**2 / model.m)
-op = Operator([stencil] + src_term, subs=model.spacing_map, name='DevitoOperator')
-# Run with source and plot
-op.apply(time=time_range.num-1, dt=model.critical_dt)
-
-if len(shape) == 3:
- if args.plot:
- plot_3dfunc(u)
-
-initdata = u.data[:]
-
-# Run more with no sources now (Not supported in xdsl)
-op = Operator([stencil], name='DevitoOperator', opt='noop')
-op.apply(time=time_range.num-1, dt=model.critical_dt)
-
-if len(shape) == 3:
- if args.plot:
- plot_3dfunc(u)
-
-
-devito_output = u.copy()
-print("Devito norm:", norm(u))
-print(f"devito output norm: {norm(devito_output)}")
-
-# Reset initial data
-u.data[:] = initdata
-
-# Run more with no sources now (Not supported in xdsl)
-xdslop = XDSLOperator([stencil], name='xDSLOperator')
-xdslop.apply(time=time_range.num-1, dt=model.critical_dt)
-
-xdsl_output = u.copy()
-print("XDSL norm:", norm(u))
-print(f"xdsl output norm: {norm(xdsl_output)}")
diff --git a/fast/plot_grid_scale.py b/fast/plot_grid_scale.py
deleted file mode 100644
index 14a4aa7338..0000000000
--- a/fast/plot_grid_scale.py
+++ /dev/null
@@ -1,70 +0,0 @@
-
-from ast import literal_eval
-from math import floor, log
-import sys
-import matplotlib.pyplot as plt
-import numpy as np
-
-dims = {"2d5pt": 2, "3d_diff": 3}
-
-if len(sys.argv) < 2 or len(sys.argv) > 3:
- print(f"usage: {sys.argv[0]} [first]")
- print("plot data starting from the 0-indexed [first] line, defaulting to 0.")
- sys.exit(1)
-
-benchmark = sys.argv[1]
-first = int(sys.argv[2]) if len(sys.argv) > 2 else 0
-
-csv_name = f"{benchmark}_grid_runtimes.csv"
-pdf_name = f"devito_{benchmark}_probsize_cpu.pdf"
-
-def human_format(number: int):
- units = ['', 'K', 'M', 'G', 'T', 'P']
- k = 1000.0
- magnitude = int(floor(log(number, k)))
- if magnitude == 0 :
- return str(number)
- return '%.2f%s' % (number / k**magnitude, units[magnitude])
-try:
- with open(csv_name, "r") as f:
- lines = f.read().split("\n")[:-1]
- header_line = lines[0].split(",")
- x_label = header_line[0]
- labels = header_line[1:]
-
- lines = list(map(literal_eval, lines[1+first:]))
-
- grid_size: list[tuple[int, ...]] = []
- values:dict[str, list[float]] = {}
- for label in labels:
- values[label] = []
- for line in lines:
- grid_size.append(line[0])
- for i, label in enumerate(labels):
- print(f"line {line} i {i}")
- values[label].append(sum(line[i+1])/len(line[i+1]))
-
- x = np.arange(len(grid_size)) #type: ignore
- width = 0.25 # the width of the bars
- multiplier = 0
-
- fig, ax = plt.subplots(layout="constrained") #type: ignore
-
- for attribute, measurement in values.items():
- offset = width * multiplier
- rects = ax.bar(x + offset, measurement, width, label=attribute) #type: ignore
- # ax.bar_label(rects, padding=3)
- multiplier += 1
-
- # Add some text for labels, title and custom x-axis tick labels, etc.
- ax.set_ylabel("Time (s)") #type: ignore
- ax.set_xlabel(x_label) # type: ignore
- ax.set_xticks(x + width, grid_size)
- ax.legend(loc="upper left", ncols=3) #type: ignore
- fig.autofmt_xdate()
-
- plt.savefig(pdf_name, format="pdf") #type: ignore
- plt.show() #type: ignore
-except FileNotFoundError:
- print(f'{csv_name} not found! Try running "python grid_scale.py {sys.argv[1]}" to generate it." ')
- sys.exit(1)
\ No newline at end of file
diff --git a/fast/plot_thread.py b/fast/plot_thread.py
deleted file mode 100644
index 7f27344c22..0000000000
--- a/fast/plot_thread.py
+++ /dev/null
@@ -1,74 +0,0 @@
-
-from ast import literal_eval
-import sys
-import matplotlib.pyplot as plt
-import numpy as np
-
-dims = {"2d5pt": 2, "3d_diff": 3}
-
-if len(sys.argv) < 2 or len(sys.argv) > 3:
- print(f"usage: {sys.argv[0]} [first]")
- print("plot data starting from the 0-indexed [first] line, defaulting to 0.")
- sys.exit(1)
-
-benchmark = sys.argv[1]
-first = int(sys.argv[2]) if len(sys.argv) > 2 else 0
-
-
-pdf_name = f"devito_{benchmark}_nthreads_cpu.pdf"
-
-modes = ["xdsl", "devito"]
-
-labels:list[str] = []
-nthreads: set[int] | list[int] = set()
-x_label = "Threads"
-values:dict[str, list[float]] = {}
-for mode in modes:
- csv_name = f"{benchmark}_threads_{mode}.csv"
- try:
- with open(csv_name, "r") as f:
- lines = f.read().split("\n")[:-1]
-
- labels.append(mode)
-
- lines = list(map(literal_eval, lines[1+first:]))
- if mode not in values.keys():
- values[mode] = []
- for line in lines:
- nthreads.add(line[0])
- print(f"line {line}")
- # line[1] is the list of runtimes
- # Here I'm just plotting the average!
- values[mode].append(sum(line[1])/len(line[1]))
-
- except FileNotFoundError:
- print(f'{csv_name} not found! Try running "python grid_scale.py {sys.argv[1]} {mode}" to generate it." ')
- sys.exit(1)
-nthreads = list(nthreads)
-nthreads.sort()
-
-print(nthreads)
-print(labels)
-print(values)
-x = np.arange(len(nthreads)) #type: ignore
-width = 0.25 # the width of the bars
-multiplier = 0
-
-fig, ax = plt.subplots(layout="constrained") #type: ignore
-
-for attribute, measurement in values.items():
- offset = width * multiplier
- rects = ax.bar(x + offset, measurement, width, label=attribute) #type: ignore
- # ax.bar_label(rects, padding=3)
- multiplier += 1
-
-# Add some text for labels, title and custom x-axis tick labels, etc.
-ax.set_ylabel("Time (s)") #type: ignore
-ax.set_xlabel(x_label) # type: ignore
-ax.set_xticks(x + width, nthreads)
-ax.legend(loc="upper left", ncols=3) #type: ignore
-fig.autofmt_xdate()
-
-print(f"saving to {pdf_name}")
-plt.savefig(pdf_name, format="pdf") #type: ignore
-plt.show() #type: ignore
\ No newline at end of file
diff --git a/fast/results/.gitignore b/fast/results/.gitignore
deleted file mode 100644
index 22f4e12573..0000000000
--- a/fast/results/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-*.data
-*.data.rank*
-*.data-split
diff --git a/fast/results/viz.ipynb b/fast/results/viz.ipynb
deleted file mode 100644
index 82953427df..0000000000
--- a/fast/results/viz.ipynb
+++ /dev/null
@@ -1,501 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "code",
- "execution_count": 1,
- "id": "d5ca5cfa",
- "metadata": {},
- "outputs": [],
- "source": [
- "import numpy as np\n",
- "import seaborn as sns\n",
- "import matplotlib.pyplot as plt\n",
- "from math import prod"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "id": "511bba3c",
- "metadata": {},
- "outputs": [],
- "source": [
- "sns.set_theme(style=\"white\")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 113,
- "id": "16aa2d61",
- "metadata": {},
- "outputs": [],
- "source": [
- "dims = 5,20\n",
- "halo = (2,2),(2,2)\n",
- "prob = '2d5pt'\n",
- "dtype = np.float32\n",
- "nodes = 4\n",
- "mpi = False"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 116,
- "id": "6d2c936f",
- "metadata": {},
- "outputs": [],
- "source": [
- "devito = np.fromfile(f\"{prob}.devito.data\", dtype).reshape(dims)\n",
- "orig = np.fromfile(f\"{prob}.input.data\", dtype).reshape([(x + h[0] + h[1]) for x, h in zip(dims, halo)])[2:-2,2:-2]\n",
- "\n",
- "if mpi:\n",
- " # load data and re-order\n",
- " stencil_raw = np.fromfile(f\"{prob}.stencil.data\", dtype)[0:prod(dims)]\n",
- " #stencil = stencil_raw.reshape(dims)\n",
- " stencil = np.zeros(dims)\n",
- " local_dims = dims[0], dims[1] // nodes\n",
- " for i in range(nodes):\n",
- " local = stencil_raw[(i * prod(local_dims)):((i+1) * prod(local_dims))].reshape(local_dims)\n",
- " stencil[:,(i * local_dims[1]):((i+1) * local_dims[1])] = local\n",
- "else:\n",
- " stencil = np.fromfile(f\"{prob}.stencil.data\", dtype).reshape([(x + h[0] + h[1]) for x, h in zip(dims, halo)])[2:-2,2:-2]\n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 117,
- "id": "6dfd7284",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "image/png": "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h3vk5ubGmDFj4tlnn43169eXuN+xY8f4xS9+Ef/1X/8VERHDhw+PGTNmRERE+/bt4/XXX9/m2hUx9sMPP4xbb701pk+fHkVFRSXm9ezZMy699NI46KCDdvhYi1u8eHHceOON8frrr5f4GRERse+++8a5554bgwcPjoiIgQMHxsKFCyMionfv3omf1QAAAABQ1TnmGAAAAKqhE044IdGeO3dufPrpp9sd//TTTyfaP/nJTyq0ktvOqgqVy7Z45pln4uSTT95mklBV8dJLLyXiLC2RMGJzsuFvfvOb+Pvf/16psUyaNCmOO+64eP3110tNuouIeP/99+PXv/51/L//9/++9z4TJ06MQYMGxX333bfNRMKIiHXr1sUjjzwSxxxzTEybNu177fXMM8/E6aefvs3kyIjNyYbDhw+PO+6443vtUZnGjRsXZ5xxRqmJhBERhYWFMXXq1DjttNPi+eef/157fPrppzFkyJB44oknSk0kjIj45ptv4pprrokLL7wwNm7c+L32+b4eeuihOOOMM2LatGmlJhJGbE42HD58eLzwwgtlXvfNN9+MIUOGxMsvv7zNnxFz586NESNGxI033vi9YgcAAACAqkJlQgAAAKiGunfvHp07d47PP/88IjYnC+63336ljv3kk08S1e0ikhMRd4WlS5cm9Zs0abJL99+WmTNnxqWXXppIzttyRG9GRkYsW7YsZs2aleIIN5s+fXpcdNFFiTj32muv2HvvvaNhw4axaNGi+Oijj5ISDG+66abo3r17HHLIIZUSywUXXFAiUWzfffeNvfbaKzZt2hSff/55fP311xERcdttt32v43Ufe+yxuPbaa6OwsDBxrWbNmrHvvvtGhw4dom7duonjnrfEsmbNmvj1r38d99xzT/Tt27fMe73zzjtxxRVXJD6HrVq1im7dukXDhg1j8eLF8dFHHyUSDIuKiuLOO++MevXqxTnnnLPTj6sy/OMf/4ixY8cmXatZs2b06NEj2rVrF999913MmzcvFi5cGOvXr49Ro0bFLbfcslN7fPXVV3HWWWeVqCraoUOH6NKlS9SvXz8WLVoUs2bNisLCwnjhhRd26fHgzzzzTPzpT39K9Lt27RodO3aMunXrxjfffBOzZ89OJBjm5+fHpZdeGt26dYu99tpru+vOnDkzzj333BLJk/vss0906tQpatWqFd9880188sknEbH5a1GWKpIAAAAAUFVJJgQAAIBq6oQTTkgkBT377LMxcuTIqFWrVolxEyZMSLT33nvv6NGjx64KMSKiRLW4HSXw7CpXX311bNq0Kfbaa6+46qqr4rDDDku6v27dutiwYUOKovs/F1xwQWzatCkOOeSQuOyyyyIrKyvp/uLFi2PUqFExffr0iNic8HbTTTfFE088UaFxrFu3Li655JKkRMIePXrEn/70p9h3332Txk6fPj2uvPLK+Prrr+OGG27YqX3efffduO666xKJhLVq1Yqzzz47zj777GjRokXS2LVr18Zf//rXuPfee6OoqCg2btwYf/zjH+OZZ54p85HHf/7zn2PTpk3RvHnzuOqqq+KYY46JmjX/7zCPb7/9Nm688cakana33XZbHHbYYSW+Frva559/HmPGjEm6NmTIkLj00kujVatWSdfffPPNuOqqqyI7OzuuuuqqMu9RVFQUl19+eVIi4Z577hnXXXdd9OvXL2ns0qVL48Ybb4wXX3wx/vGPf8Qee+zxPR7Vzlm5cmVcccUVERExaNCguPjii+MHP/hB0pj58+fHhRdemEiqXr9+fdx2221x2223bXPd9evXxyWXXJKUSNitW7e4/vrr44ADDkga++WXX8Y111wT06ZNi5tvvjlq1/YrVwAAAACqJ8ccAwAAQDV1/PHHJ5KecnJy4q233ioxpqCgIOlY06FDh+6q8CJic6LP448/nnTt0EMP3aUxbEteXl506dIlHnvssRKJhBERjRo1KnNCWmXKzc2NQYMGxT/+8Y9Sk9fatm0b99xzT+y5556Jax999FGiamVFueeee2LRokWJ/kEHHRQPPfRQiUTCiIg+ffrEI488EnvuuWesWrWqzHts3LgxLr744kQlwDp16sS9994bf/zjH0skEkZEZGRkxEUXXRR//vOfE9dycnLi3nvvLfOeq1evjiZNmsRDDz0UgwcPTkokjNhcqXDs2LFx2mmnJa4VFBTEddddV+Y9Ksvo0aOTjt497bTTYuzYsSUSCSMiDjvssHjkkUeiffv2kZubW+Y9XnzxxXj33XcT/fbt28fDDz9cIpEwYnN1z9tuuy2GDRsWRUVFO7XP95WXlxcbNmyIM844I+68884SiYQRmysJ3n///dG4cePEtYkTJ273e/PBBx9MVNiMiMjKyoqHHnqoRCJhRESnTp3ib3/7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P1snje1MNbidSUaqirp165bUnzVrVpnnlnVsz549k/pvv/12mfcoj515LKtWrUpKJtx///1LPSZ5V3yvdO/ePdEuKCiImTNnlnmPd955p0zjevTo8b3mRUTMnDlzp5Ioq5LyPO533323osMBAAAAgF1GMiEAAADsJo477rioXbt20rXSEgz5fpo1a5bU/+KLL8o0b+3atfHBBx9UQkS7ztaJfi+99FKZ57744otlGteqVavo3Llzoj99+vRYtGhRmff5vl5++eUoKioq09iXXnop6RjiAw88sNRxu+J75dBDD03qP/XUU2Wat3r16njttdfKNLZr167RpEmTRH/ixIllrpxY1niqooMPPjjpZ+mzzz4bmzZtKtPc6vy4AQAAAEAyIQAAAOwmmjVrFo8//ng8/PDDiY9TTz011WHtNlq1apV0FO/UqVPLlIT20EMPxXfffVeZoVW6fv36JT32F154IalC37ZMmzZtpyrmnXbaaYl2fn5+3HTTTTsX6PewaNGimDBhwg7Hbdy4Me67776ka8cdd1ypY3fF98qAAQOiZcuWif5zzz0XH3300Q7njR07NvLy8sq0R+3atePEE09M9PPy8mLs2LE7nPfhhx/G888/X6Y9qqJmzZrFwIEDE/3s7Ox44IEHdjjvxRdf3KnvdwAAAACoaiQTAgAAwG4kKysrDjnkkMRHo0aNUh3SbqV3796J9pIlS+LJJ5/c7vgZM2bEXXfdVdlhVbo6derEKaeckuhv3LgxLr744li/fv025yxbtiyuuOKKndrntNNOi1atWiX6L730UvzlL39Jqga4I+vXr49nn312p/YdPXr0DqsH/ulPf0pKoOzRo0cccMAB2xxf2d8rderUibPOOivRLywsjHPPPTfmzZu3zTl/+9vf4pFHHinzHhERw4cPjwYNGiT6Dz/8cPztb3/b5vi5c+fGueeeu1Nfs6roV7/6VdSs+X+/Or311lu3myA5bdq0uOyyy3ZFaAAAAABQaSQTAgAAAJTRySefnNS/9tprY8KECSWqzq1fvz7uu++++OUvfxn5+fnRuHHjXRlmpTjnnHOiTZs2if77778fZ555ZsydO7fE2BkzZsQZZ5wRCxYs2KnHXq9evbj11lujTp06iWv33XdfnHnmmfH2229vM0Ft48aNMW3atPjTn/4UAwYMiNGjR5d5z8aNG0dubm4MHz48Xn755RJ75OTkxEUXXRT/+te/Etdq1aoVV1111XbX3RXfK2eddVZkZWUlxXrSSSfFtddeG1OnTo358+fHnDlz4t///necccYZcfPNN0dExODBg8u8R/v27eP3v/990rWbb745fvazn8WECRPik08+ifnz58eUKVPimmuuiZNPPjmWLVsWHTt2jG7dupV5n6qmZ8+eccYZZyT6mzZtij/84Q/xu9/9Ll588cWYO3dufP755/Haa6/FyJEj46yzzoq8vLw46KCDonXr1imMHAAAAAC+v9qpDgAAAACguujfv38cfvjhMXXq1IjYnMQ2atSoGDt2bBxwwAFRv379+Pbbb+Ojjz5KVO076KCDonfv3vHXv/41laGXW0ZGRowePTp+/etfR35+fkRsPs72+OOPj/322y9+8IMfREFBQXz++efx1VdfJeZdfvnlMWrUqDLv88Mf/jCuv/76uPLKKxP7vPPOO3HWWWdF48aNo1u3btG0adOoVatWrFmzJhYvXhxffPFFbNq0KbFGixYtyrzfpZdeGldccUUsW7YsLrjggmjdunV069YtGjZsGIsWLYqPPvooCgoKkuacf/750b179+2uuyu+V2rXrh133XVX/OxnP4vs7OyI2Hw89COPPLLNCoQHHnhgXHjhhfHSSy8lrtWoUWO7+/z85z+P+fPnx+OPP5649s4778Q777xT6vh69erFLbfcEn/5y1/K9DiqqosvvjgWLFgQ//nPfxLXXn/99Xj99ddLHd+kSZMYM2ZMnHnmmbsoQgAAAACoWCoTAgAAAOyE0aNHR5cuXZKuLVmyJCZOnBjPPfdczJgxIyk5bNy4cUmV9qqzvn37xm233Rb169dPuv7pp5/Gyy+/HBMnTkxKJDz//PNj6NChO73PiSeeGP/4xz9KVHhbvXp1TJs2LV588cV47rnn4o033oh58+YlJRJGxE5V9+vdu3fccMMNUatWrYiIWLp0aUyaNCmef/75eP/995MSCWvUqBG/+93v4ne/+12Z1t4V3ytt27aNhx9+OA477LAdjv3pT38a//jHP0okRzZs2HC782rUqBHXXXddjBgxIurWrbvdse3bt4/HHnssevToERs2bEhcr45HrtetWzfuuOOOGD58eNKRx6XZf//9Y/z48dGhQ4dq/7gBAAAASF8qEwIAAADshJYtW8bDDz8cd9xxRzz22GOJ6nnFtW7dOs4444z4xS9+sdskEm4xaNCgePbZZ+PPf/5zTJ48uURiWkREjx494txzz40jjzzye+9zyCGHxKuvvhpPPPFE/Otf/4p58+Ztd3zz5s2jb9++MXjw4PjRj360U3udeOKJsffee8ftt98eb731VqnHKWdlZcXFF18chx56aJnX3VXfK23atIn7778/3njjjXj22Wfjww8/jJycnKhdu3a0bds2evToESeffHL06tUrIiLWrFmTND8zM3OHe9SoUSPOPffc+OlPfxpPPfVUvPHGG7Fo0aL47rvvomXLlrHXXnvFT3/60/jxj3+cSDZdvXp1Yn5GRsb3emypVrdu3bjiiivilFNOiX//+9/x1ltvxZIlSyI/Pz9atWoV++yzTwwdOjQGDhyY+PoV//xW18cNAAAAQHqqUVRUVJTqIAAAAACqo3Xr1sWMGTMiOzs78vLyokWLFtGxY8fo1atXotLd7iwnJyfeeeedWLp0aRQVFUXr1q1jv/32i3322adS9vrwww9j+fLlkZubGzVq1IiMjIxo27ZtdO7cOTp06LDD43rLYsmSJfHhhx/G0qVLY8OGDdGyZcvo0aNH7L333uVatyp9rzz11FNx6aWXJvp33313HHXUURW6x8aNG6NXr16JBMqjjz467rzzzgrdoyrKzs5O+lyeddZZSZ9rAAAAAKjKVCYEAAAA+J4aNWpUrup71V3Lli1jyJAhu2yvQYMGVfo+bdq0iTZt2lT4ulXpe+W9995L6nfr1q3C9/joo4+SKjHuv//+Fb5HVbT15zZdHjcAAAAAu4eaqQ4AAAAAANg11q5dGy+++GKi37Jly2jbtm2F7/Pkk08m9Xv06FHhe1RF48ePT+qny+MGAAAAYPcgmRAAAAAA0sTNN98c69atS/R/+tOfVvge7733XkyYMCHRb9GiRRx66KEVvk9V89xzz8WMGTMS/aysrHIfjw0AAAAAu5JkQgAAAACopt5444249dZbIzc3d7vjNm7cGDfddFP861//SlyrXbt2DBs2rEz7nHfeefHRRx/tcNzbb78dv/vd76KwsDBxbdiwYVGnTp0y7VOV5ObmxoUXXhhffPHFDsc+99xzcdlllyVd++///u/KCg0AAAAAKkWNoqKiolQHAQAAAADsvJdeeilGjBgRdevWjYEDB0bfvn2ja9eu0bRp09i0aVMsW7Ys3nvvvXjqqadi4cKFSXPPPffcGDFiRJn2OeiggyIvLy+ysrJi0KBB0b1792jVqlXUq1cvVq1aFZ9++mm88sorMXXq1KR5nTp1igkTJkT9+vUr7DHvKitWrIi+fftGjRo14pBDDokf/ehHkZWVFS1atIhatWpFbm5ufPzxx/HCCy/E+++/nzS3d+/e8eCDD0aNGjVSFD0AAAAA7LzaqQ4AIN0NHDgw8Qed1157LTp06JDiiAAAALxWqW42btwYL730Urz00ktlGv/jH/84zj333J3eZ/bs2TF79uwyjW3Tpk3ccccd1TKRsLiioqJ455134p133inT+K5du8aYMWMkEgIAAABQ7UgmBAAAANjK8OHDY8aMGaXeq1u3bmRmZkZGRkY0b948unXrFt26dYtDDz002rdvv4sjJd1lZGRE7dq1Y9OmTWUan5mZGeecc078+te/3qlktyZNmkReXl6Zxx911FFx9dVXR+vWrcs8p6qpU6dONGrUKNatW1em8bVq1YoTTjghLrvsssjMzKzk6ACAqm7ffffd5r2GDRtGo0aNIjMzM9q1axfdunWLrKysOPzwwyMjI+N77bdy5cp4+umnY/r06TF37txYuXJlbNiwIerXrx/NmjWLDh06xL777hs9evSIvn37RrNmzcoU+4MPPhh9+vT5XjEBAFD9SCYEoMrKzs6Oo446KiIi2rdvH6+//nqKIwIAgM0V4JYvXx7Lly+Pr7/+OmbOnBkRETVr1ozDDjsshg8fHgMGDEhxlLvGJZdcEv/+978jIuLGG2+Mk046KcURpZ/DDz88pkyZEpMnT45333035s2bF4sWLYo1a9ZEfn5+ZGZmRpMmTWK//faLvn37xpAhQ6Jx48Y7vc+rr74a77zzTkybNi1mzZoVCxYsiOXLl8f69eujXr16sccee0SHDh2id+/eccwxx8R+++1XCY9218rMzIxp06bF1KlTY8aMGTF79uxYuHBh0h/mmzRpEp06dYo+ffrE4MGDo2PHjqkOGwCoBvLy8iIvLy9ycnLiiy++iKlTp0ZERIMGDWLIkCFx9tlnR5cuXcq0VlFRUdx///1x++23x/r160vcX7duXaxbty4WLFgQb7/9dkRE1KhRI2644YY4+eSTK+5BAQCwW5BMCAAAALAd3bt3jx49eiT6hYWFsWbNmlizZk18/vnniaOACwsLY8qUKTFlypQ44YQT4sorr1SdjF2iWbNmMXTo0Bg6dGil7VG7du3o27dv9O3bt9L2qIrq1q0bAwcOjIEDB6Y6FACgGhs0aFBSxeZNmzbF6tWrIzc3Nz755JPIzc2NiIjvvvsunnzyyXjmmWdixIgR8ctf/jJq1qy53bWvuOKKGD9+fKJfs2bN2H///aNTp07RqFGj+O6772Lp0qUxZ86cWLNmTURsTkDc0gYAgOIkEwKkmGp7AABQtQ0YMCDOP//8bd7PycmJp59+Oh566KFYsmRJREQ8/fTT8fnnn8fDDz8cDRo02FWhViivVQAAoGKceeaZ2z0q+PPPP4/HHnssnnzyycjLy4v8/PwYM2ZMZGdnx7XXXrvNeU8//XRSIuFxxx0XI0eOjDZt2pQYW1RUFB999FG89NJLieriAACwte2/lQUAAACA7WrZsmX86le/ihdeeCEGDx6cuD579uwYNWpUCiMDAACqg86dO8cVV1wREyZMiK5duyauP/bYY/HPf/5zm/PuvffeRHvo0KExZsyYUhMJIzYfbdyzZ88YNWpUTJ48Oem1CwAAbCGZEAAAAKACNGrUKG677bY48sgjE9defvnlmD59egqjAgAAqosf/OAH8eCDD0bbtm0T12677bZSjyReunRpfPbZZ4n+OeecU+Z96tatu82kQwAA0ptkQoAUGzhwYOy7776x7777RnZ2don7w4cPT9zf8kfI3NzcuOeee+Lkk0+OPn36RI8ePeKoo46Kyy67LObNm7fDPS+55JLEmk899VRizXvvvTdOOeWUOPTQQxNrXn755fHxxx/vcM077rgjseYdd9yxw/HTp09PjB8+fHjSvaeeeir23XffOOqooxLXFi5cmBi/9QcAAFQVNWrUiNGjR0ejRo0S18aNG7fDefPnz49bb701TjnllOjXr18ccMABceihh8app54a//u//xtLly7d5tzrr78+8dz4qquuKnOsEyZMSMw76aSTStzf3muVLfeKH4926aWXlvp8fXuvDxYtWhT/+7//G8OGDUs87n79+sWwYcPi9ttvj8WLF5f58QAAwPe1YMGC6NWrV+I57N///vcdzrnqqqsS4wcOHFhqwt/30bRp07jhhhsS/TVr1pRanXDr1wgdOnSokP0BAEhvkgkBqpn33nsvjj/++Ljlllvi448/jtzc3NiwYUNkZ2fHk08+GUOHDo3HH398p9b84IMP4vjjj48xY8bErFmzYuXKlYk1x48fH6eeemrceuutlfSIAABg99KkSZOk5Ly33347cnNzSx27cePGuPrqq+O4446Lv/71rzFr1qxYvnx55Ofnx8qVK+Ojjz6Ku+++O4455phtHm92/PHHJ9ovvfRSbNy4sUxxPvPMM6WusauMGzcuBg8eHHfffXd8+OGHice9fPny+PDDD+Ouu+6KY489Nu65555dHhsAAOllzz33THpjzi233BKffPLJNsdPnDgx/vWvf0VERM2aNePmm2+OzMzMCovnsMMOS3oj/YsvvrjDOaUVKwAAgJ1VO9UBAFB2n332Wdxyyy2Rl5cXzZs3j0MOOSSaNGkSS5cujWnTpsX69eujoKAgrr766ujSpUscdNBBO1xz0aJFMXr06Fi1alU0bNgw+vTpEy1atIhly5bF9OnTIy8vLwoLC+Ovf/1rbNq0KS6++OJKf5z77LNPnHHGGbFu3bqYMGFCRGw+Mm7o0KGVvjcAAFSEwYMHx0MPPRQREUVFRfHuu+/GoEGDksbk5eXFL3/5y5g5c2biWocOHeKAAw6IPfbYI1atWhXvv/9+LF26NNavXx/XX399rF27Nn77298mrdOzZ8/Ya6+94quvvopVq1bF5MmTS+y1tZycnJg2bVpERNSqVSt+8pOf7NTjGzp0aOTm5sbbb78dX3zxRURE9O3bN/bee+8SY3v06FHi2nXXXRcPP/xwor/ltUjLli0jJycn8Vpkw4YNccstt8SyZcvisssu26kYAQBgZwwdOjSmTJkSzz33XOTn58dFF10UTz31VNSvXz9p3NKlS+Pyyy9P9H/zm9/EIYccUuHxHHvssTF37tyIiJg3b16sWrUq9thjj8T9PffcM2rUqBFFRUUREXHffffFjTfeWOFxAACQXiQTAlQjN910UxQUFMQll1wSw4cPj9q1/+/H+OLFi+Occ86JefPmRWFhYYwdOzYefPDBHa45bty4yM/Pj5/+9KdxzTXXJL17cs2aNXH11VfH888/HxERf/vb3+KII46IQw89tOIfXDE9e/aMnj17RnZ2diKZsEmTJjt1ZBsAAKRSVlZW1K5dOzZt2hQRER999FGJBL9rr702kUjYsWPHuPbaa6Nfv35JYwoKCuJf//pX3HjjjbFx48a4/fbbo0+fPiXeOHTccccljhN+5plndphM+Pzzz0dBQUFEbE4CbNmy5U49vgsuuCAiIi655JJEMuHxxx9f6nHJW3vhhReSEgmHDh0aV155ZWRkZCSurV27Nq699tpE9cQHHnggDj744Dj22GN3Kk4AANgZ11xzTbz//vuxcOHCmD9/ftx4441x7bXXJu4XFRXFJZdckqg83rNnzzjvvPMqJZaePXsm7Ttr1qw4/PDDE9eaNm0aP/zhD2PGjBkREfHUU0/FqlWr4swzz4wf/vCHUatWrUqJCwCA3ZtjjgGqkS1HoJ199tlJiYQREW3bto1bbrklatSoERERM2bMiG+//XaHa+bn58eAAQPiL3/5S4ljGDIzM2PMmDFJv6AYM2ZMBTwSAADYvTVo0CBat26d6C9btizp/rvvvpt440ybNm3ikUceKZFIGLG5auB///d/xzXXXBMRm5ML77rrrhLjih9T/J///CfWrl273fiKH3F83HHH7fDxVJTCwsK45ZZbEv1jjz02Ro8enZRIGBGRkZERN998cxx11FGJa2PGjInCwsJdFisAAOknMzMz/vKXvyQS8R577LF47bXXEvf/9re/xVtvvRURm6trjxkzpsTv6itKp06dkvpbv6aIiPjjH/8YderUSfRfe+21+PnPfx69e/eOs846K8aMGRMvv/xyqXMBAKA0kgkBqpGuXbvGaaedtt373bt3j4jN71ScPXv2DtesUaNGXHHFFVGzZun/JdSsWTOuuOKKRJLirFmz4tNPP/0e0QMAQHop/mad1atXJ937+9//nmj/4Q9/2GFlwJNOOilxhPDUqVNjxYoVSfc7duwYBx54YEREbNiwIV5++eVtrvXFF18kXis0aNAgjj766B0/mAoyderUyM7OjoiIOnXqJL3W2FqNGjXi6quvTvxx9Jtvvok333xzl8UKAEB6Ovjgg+O3v/1ton/55ZfHt99+G7Nnz47bbrstcf3KK6+Mjh07VlocW7/5f+vXFBERPXr0iLvuuiuaNGmSdH3t2rXx9ttvx7333hsXXHBBHHbYYXHcccfFPffcE2vWrKm0mAEAqP4kEwJUI4MHD97hmP333z/RXrhw4Q7H9+rVa4e/8OjUqVPiD5MREdOmTdvhugAAkO4aNmyYaK9bty7R3rRpU6KaSe3atct0dG+NGjWiT58+EbH5jUPvv/9+iTHFqxM+++yz21yreFXCo446Kho1arTD/StK8dcSRxxxRLRq1Wq741u3bp1UKX369OmVFhsAAGzxP//zP3HQQQdFRMTKlSvj4osvjosuuijy8/MjIuLHP/5xnHTSSZUaQ/HXExHJrymKGzBgQLz88svxu9/9Ltq0abPN9ebNmxe33HJLDBo0KF544YUKjRUAgN1H5dTdBqBS7Lvvvjsc07Rp00S7LO8w7NmzZ5n2PuiggxJ/sPzkk0/KNAcAANJZ8T/2FT/Gd+7cuZGXlxcREXXr1o2bb765TOvNmjUr0V6yZEmJ+0OGDIkbb7wx8vPzY/r06bF06dKko5a3eO655xLt4gmIu0Lx1xK9evUq05xevXrFpEmTIiJizpw5lRIXAAAUV6tWrfjLX/4SQ4cOTVT526Jt27Zx3XXXVXoMWycPFn9NsbUmTZrE73//+xgxYkTMmTMn3nnnnZg1a1bMmTMnvvzyyygqKkqMzc3NjQsvvDDy8vLilFNOqbT4AQConiQTAlQj2/tlwRa1a//fj/ZNmzbtcHy7du3KtHfxdzRufaQaAABQ0tq1axPtPfbYI9H+9ttvE+28vLx4+OGHd3rtVatWlbjWtGnTOPzww2PSpElRWFgYzz//fPziF79IGjNz5sxYsGBBREQ0b948DjvssJ3euzyKv5Yo62uRDh06JNorV66s8JgAAKA0e+65Z1x99dXxxz/+MXGtZs2acfPNN0fjxo0rff+tiwUUf02xLTVq1IisrKzIyspKXFu5cmW88cYb8eCDD8bs2bMT16+77rro379/qW9AAgAgfTnmGKAaqVGjRoWvWb9+/TKN29YRbQAAQEl5eXlJ1QNbtGiRaJelgviOFBQUlHp9R0cdFz/ieMiQIUlvRtoVtlRkjCh5bNu2NGjQINH2WgQAgF2pefPmSf3WrVtHjx49dsneX3zxRVK/ZcuW32udpk2bxtChQ2P8+PFx1llnJa5v2LAh/vWvf5UnRAAAdkMqEwKkufXr15dpXPE/+jVq1Kjc+xYWFpZ7DQAAqKo+/vjjpIS/Aw88MNEunkS3//77x4QJEyps36OOOioyMjJi7dq1MWfOnJg/f37ss88+ERGRn58fL730UmLsrj7iOCL5sRd/jbE93333XaJdEa9FAACgLFauXBmjRo1KurZ48eK48cYb49prr630/T/66KNEu2bNmtG9e/dyrVezZs0YNWpUTJ48OZGo+O6775ZrTQAAdj8qEwKkuUWLFpVp3OLFixPtpk2blri/s8crFz/yDQAAdjcvvvhiol2zZs3o1atXol+8usmCBQsq9I029erVi2OOOSbRL16JcMqUKYljgvfaa69dVlGluGbNmiXaxV9jbM/ChQsT7dJeiwAAQGW4/PLLIycnJyI2P3+uWXPzn1Ufe+yxeP311yt9/+JvBNpvv/0iIyOj3GvWrFkzDjvssER/y+MDAIAtJBMCpLkPPvhgp8d169atxP3iFUJyc3N3uN7cuXN3OKYyjnUGAIDKtmLFiqRqg4cffng0btw40d9///2jbt26EbH5TTbvv/9+he6/9VHHRUVFiXZpY8pjZ5+z77///ol2WR/3zJkzE+3SXosAAEBFe+yxx+K1116LiIgGDRrEuHHj4pxzzkncL55oWBmmTJkSn332WaI/ZMiQClu7Xr16ifaW1yUAALCFZEKANPf+++/HN998s90xX375ZVIy4aGHHlpiTIcOHRLtTz/9dIf7Fn9X5bYU/6VGfn7+DscDAECqFRUVxSWXXJJ0hO9vf/vbpDH169dPek79wAMPVGgMffr0idatW0fE5qp+M2fOjLVr1yZVT6moZMLif3wsS4Xy4o/7jTfeiOXLl293fE5OTkyZMqXU+QAAUBm++OKLGD16dKJ/6aWXRqdOneL8889PVPdesWJFXHLJJYk37lSklStXxpVXXpno77HHHvFf//VfFbZ+8d/ft23btsLWBQBg9yCZECDNFRUVxZ/+9KdtHq1WWFgYf/rTnxK/FDnggANiv/32KzGue/fuiaokH374YcyfP3+bez788MNJ76rclsaNGyeOjlixYoWEQgAAqrR169bFhRdeGG+88Ubi2nHHHRcHH3xwibG//vWvE+2XX345nnrqqTLvs6MKKDVr1oyf/OQnif4zzzwTr776aqxfvz4iIg466KDYc889y7zf9jRp0iTRXrp06Q7HH3744Yk3Im3cuDH+/Oc/b3PsltcqW14HdOzYMfr161e+gAEAYDvy8/Nj5MiR8d1330VExFFHHRWnnXZaRETUrl07xowZEw0bNoyIiKlTp1b4G4O+/vrr+PnPfx6LFy9OXBs5cmSpRxxnZ2fH2LFjy3RS0BbTpk2Lt956K9Hv379/ueIFAGD3I5kQIM3VqVMn3njjjbj44otjzZo1SffWrFkTf/zjH2Pq1KmJaxdddFGp67Rs2TL69OkTEZv/6PeHP/whlixZkjRm06ZNcf/998cNN9xQpuMT6tatG3vttVdi7quvvrozDw0AAHaJnJyc+Nvf/hY/+clP4sUXX0xc79mzZ9xwww2lzundu3eceOKJif5ll10WN910U6xcubLU8Rs3boyJEyfG//zP/8Tvfve7HcZ0wgknJNovvfRSUrJiRVUljIjYd999E+2JEyfGxo0btzu+Zs2aSa8pnnvuubjiiiti3bp1SePWrl0bl112WVJF85EjRybebAQAAJVh7NixMXv27IjY/DvvP/3pT0n3f/CDH8Tll1+e6N9yyy0xd+7ccu87f/78+NOf/hRDhw5NWu/MM8+MYcOGlTpnw4YNMW7cuDjyyCPj8ssvjxkzZmyzWvj69evj4Ycfjt/97neJwgKtW7eOoUOHljt2AAB2L7VTHQAAqfXb3/42HnzwwXj22Wfjtddei0MPPTRatGgRy5Yti2nTpiUdz3b22WdvtxLIH/7whzj99NOjsLAwPv300zj22GOjb9++0apVq8jNzY133303li9fHg0bNoyLLroorr/++h3Gd8wxx8S4ceMiIuLiiy+OCRMmRMeOHaNOnTqJMaNGjSrHZwAAALbvjTfeSEryKywsjLVr18aaNWvi888/j+zs7BJzTj755Lj88sujXr1621z3uuuui5ycnJg6dWoUFRXF/fffHw899FB07949OnbsGPXq1Yu1a9fGN998E/PmzYsNGzZERERWVtYOY95vv/2ia9euMW/evMjNzY0ZM2ZExOY3E/34xz/e2U/BNh1xxBHRoEGD+O677+LTTz+NIUOGRO/evaNx48aJyuWHHXZYHH744Yk5Q4YMiXfffTcefvjhiIh44okn4oUXXog+ffpEixYtYvny5TFt2rSkBMOf//znceyxx1ZY3AAAsLW33347/v73v0dERI0aNWL06NHRrFmzEuNOOeWUmDx5crz88suxcePGGDlyZIwfP367z/0ffPDBePnllxP9TZs2xZo1ayI3NzfmzJlTorpgvXr14g9/+EP8/Oc/32HceXl5MX78+Bg/fnzUr18/unXrFm3atInMzMzIz8+PhQsXxqxZs5J+19+wYcO45ZZbolGjRjtc/4orrkhUYyyLe+65J1q3bl3m8QAAVC2SCQHSXLt27eKvf/1rXHDBBfHtt9/G66+/XmJMzZo14+yzz44//vGP212rZ8+ecf3118dVV10VBQUFsX79+pg0aVLSmJYtW8Ztt90WBQUFZYrv17/+dUycODE+//zzyM/PTzoybgvJhAAAVKZZs2bFrFmzdjiuZs2a0b9///j5z38ehx122A7H161bN+65556488474+9//3t89913kZ+fHzNnzoyZM2eWOqdOnTpx4IEHlinu4447Lm655Zaka/3794+mTZuWaX5ZZGRkxGWXXRZXX311FBYWxoIFC2LBggVJYxo2bJiUTBgRcdVVV0WLFi3i//2//xcbN26MdevWlfpapF69evE///M/8Zvf/KbCYgYAgK3l5ubGqFGjElX7hg8fXuI5bHHXX399fPjhh7FkyZKYN29e/OUvf4krrrhim+MnTpxYpjgaNmwYQ4YMiV/84hexzz77bHds06ZN44gjjoi333478vPzI2JzBcJtvZbY4sADD4xrr7029ttvvzLF9M0335Rp3BZbYgEAoHqSTAhAHHTQQfH000/H448/Hq+88kosXLgw8vLyEkcX//d//3d07969TGudcsopceCBB8bf//73mDZtWuTk5ES9evWiQ4cOccwxx8Rpp50WzZo1i+nTp5dpvYyMjHjiiSfi0UcfjUmTJsX8+fNjzZo1fiEBAEDK1KlTJzIyMiIzMzOaN28e3bp1iwMOOCD69u0bbdu23am1atWqFSNGjIjhw4fHhAkT4q233or58+fHypUrY9OmTdGoUaNo3759dO3aNfr06RMDBgwotTpKaY4//vgYO3Zs4g+iW65VtGHDhkWXLl3iscceiw8++CC+/fbb+O6776KoqGi7884999w44YQT4oknnoipU6dGdnZ2rFmzJjIzM2PPPfeMww8/PE499dRo165dhccMAADFXXXVVbF06dKIiOjatesO31i/xx57xE033RRnn312FBYWxkMPPRT9+/ePAQMGlGm/+vXrR2ZmZuL5flZWVnTv3j369esXGRkZZVqjWbNmce+998batWtjxowZ8d5778Wnn34aX3/9daxYsSLWr18f9erVi8zMzNhrr70iKysrjj322DK/OQkAgPRUo2hHv9kFYLdzySWXxL///e+IiLjxxhvjpJNOSnFEAAAAAAAAAACkUs1UBwAAAAAAAAAAAACklmRCAAAAAAAAAAAASHOSCQEAAAAAAAAAACDNSSYEAAAA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nJzIycmJN998M+666664/PLL45RTTtnm/C+//DLR7tChww7369ChQyxevDgiIr744oto1qxZudYqbW51iK06kUwIAAAAAAAAAABQiieffDLuvPPOcq1x3nnnxfnnn19BEe28GjVqRLdu3aJPnz6x9957R2ZmZuTl5cW8efPixRdfjCVLlkReXl5cfvnlsWLFijjnnHNKXWfNmjWJdtOmTXe4b5MmTUqdGxGxevXq771W8bnVIbbqRDIhAAAAAAAAAADAbqhTp07x4osvRqdOnUq9f9FFF8Wtt94a999/f0RE3HrrrdG7d+848MADS4zNy8tLtOvVq7fDvYuPWbdu3TbXqlu37g7Xql+//jbXquqxVSc1Ux0AAAAAAAAAAACwGygs3P0+qrlWrVptM5EwIqJOnToxatSoOOmkkyIioqioKO6+++5dFV5EbK6cWFVV5dgqg8qEAAAAAAAAAAAApTj55JOjb9++5VqjXbt2FRRN5fn9738f//73v6OoqCjefvvtWL9+fVLFvYiIhg0bxqpVqyIiYsOGDVG79vZTzzZs2JBoN2rUqMRapY3blvXr129zraoeW3UimRAAAAAAAAAAACi3oqKCVIdQ4dq1a1ctkgHLq3Xr1vGDH/wgvvrqq9i4cWNkZ2dH586dk8ZkZmYmEvZWrly5w8S53NzcpLnFNW7cONFeuXLlDuMrvlbxudUhturEMccAAAAAAAAAAABprmnTpon26tWrS9wvflxydnb2DtcrPmbvvfeusLVKO7a5KsdWnUgmBAAAAAAAAAAAyq+ocPf7SCPFq/CVVmGva9euifasWbO2u9ayZcti8eLFERHRvHnzaNasWdL9ffbZJ2rW3Jy6NmfOnCgo2H5Vy+L7denSpVrFVp1IJgQAAAAAAAAAAEhjS5Ysia+//joiIurWrRvt27cvMaZ///6J9uTJk7e73htvvJFoDxgwoMT9jIyM6NWrV0RErFu3Lt57771trlVYWBhTp05N9I844ohqFVt1IpkQAAAAAAAAAAAgjf3v//5vFBUVRUREnz59okGDBiXG9O7dO1q2bBkRETNmzIjZs2eXulZBQUE89NBDif6QIUNKHVf8+v3337/N2CZOnJg4SvjAAw+MDh06VKvYqpNdlkw4ceLEuOCCC+LII4+M7t27R9++feO0006Le++9N9asWbOrwgAAAAAAAAAAACpDYeHu91GNff3113HvvffG2rVrtzkmPz8/brrppnjqqacS184999xSx9aqVSvp3qhRo2L58uUlxo0ZMyY++eSTiIjo1atXUtXA4k455ZRo165dRERMmjQpHn744RJjvvrqq7juuusS/REjRlS72KqT2pW9wdq1a2PkyJExadKkpOsrVqyIFStWxAcffBD//Oc/Y+zYsYnykAAAAAAAAAAAAOlqwYIFMX78+KRrc+fOTbTnzJkTY8eOTbqflZUVxxxzTKKfl5cXY8aMidtvvz0OPfTQ6N69e3To0CEaNWoUeXl5MW/evHjxxRdj8eLFiTkXXnjhdnO4hg0bFhMnTow333wzPvvsszjhhBPi1FNPjc6dO0dubm48//zziWOBMzMzk5LttlavXr244YYb4pxzzon8/Py47rrrYsqUKTFw4MBo0KBBzJkzJ5544olEobphw4ZFv379qmVs1UWlJhNu2rQpLrjggnjzzTcjIqJFixaJL9CqVaviueeei5kzZ8aSJUviN7/5TTzyyCPRpUuXygwJAAAAAAAAAACoDEXVu5JfVbJo0aIYN27cNu/PnTs3KbkwIuLEE09MSibcYuPGjTF58uSYPHnyNtfLyMiISy+9NE455ZTtxlW7du24/fbbE8XlcnJy4u677y4xrk2bNjF27Ngd5oL169cvxo4dG5dddlmsXr06Jk2aVKJoXcTmZL1rrrmm2sZWXVRqMuHjjz+eSCTs3LlzPPDAA9GiRYvE/TPOOCNuuummuP/++2P16tVx1VVXxaOPPlqZIQEAAAAAAAAAAOz29tlnn7jvvvviww8/jA8//DAWLlwYubm5sXr16qhTp040bdo09ttvvzjssMPihBNOiIyMjDKtm5GREePGjYuJEyfG008/HbNmzYrly5dHo0aNomPHjnH00UfH6aefHpmZmWVa7+ijj46ePXvGo48+GpMmTYqFCxfGhg0bomXLlnHwwQfHKaecEr179672sVUHlZZMWFBQkJTZefPNNyclEm4xcuTIePvtt+OTTz6JmTNnxpQpU7Z5FjUAAAAAAAAAAMDurk+fPiUqD+6sunXrRv/+/SstF2vQoEExaNCgClmrVatWMWLEiBgxYkSFrFeVY6vKalbWwjNmzIicnJyIiOjdu3dkZWWVOq5WrVoxfPjwRP/555+vrJAAAAAAAAAAAIDKUliw+31A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AAAAAAAAAABADRqtMmFdtG/fvnQ8f/78JowEAAAAAAAAAACoj6LKhNCiNVplwtr65JNP8tZbb5U+79q1a9MFAwAAAAAAAAAAABWoyRcTPvDAA5k9e3aSZNttt80666zTxBEBAAAAAAAAAABAZWnSbY5nzJiRCy64oPT5f//3fzdhNAAAAAAAAAAAQH0Vi00dAVCOJqtM+Mknn2TIkCGZMWNGkqRv377p169fU4UDAAAAAAAAAAAAFatJKhNWVVXll7/8ZcaOHZsk2WijjXLuuec2RSgAAAAAAAAAAEADqCoWmjoEoAwrvTJhsVjM6aefnj//+c9Jkq5du+b6669P586dV3YoAAAAAAAAAAAAQFZyZcJisZgzzjgjd955Z5Jk/fXXz4033phu3bqtzDAAAAAAAAAAAACavUceeST3339/XnzxxUybNi0dOnTIRhttlL59++bggw9Ox44dmzpEPkdW2mLCYrGYX//617n99tuTJOutt15uuummbLTRRisrBAAAAAAAAAAAoJEUbXPcYObMmZMTTzwxjz766BKPz5gxIzNmzMjzzz+foUOH5pJLLsmOO+7YRFHyebNSFhNWLyS87bbbkiTrrrtubrrppmy88cYrY3gAAAAAAAAAAIAWYcGCBTnuuOPyxBNPJEm6dOmSQYMGZfPNN8/MmTPzwAMP5Lnnnsu7776bY445Jrfeemu22GKLJo6az4NGX0z42YWE66yzTm666aZssskmjT00AAAAAAAAAACwklSpTNgg7rzzztJCws033zw33nhjunTpUjr//e9/P+eff36uu+66zJo1K6eddlppbRaUo1VjD3DmmWcutZBw0003bexhAQAAAAAAAAAAWpSFCxfmj3/8Y+nz3/72t0ssJKx24oknZuutt06SPPfccxk9evRKi5HPr0ZdTHjWWWfl1ltvTbJoIeGNN96Y7t27N+aQAAAAAAAAAABAEyh+Dj9WtqeffjpTp05Nkuyyyy7Zdttta2zXunXrDB48uPT5X/7yl5USH59vjbbN8SWXXJKhQ4cmSQqFQg477LBMmDAhEyZMWO5122yzTbp27dpYYQEAAAAAAAAAADRLi1cY3GuvvZbbtk+fPqXjxx57rNFionI02mLC5557rnRcLBZz0UUX1eq68847LwMGDGissAAAAAAAAAAAAJql1157rXTco0eP5bbt0qVL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Bx8sHR922GHL3CJ4u+22y84775wkef/99/PMM8+0qNiaI4sJAQAAAAAAAACAshU/hx+s2GOPPVY63nPPPVMoFJbZtmfPnmnXrl2SZOzYsZk7d+5SbUaPHl067tOnz3LH3muvvWqMoyXE1hxZTAgAAAAAAAAAAFChnn322QwcODA777xztttuu+y+++75/ve/n8suuyzvvffeCq9/7bXXSsc9evRYbts2bdpkm222SZJUVVXljTfeWOL8tGnTMmPGjCRJ165ds/baay+3v8XHe/3111tUbM1Rm6YOAAAAAAAAAAAAoDmaPHlyJk+eXFYfXbt2TdeuXRsooob39ttvL/H5tGnTMm3atIwdOzZXXXVVjj322BxzzDHLrOo3YcKE0nG3bt1WOF63bt0yduzY0rXbb799WX3VdG1LiK05spgQAAAAAAAAAAAoW9XncGPg4cOH5/LLLy+rj2OPPTZDhgxpoIga1mabbZbddtstm2++eTp37pz58+fnzTffzMMPP5wJEybk008/zSWXXJLJkyfnzDPPrLGP2bNnl47XXHPNFY65xhpr1HhtksyaNatOfS3eZvFrW0JszZHFhAAAAAAAAAAAABVkjTXWyN13351tt922xvPHH398brzxxvzmN79JsVjMHXfckd69e+eb3/zmUm0/+uij0vGqq666wrFXW2210vHcuXOX2dcqq6yywr4WH++zfTX32JojiwkBAAAAAAAAAICyVTV1AJ8jgwcPztNPP90gfZ133nkZMGDAEo916NBhmQsJk6RQKOSII47InDlzctlllyVJ/vCHP9S4mPCz1zWU2vRVl/Gac2zNhcWEAAAAAAAAAAAANTjwwAOz6667ltVH165dGyiale/oo4/O9ddfnzlz5mT8+PF55513suGGGy7Rpl27dqXjjz/+eIV9Lt6mffv2y+xr/vz5ZfXV3GNrjiwmBAAAAAAAAAAAylZs6gAaQdeuXZtkMeB+++2XHXbYoUH62nLLLet97aqrrpovfelLefzxx5Mkb7755lKLCTt27Fg6/uCDD1bY54cffljjtUnSqVOnOvW1eJvFr20JsTVHFhMCAAAAAAAAAAA0IwcddFBTh1CyxhprlI5nzZq11PlNN900Y8aMSZJMmjQpvXr1Wm5/kyZNWuLaz/ZVU7v69NXcY2uOWjV1AAAAAAAAAAAAADRPK6qwt3jlwxdffHG5fS1YsCAvv/xykqRVq1bZfPPNlzjfpUuXrLXWWkmSyZMnZ/r06cvtb/HxtthiixYVW3NkMSEAAAAAAAAAAFC2qs/hR6X7+OOP8/zzz5c+r6nC3l577VU6Hj16dIrFZW94PXbs2Hz00UdJkp49e6Zdu3ZLtdlzzz1Lx4899thy41v8fJ8+fVpUbM2RxYQAAAAAAAAAAAAs5eqrr87cuXOTJN27d89GG220VJsNN9wwPXr0SLJoa98RI0Yss78bbrihdNy/f/8a2yz++I033piFCxfW2G7cuHF55plnkiTrrbdeevbs2aJia44adTHhv//979xyyy35+c9/ngMPPDD77LNPvvzlL2e77bbLbrvtlsGDB+fyyy/P5MmTGzMMAAAAAAAAAACgkVUVPn8fn0dz587NJZdcstxteovFYm644Yb84Q9/KD32k5/8ZJnthwwZUjo+88wzM3HixKXaDB06NI8++miSpFu3bhkwYECNffXp0yc77LBDkuSVV17JRRddtFSbadOm5eSTT15i/Fatal4K15xja27aNGbnhx9+eKn042dNnz4906dPz9NPP52rrroqxx57bI455pjGDAcAAAAAAAAAAKCiLVy4MFdeeWWuvvrq7LTTTvnSl76UjTbaKB07dszHH3+cCRMm5OGHH86bb75Zuua73/1u9ttvv2X22adPnwwYMCB33313pk6dmgMPPDCDBg3KNttsk3nz5mXkyJGlxXpt27bNOeeck1VWWWWZ/Z111lk55JBDMmfOnFx77bV5/vnn079//6yxxhoZP3587rrrrkydOjXJoq2Hl7X4r7nH1tw06mLCJFl77bWz/fbbZ/PNN0+XLl2yzjrrpFgs5j//+U9GjRqV5557Lp988kkuvvjifPrppzn22GMbOyQAAAAAAAAAAICKtnDhwjz99NN5+umnl9lmlVVWyZAhQ3LUUUetsL+zzjorhUIhw4cPz+zZs3Pdddct1aZz584599xz07t37+X2tdVWW+Wqq67KCSeckPfeey/PPvtsnn322aXa7bPPPrnwwgvTunXrFhtbc9KoiwnvuOOObLHFFikUaq75ecwxx+Tee+/Nz3/+8xSLxVxxxRUZNGhQ1ltvvcYMCwAAAAAAAAAAaGBVKTZ1CNRChw4dctNNN+WFF17ICy+8kLfffjsffPBBPvzww7Rp0yadO3fO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AAAAQIWzzTEAAAAAAAAAAFC2YtE2x9CSqUwIAAAAAAAAAAAAFU5lQgAAAAAAAAAAoGxVUZkQWjKVCQEAAAAAAAAAAKDCqUwIAAAAAAAAAACUrVhUmRBaMosJAQAAAAAAAAAAKsycOXPy0ksv5aWXXsq4cePy0ksvZeLEiaVFoTfddFN69epVq75+/vOf55577qn12LXte/bs2bn99tvzyCOP5O23386cOXPSpUuX9OjRIwcccEC++tWv1nrMJBkzZkyGDx+eZ599NlOnTs1qq62WDTbYIPvss08OOuigrLvuurXuqznHVl8WEwIAAAAAAAAAAFSQ2bNnZ+edd27W1STHjh2bE044Ie+9994Sj0+ePDmTJ0/O3/72t+yzzz656KKL0q5du+X2tWDBgpx++ukZNmzYEo/Pnz8/M2fOzMsvv5ybb7455557bvr27duiYyuHxYQAAAAAAAAAAEDZqprxwjSWVCwWl1hIWCgUstFGG+XDDz/MzJkzy+r7zDPPzNprr73cNltsscVyz7/66qs55phjMmfOnCTJTjvtlP79+6dz584ZP3587rrrrkybNi0jR47Mcccdl6uuuiqtW7deZn+nnnpq7r777iRJx44dM3DgwGyzzTaZN29eRo4cmVGjRmXmzJn56U9/mmuuuSa9e/dukbGVy2JCAAAAAAAAAACACtK6dev0798/2267bemjY8eOGTx4cJ5++umy+t59993TrVu3svo49dRTS4v1fvCDH+Tkk09e4vyhhx6aww8/POPHj8/o0aMzfPjwfPe7362xr3/84x+lxXrrrLNOhg4dmk022aR0/qCDDsrNN9+cs88+O59++mlOOeWUPPTQQ1lllVVaXGzlatUovQIAAAAAAAAAABWlutrd5+nj86p9+/a5+OKL88Mf/jC9e/dOx44dmzqkklGjRuWFF15Ikmy99dY58cQTl2rTpUuXnH/++aXPL7vsslRVVdXY3+9///vS8WmnnbbEYr1qgwcPzle+8pUkyaRJk0oL/FpSbA3BYkIAAAAAAAAAAACahQcffLB0fNhhhy1zi+DtttsuO++8c5Lk/fffzzPPPLNUm3feeSfjxo1LknTr1i39+vVb5rhHHHFE6fgvf/lLi4utIVhMCAAAAAAAAAAAQLMwevTo0nGfPn2W23avvfYqHT/22GNLnV/8sT333DOFQmGZffXs2TPt2rVLkowdOzZz585tUbE1hDaN0isAAAAAAAAAAFBRqvL53RaY2jvttNMyYcKETJs2Lausskq6dOmS7bffPvvuu2+++tWvLnfR3LRp0zJjxowkSdeuXbP22msvd6wePXqUjl9//fWlzr/22ms1tq1JmzZtss0222Ts2LGpqqrKG2+8ke23375FxNZQLCYEAAAAAAAAAACoweTJkzN58uSy+ujatWu6du3aQBE1f0888UTp+JNPPsmcOXPy1ltv5f7778/WW2+diy++ON27d6/x2gkTJpSOu3XrtsKxFm+z+LXl9Dd27NjStYsv2GvOsTUUiwkBAAAAAAAAAICyFYufv8qEw4cPz+WXX15WH8cee2yGDBnSQBE1X+3atUvv3r2z/fbbZ4MNNkjbtm0zffr0jB07No888kg+/fTTvPLKKzn44INz2223ZbPNNluqj1mzZpWO11xzzRWOuXibxa+tNnv27Dr1t8Yaa9R4bXOPraFYTAgAAAAAAAAAAEC9ff/738+pp56a9u3bL3Xu0EMPzTvvvJPjjjsuL7/8cmbOnJn/+Z//yf33359WrVot0fajjz4qHa+yyiorHHfVVVctHc+dO3ep84v3t3jbZVlttdWW2V9zjq2hWEwIAAAAAAAAAACUrepzWJmwqQwePDhPP/10g/R13nnnZcCAAQ3S17L06NFjuec33HDDXHvttdlvv/0yffr0vP766/nb3/6Wb3zjG8u8plAorHDc2rSpT9uG6KupYiuHxYQAAAAAAAAAAAA1OPDAA7PrrruW1UfXrl0bKJqWba211sphhx2WSy65JEkyatSopRYTtmvXrnQ8f/78Ffb58ccfl45rqoq4eH+Lt61Pf805toZiMSEAAAAAAAAAAEANunbt2iSLAffbb7/ssMMODdLXlltu2SD9NIRevXqVjt94442lznfq1Kl0/MEHH6ywv8XbLH5ttY4dO9apvw8//LDGa5t7bA3FYkIAAAAAAAAAAKBsxdjmuKEcdNBBTR1Co1hzzTVLx7Nnz17q/Kabblo6njRp0gr7W7zN4tcu/tiYMWNKbRdfzFjX/ppzbA2lVaP0CgAAAAAAAAAAAIuZMWNG6bim6npdunTJWmutlSSZPHlypk+fvtz+XnzxxdLxFltssdT5xasyLt62JgsWLMjLL7+cJGnVqlU233zzFhNbQ7GYEAAAAAAAAAAAKFtVsfi5+6BhVVfiS5ZdXW/PPfcsHT/22GPL7W/x83369Fnq/F577VU6Hj16dIrL+Z6OHTs2H330UZKkZ8+eadeuXYuKrSFYTAgAAAAAAAAAAECjmj59em666abS51/5yldqbNe/f//S8Y033piFCxfW2G7cuHF55plnkiTrrbdeevbsuVSbDTfcMD169EiyaJvgESNGLDO+G264ocYYWkpsDcFiQgAAAAAAAAAAAOrlnnvuyWOPPbbcynrvvPNOjjrqqNI2x5tttln23XffGtv26dMnO+ywQ5LklVdeyUUXXbRUm2nTpuXkk08ufT5kyJC0alXzUrghQ4aUjs8888xMnDhxqTZDhw7No48+miTp1q1bBgwY0OJiawhtGq1nAAAAAAAAAACgYixvMRnNz8MPP5yXXnppiccmTZpUOh42bFiefPLJJc4PHDgwG2644RKPvfzyy7npppuy7rrrZo899shWW22VtddeO23atMmMGTMyduzYjBgxIp9++mmSpHPnzrn00kvTunXrZcZ21lln5ZBDDsmcOXNy7bXX5vnnn0///v2zxhprZPz48bnrrrsyderUJIu2Hl7eArs+ffpkwIABufvuuzN16tQceOCBGTRoULbZZpvMmzcvI0eOLC3Wa9u2bc4555ysssoqLTK2cllMCAAAAAAAAAAAUGFGjhyZe+65Z5nn77///qUe22233ZZaTFjt/fffz913373cMXv06JHzzz8/m2222XLbbbXVVrnqqqtywgkn5L333suzzz6bZ599dql2++yzTy688MLlLkxMFi0ALBQKGT58eGbPnp3rrrtuqTadO3fOueeem969e7fY2MplMSEAAAAAAAAAAFC2YlQmrERHHXVUtttuu7zwwgt5+eWXM23atHz44YeZN29eOnTokPXWWy877LBDvv71r2e33XZLoVCoVb89e/bMAw88kDvuuCMjRozIxIkTM3fu3HTp0iU9evTIAQcckL59+9aqrzZt2uTcc8/NAQcckGHDhuW5557L1KlTs+qqq2aDDTbIPvvsk4MPPjjrrrtui4+tHBYTAgAAAAAAAAAAVJjf/OY3+c1vflN2P+utt14OOOCAHHDAAQ0Q1ZI6deqUo48+OkcffXSD9NerV6/06tWrQfpqzrHVl8WEAAAAAAAAAABA2YpFlQmhJWvV1AEAAAAAAAAAAAAATctiQgAAAAAAAAAAAKhwtjkGAAAAAAAAAADKZptjaNlUJgQAAAAAAAAAAIAKpzIhAAAAAAAAAABQNnUJoWVTmRAAAAAAAAAAAAAqXKFos3IAAAAAAAAAAKBMbVbZoKlDaHALPvlPU4cAK43FhAAAAAAAAAAAAFDhbHMMAAAAAAAAAAAAFc5iQgAAAAAAAAAAAKhwFhMCAAAAAAAAAABAhbOYEAAAAAAAAAAAACqcxYQAAAAAAAAAAABQ4SwmBAAAAAAAAAAAgApnMSEAAAAAAAAAAABUOIsJAQAAAAAAAAAAoMJZTAgAAAAAAAAAAAAVzmJCAAAAAAAAAAAAqHAWEwIAAAAAAAAAAECFs5gQAAAAAAAAAAAAKpzFhAAAAAAAAAAAAFDhLCYEAAAAAAAAAACACmcxIQAAAAAAAAAAAFQ4iwkBAAAAAAAAAACgwllMCAAAAAAAAAAAABXOYkIAAAAAAAAAAACocBYTAgAAAAAAAAAAQIWzmBAAAAAAAAAAAAAqnMWEAAAAAAAAAAAAUOEsJgQAAAAAAAAAAIAKZzEhAAAAAAAAAAAAVDiLCQEAAAAAAAAAAKDCWUwIAAAAAAAAAAAAFc5iQgAAAAAAAAAAAKhwFhMCAAAAAAAAAABAhbOYEAAAAAAAAAAAACqcxYQAAAAAAAAAAABQ4do0dQDwefXXv/41DzzwQAqFQi677LKmDocK8f7772f27NmZM2dOCoVCOnfunLXXXjsdOnRo6tAAAFocOT1NRV4PANBw5PU0BTk9AAAtlcWE9fDBBx9kwoQJmT17dubOnZskad++fTp27JhNN900a665ZhNHSHMwYcKEPPLIIykUCk0dykr30Ucf5bnnnsvEiRMzd+7cdOjQIZtuuml22mmnrLLKKk0d3ko1bdq0jBs3Lh999FHWWGONbLvttuncuXOD9T9p0qQ8+OCDGTVqVF577bXSa9LiCoVCNtlkk/Ts2TODBg1Kjx49Gmx8AGip5PTUhpxeTl9NXg8AzZO8ntqQ18vrEzk9AADUlsWEtfTEE0/kgQceyOjRozN9+vTltl177bWz1157pX///tl9991XUoQrx/z58zNx4sR8/PHH2WCDDbL22mvX+topU6ZkzJgxSZJvf/vb9Rp/6tSpGT16dKZNm5Z11lknffr0yVprrbVEm1dffTVXXXVVnn766cyaNStrrbVWdtxxxxxyyCHp2bNnvcZtScaNG5dRo0bljTfeyKxZs9KpU6dsuumm2XvvvbP99tvXu99isVh689uuXbu0arX0Lulz5szJ7373uwwbNizz589f6nz79u1z2GGH5Uc/+lG9Jiq++tWvZuONN86BBx6Yfv36Ndlkx/Tp03PNNdfkmWeeyUcffZQtttgiP/jBD7LDDjuU2sycOTNnnXVWHnrooVRVVZUeb9WqVfbee++cfPLJ2Wijjeodw+zZs3PRRRdl2LBhWbhwYZJF36OaFIvFTJgwIRMmTMhdd92VXr165eyzz063bt3qPT40hBkzZuT9999Pknzxi19s4miASiCnX0RO3zI0Rl7fHHL6RF6/OHk9LZ2cHmgK8vpF5PXNn7n6xienh4YhrwcAFlcoLiujJUnyxhtv5LTTTstzzz1XemxFT9nid7fttNNO+fWvf53NNtus0WKsrREjRmTkyJEpFAo599xz63TtjBkzctFFF+XBBx/Mxx9/XHp82223zX//93/nq1/96gr7eOSRR3LsscemVatWefnll+sc/x//+Mf88Y9/LL0ZS5LVVlstZ511Vvbbb78kyeOPP54f//jH+fTTT5Ms+l4t/v045phj8tOf/rRO415++eV1jjVJxo4dm6eeeiqFQiE/+clPljp/7LHH1rqvyZMnJ1k0+bXqqqvW2Gb69On55S9/mccee2yZ/eyxxx4599xzs84669R67Gp/+9vf8tOf/jStWrXKP/7xj3Tp0mWJ8++++24OP/zwvP3228v9HSkUCtluu+1y3XXXpWPHjnWK4Ytf/GLp+9mpU6fsv//+GThw4Ep9Y/P666/n8MMPzwcffLDE461atcpFF12Ur3/965k/f34GDx6cF198scbnolAopFOnTrnxxhvrFft7772XH/7wh3njjTeW2X+y6OdllVVWyfvvv58FCxYscX711VfPZZdd1qCTqJMnT85jjz2W119/PRMmTMisWbOWuCO8erJsiy22yF577ZWuXbs22NjlmjNnTmbNmpUkzSquxvLmm28uNYnbvXv3lR7HFVdckd///vcpFAr1+rtQX5988kneeeedzJ49Ox07dky3bt2W+dra0N5///3cdttt+ec//5mJEydmzpw5pWoJffr0yUEHHVTvO6LvvffebLjhhtlpp50aOOr6mTlzZp5//vnMnTs3W265ZTbffPOl2rzxxhu55ZZb8sILL5TuCt9+++1zwAEHZJtttmmwWD755JM8++yzefXVV/Pmm29m1qxZmTNnTlq1apVOnTplnXXWSY8ePbLTTjtlvfXWa7BxaT7k9IvI6euuIXP6pOnz+uaQ0yfy+mry+oZXSXl9pef0ibx+ZZDT09zI6xeR19edufqamauX08vpm16l5/Vy+pVDXg9AXVlMuBz/+te/8qMf/SizZs1a4k3AF77whXTr1i1rrLFGKaGZP39+Pvzww0yaNClTpkxZop9OnTrl6quvXuJOqKbwu9/9LldeeWUKhUJeeeWVWl83ZcqUHHbYYZk0adJSb4aq3wj169cv55xzznLfcFZPUNR1/CT505/+lIsvvjiFQmGpGNq2bZubb745X/jCF/Ktb30rM2fOXGY/hUIhZ5xxRg466KBaj734m+K6qo61puvr8hx88YtfTKtWrXLZZZfVOBk0derUHHzwwZk8efIKJwc22GCD3HbbbXWepDjrrLNyyy23ZIcddsgdd9yxxLmqqqoMHDiw9AajUChkhx12yHbbbZcOHTpk9uzZeemll/L888+Xzu+5557505/+VKcYqr8Xn31et9122wwaNCj9+/dPhw4d6tRnXSxYsCD7779/JkyYUOP59u3b58EHH8x1112XG2+8Mcmi3/8vf/nL6dixYyZPnpx///vfpcmCTTfdNPfff3/atm1b6xiKxWK+973vlZ7LjTbaKPvvv3+6d++eYrGYt956K3/+858zceLEtGvXLpdffnl23nnnvPLKK3nsscdy9913lya8Vl999dxwww1lvzb985//zKWXXpoXXnihTtd96Utfyv/8z/+kd+/eZY3fEH73u9/lqquuKuuN8jvvvJP77rsvr732Wj7++ON07do1e++9d/bee+9aXf/EE0/ktNNOS6FQyCOPPFLn8WfMmJE//OEPefTRRzNt2rR06dIl3/jGN/KTn/wk7dq1S5LMmzcvp5xySh566KGlru/du3fOOuuslXoX7BVXXJFLL720Xn8X6uPf//53/vjHP+af//xnPvnkk9Ljq6yySnr37p0f//jH9f59mDhxYm699dYkydFHH73UJG6S3HrrrTn//POXGPuzE+nt27fPueeem6997Wt1jqH6NXLjjTfOoEGD8u1vf7tOVQka0qWXXpprrrlmicnRPffcMxdeeGE6deqUJLn77rtz+umnL9GmWqFQyPe///388pe/LGsLosmTJ+cPf/hDHn744cyZM2eF7QuFQvbaa68cddRRFVEhoVLI6ReR0zd9Tl8dR1Pm9c0hp0/k9Ym8vrGUm9fL6etuZef0ibx+ZZHT09zI6xeR1zd9Xt/UOX3SPPJ6Ob2cvrGYq6+MvF5Ov/LI6wGoD4sJl2HOnDnZb7/98u677yZJtt566wwePDh9+vRZ4R/76dOnZ9SoURk6dGgp4eratWvuv//+Rn3ztCL1naA49NBDM3bs2NLn3bt3T/v27fPWW29l9uzZSRb9Qd9oo41yww035Atf+EKN/dR3gmLKlCnZd999S3cw7r333tliiy0yceLEjBgxIsViMb17907v3r1zySWXZJ111snPfvaz9OnTJ+3bt8/EiRNz22235bbbbkuxWEynTp0ycuTIWn8vPvumuCHU9TmojuHyyy+vcYLiiCOOyFNPPZVkUaL97W9/O7169cqaa66ZGTNmZMyYMbnvvvvyySef1Hty4MADD8zLL7+co446Kj/72c+WOHf//ffnpJNOSqFQyOabb54LLrigxrv4XnnllZx00kl5/fXXUygU8qc//Sl77rlnnZ+HTp06LTERVZ28rrbaavn617+eAw88sFESy89+nT/72c+yySab5K233soll1yS1157LT/60Y9yyy23ZPbs2TnkkEPyv//7v1lttdVKfUycODE//elP88orr6RQKOT888/Pt771rVrH8MADD+TEE09MoVDIgQcemDPOOCNt2iy5Y/3ChQtzxhln5K677soaa6yRBx54oPRm6ZNPPskf/vCHXHXVVUmSLbbYIvfdd1+NW2GsSLFYzOmnn5677rqr9HldVH/fvvvd7+aMM84o601Iuer7+ljt+uuvzyWXXFJ6nVrc1ltvnbPOOivbbrvtcvsoZxL37bffzve///1MmzYtyZJvenfYYYfcfPPNadu2bY4//vj89a9/Xeb36gtf+EJuvfXWZb6ON7SGmqD4xS9+kSQ57LDDsvXWW9fY5uqrr84ll1ySYrG43LuEjz/++PzXf/1XnWO47rrr8tvf/jZrrrlmnnzyyaV+nm+66aacd955SWpXNeF3v/td9t133zrF8NkJ9datW+crX/lKBg4cmL322mul/Y5dfPHFNf6NWfzvz1NPPZWjjjoqCxcuXObzUSgU8oMf/CD/+7//W6847rjjjpx33nmZP3/+EmNUPw/LGzdJDj744PziF79osm16aBhy+v9HTt/0Of3icTRVXt8ccvrFnwd5vby+oZWT18vp66ch/9NRXr9Ic8jr5fQ0N/L6/0de3/R5fVPn9EnzyOvl9HL6xmKufpGWmtfL6RdpDjl9Iq8HoP7arLhJZbr99tvz7rvvplAo5Mgjj8yJJ55Y6wR+7bXXzoEHHpjvfOc7ueCCC3L99ddnypQpufPOO/ODH/ygkSNvWKNHj87YsWNTKBSyySab5JJLLim98fzkk0/ywAMP5MILL8yMGTMyceLEHHroobnxxhsb9G6Zu+++u/TG+rzzzsu3v/3t0rnqhH7MmDGZOHFiOnTokFtvvTUbbrhhqc0WW2yR0047Leuvv34uvvjizJ49O3/9618zcODAOsXRrl27HHTQQWnfvn2t2j/zzDMZM2ZMCoWat05oKGPGjClt0bDBBhvkmmuuySabbLJEm/322y9HHnlkjj766PznP//J6NGj8+9//zvbb799rceZOnVqkmT99ddf6lz1nVOdO3fODTfcsMxJvK233jrXX399+vfvn1mzZuXee++t8388Jsm5556btdZaK3feeWf++te/Zt68eUkW3cl177335t57780mm2xSuttnrbXWqvMYNRkxYkSSRXcj3XTTTVlzzTWTJJtsskl22GGH9OvXr3R3T58+fXLqqacu1cfGG2+cq6++Ot/85jcze/bsPPLII3WaoPjLX/6SJNl8881z1lln1fiGo3Xr1vn1r3+d559/PuPHj8/NN9+c448/PsmiCazjjz8+7du3z8UXX5zx48fnr3/9a775zW/W+fk4/fTTc+edd5Y+32CDDbLnnnumR48epTvCqydnPv7449Id4S+++GIef/zxTJo0KUlKffz617+ucwzNwS233JLzzz9/mROZL7/8cg4++OD8/Oc/z/e///0GH79YLOb4448v/Y4u/niSvPDCC7n88svz5S9/ufS7uvHGG2ePPfYoTTaPHj068+bNy5QpU3Laaafl6quvrlMMy5oUqMvX8Nk+6nLn6T333JNCoZC+ffvWGMvw4cNz0UUXlb5H1XcEVk/iLr7lS/VE93e+8506fQ1jxoxJkhonAiZNmpTf/va3pTH69euXgw8+ONtuu206duyYWbNm5aWXXsptt92Wv//97ykWi/nlL3+ZXXbZpfQ6UxfV4yxYsCCPPPJIHnnkkay77roZMGBABgwYsMTfyIb25ptv5tprry0919tuu2022WSTTJw4MePGjcvo0aMzatSoXHnllVmwYEE6d+6cH/zgB9ltt93SqVOnTJ48Offdd1/uvffeFIvFXH/99Rk4cGA23XTTOsVxyy235Oyzz06y6PlYZZVV0rVr1xSLxUyZMqWUV3Tr1i0//OEPM3Xq1Pz73//O2LFjS39Tbr/99kyZMiWXX375UhPBtBxy+kXk9P9Pc83pk5WT1zennD6R1yfy+uZCTt/0OX0ir/+spsrr5fQ0R/L6ReT1/09zzevN1cvpP0tOv3LJ65s+r5fTL8lcvbweoKXyarsM1WWrd9xxx5x00kn16qNVq1Y5+eST8+9//zvPPvtsHn744RY3QfHAAw8kWfTm/LrrrlviDphVVlklAwYMyN57750hQ4bk2WefzX/+858cdthhufHGGxssAaq+i2/HHXdcYnIiSfr27Zvdd989TzzxRKZMmZJjjz12meMeddRRueOOOzJ58uQ8/vjjtZ6gOOCAA3Lfffdl3rx5+etf/5ozzjgjffr0WeF1V1xxRSlhPfbYY2s1Vn1Uf4+qt1b47OREte7du+eyyy7LwIEDUywW8+c//7lOExQffPBBktQ4+fDSSy+lUChk0KBBK7wbuEuXLhk0aFCuueaa/Otf/6r1+J/15S9/OV/+8pdz6qmn5i9/+UuGDRuWF154oZSYv/XWW7ngggty8cUXZ5999smBBx5Y9t0+1Xcofvvb317qTcOaa66Z73znO7n55ptLE5vL0qVLl3zrW9/K0KFD61ym///+7/9SKBTyrW99a7lfS6tWrXLAAQfkwgsvzN///vfSBEW1o446Kvfcc0/eeuutjBgxos4TFM8880zuvPPOFAqFrL322jn99NPTt2/fFT6/vXr1yoEHHphisZgRI0bkzDPPzLRp03LnnXdm//33b3GlyqdOnZoLL7wwyaI3Qf369cs3vvGNtG/fPq+99lqGDRuWiRMn5tNPP83ZZ5+dDz74oMFfD/7+97+Xfgd79OiRM844I5tvvnkmTpyYM888M88880yGDx+eiRMnJln0vT/hhBOWmHSfPHlyjjnmmLz++ut5/PHH8+KLL6ZHjx61jqEh7gZvrELJM2fOzDnnnFMaY8CAAfmf//mfrLfeeqU27733Xn73u9/lnnvuSbFYLG1dUNsJ6WTRa06hUEj37t2XOjd06NAsWLAghUIhp5xySg499NAlzq+55prZY489sscee2To0KE5++yz89FHH+W2227Lj3/84zp/zd/73vfy9ttv55///GeqqqqSJO+//36uvPLKXHXVVdlll13y3e9+N3379m3wO/mGDx+ehQsXplBYtFXRwQcfXDp311135dRTT83ll1+ecePGpXPnzrnjjjuW+Lu18cYbZ9ddd82XvvSlnHHGGSkWixk2bFid7nh85513csEFF6RYLKZz58456aSTsv/++5e+1ur/YDn//PMzadKk0vYvSfLRRx/l3nvvzWWXXZYPPvgg//jHP3LxxRfXOxek6cnpF5HTN/+cPlk5eX1zy+kTeb28vunJ6VP62svVmJufyOtXXl4vp6c5ktcvIq9v/nm9uXo5fU3k9CuHvD6lr71c5upbfk6fyOsBKI/FhMvw9ttvp1AopH///mX31b9//zz77LN5++2363xtdTnohlCfstT//ve/S2+GllVKe6211soNN9yQX/ziF3nggQcyefLkHHbYYbnpppsaZJLizTffTKFQWOakwB577JEnnngiSWrcVqBaq1at8tWvfjU33XRTXn311VqPf/7556d///45/fTTM2XKlPzoRz/KN7/5zZxyyikNdhddOf71r3+VylGv6I6jbbbZJnvttVdGjRqV559/vk7jdOjQIR9++GHmzJmz1LkPP/wwSWrcLqEm1XHOmDGjTjHUpF27dhk0aFAGDRqU8ePH56677sr9999fmlBZsGBBRowYkREjRmS99dYr3e1Tnztyp0+fnmTRHbQ1WfzxFZXJ32677Zbos64x1OZ3q/pr/M9//rPUuVatWuXrX/96rrjiirz00kt1iiFZ9CYkWfRzccstt2TjjTeu0/WFQiFf+9rXsuWWW2bQoEGZM2dOhg0bVqcJismTJ9dpzOWp6ee6NoYPH5558+alUCjkhBNOyNFHH10616dPnxx55JG54oorcsUVV6Sqqip/+MMfsmDBgvz0pz9toMiTv/3tb0mSTp065eqrr07nzp2TLPp5vPLKK7Pvvvtm+vTp+dvf/pbevXvnxBNPXKqPrl275ve//33233//LFy4MA8++GCdJiiSNPgWMw1l2LBh+eijj5Zbhn+99dbLeeedlzXWWCPXX3995syZk/vuuy+HHHJIrcep/t1cfOKj2j//+c8UCoXsuuuuS01OfNahhx6akSNH5sknn8xjjz1WrwmKPfbYI1/96lczefLkDBs2LPfee2/p96VYLGbMmDEZM2ZMOnXqlG9961sZOHBgttpqqzqPU5PqrZZ22GGHJSYnkmTQoEG555578txzz6VQKOTHP/7xMifVDz744DzwwAMZO3bsEts31cadd96Zjz/+OG3bts0NN9yw1N/G6v9g2WabbTJo0KA8/PDDeeSRR9K3b9+0a9cuhxxySPr165cjjzwy48ePz0033ZSDDjqozq9zNA9y+kXk9M0/p09WTl7fXHP6RF6/PPL62qtPXi+n/3+aa06fyOtXZl4vp6c5ktcvIq9v/nm9uXo5/bLI6WvPXP3nN6+X05url9cDtBwWEy5DdbK6xhprlN1XdR9z586t87XV5aCbyvvvv59kUaKxPG3bts0FF1yQ1VdfPXfddVemTJmSwYMH56abbspGG21UVgyzZs1KkmW+oVy8lP+yEp1q1W8g6/qmcK+99sqf//zn/Pa3v81dd92VBx98MI8//nh+8YtfLHUH5spW/T3q3bt3rdrvuuuuGTVqVI1vWpdn/fXXz4cffljj3XkdO3bMjBkzsmDBglr1Vd2uoUtRb7755vnFL36RE088MY888kiGDx+eJ598snS3z3vvvZcrrrgiV155ZXr16pVBgwalX79+adu2ba36//TTT5MselNek8XvjFp99dWX21f1lgLVfdbWaqutlk8//bRWrycralP9+zJt2rQ6xZCktKXKwIEDy0raN9lkkwwcODDXX399nn322Tpdu88++zTp62OSPPnkk0mS7bfffonJiWpt2rTJkCFD0qNHj/zsZz/L3Llzc9VVV6WqqionnHBCg8Qwbty4FAqFfOMb3yhNTlRr3759vvnNb+amm25KoVBY7pvjTTfdNHvssUdGjRqVF198sU4xtG3bNgsWLEi7du3y05/+NIcddlitrrviiity6aWXplAo1GsSvTaqv0frr7/+Cp/zn/3sZ/nrX/+ad999N08++WSdJiiqX9dqej2pnhzo27dvrfrq169fnnzyyUyYMKHW49eka9euOe644zJkyJA8/vjjGTZsWEaOHFl63Zk5c2aGDh2aoUOHZrvttsugQYPSv3//Ot3l+VnVd30u62vdZ5998txzzyVZ/n8qJIuer7Fjx9b5P3gee+yxFAqF7L///suduP/iF7+Y/fffP3fffXeGDRu2RMzrrLNOfv/73+eAAw7IggULct999+W4446rUxw0D3L6ReT0izTnnD5ZOXl9S8jpE3n9Z8nrG5ecfpHmnNMn8vqVmdfL6WmO5PWLyOsXac55vbn6/0dOvyQ5feOT1y/SnPN6Ob25+mWR1wM0P61W3KQydenSJUkyfvz4svuq7mNFJeWXp1gsNshHXc2fPz9Jsuqqq66wbaFQyFlnnZWDDjooSfLuu+9m8ODBpXLd9bWiN7GLJ4PVb/qWpVOnTkkWlUauqw4dOuTMM8/M9ddfnw022CAzZ87ML37xi/zwhz/MpEmT6txfQ6n+Wmq6w6Ym6667bpJk9uzZdRpn1113TbFYzMMPP5x58+YtcW7LLbdMklLSuSLVb0RrG3NdtW3bNt/4xjdyzTXX5O9//3uOPfbYdO3atfR7UFVVlaeeeio/+9nPstdee9W63+qJiSlTptR4/t133y0dL6vNZ9sua7JjWarvOq7elmN5qttUf88/q7qMeH1eG6onNVZ0V2dtVPcxderUOl/bUK+N9b1L74033kihUMi+++673HZ77713brjhhnTu3DnFYjFXX311acuFclU/b8v6Xix+F/KXvvSl5fZVfbfpW2+9VacY7r333uywww756KOPct555+Xggw9ukL+fDeG1115LoVDI17/+9bRu3Xq5bdu0aZOvf/3rKRaL+b//+786jVP9N76m3/1PPvkkSWp9h3z11iz1+VtVk+o74i+99NI89thjOfnkk0sT9tU//+PGjcvpp5+ePfbYI7/85S/rPGFYrXpidFkVEhZ/fFltqlX/B0Rd/15Vv77uvPPOK2xb3WbcuHFLnevevXv69u2bYrGY0aNH1ykGmg85/SJy+v+nueb0ycrJ61tSTp/I66vJ6xv3NVJOv0hzzukTeX2y8vJ6OT3Nkbx+EXn9/9Nc83pz9UuT02eJNnJ6c/XVKjGvl9Obq18eeT1A86Iy4TJst912mTx5cu68884ceuih9S6RP2PGjNx5550pFAqlUul1sdpqq2X+/PnZZJNNcswxx9QrhmoPP/xwHn300Tpd07Fjx3z44Yd1KnH/61//OoVCIbfffnvee++90l2P9bXmmmtmypQp9boj67Oq7/Ao506O3r1754EHHsiFF16YW2+9NU8++WT233//HHfccTniiCNW+t1Xa621VqZOnVq6o29FqttVvzmtrf333z/XX399pk+fnvPOOy9nnnlm6dx3vvOd/POf/8y9996b73//+6UJi5q8+uqruffee1MoFLLbbrvVKYb6+MIXvpBjjz02xx57bJ544okMGzYsf//730tvGKq3faiN7t2757nnnsujjz6ao446aqnzi/9+jRw5crl3fP39739PUrstEBa3yy675NVXX82DDz6Y733ve/nyl79cY7vnn38+Dz74YAqFQnbcccca21S/sa2ekK2LVVddNfPnz19qsqo+qvuozUToZxUKhay66qplb2Mye/bsOr8JShbdLZYsuqtsRXr06JEbb7wxRx55ZD744INce+21qaqqykknnVTncRf38ccfJ8lSdzpW69ixY+l4Rc9T9RvCum4lsdlmm+W2227LjTfemEsvvTTPP/98vvOd7+Soo47Kf//3f9f59aYhVX+Pars1QHW76u1XamvLLbfMf/7znzz++ONLvT6sv/76efvtt1c4cVmtul1jbM+z5ppr5sgjj8yRRx6ZF154IXfeeWceeuih0mTIvHnzcs899+See+7JpptumkGDBuXII4+sdf9t27bNwoULl3m39eKPz5s3b7mTtNU/27W9I71a9deyov+0WLxN9c/JZ+2888556KGHav29o/mR0y8ip19ac8vpk5WT17fUnD6R18vra6c+eb2cfpHmnNMn8vrPasy8Xk5PcySvX0Rev7Tmltebq18+Ob2cvjbM1S/yeczr5fRLMle/JHk9QPOiMuEyfOtb30qyqMT+4YcfXue7HpLklVdeyeGHH156Y12fEvtf/OIXUywW8+GHH+Y73/lOWR+1Tc4WV10Svaa7AJbnjDPOyMEHH5xk0ZugwYMH17sEdHWCtqwJijXWWCPbb799tt9++xX2Vb1lQjl3niaLEppf/epXGTp0aDbeeOPMmzcvv/3tbzNw4MB6/azUVk2TH9tss02SRdsC1Eb1G/Lqu2lqa+utt863v/3tFIvF3HXXXTnhhBNK35Nvfetb2WWXXTJ//vwcfvjh+fOf/7zUhMnChQtz33335Ygjjsgnn3yS1q1bZ+DAgXWKoVy77757Lrnkkjz22GP5+c9/Xrrbp7Z69eqVZNFdncOGDVvi3D333FPaTmDbbbfNH/7wh7zzzjs19jN8+PA888wzy508WJbvfe97KRQKWbhwYX74wx/mpptuKm0vkizaauTmm2/OD3/4w1Ip9wEDBtTYV3V5/GVtS7I8G2ywQZJFEzHlqp6sqe6ztqonBTbccMOMHDmyrI/vf//79Yq9+o1T9RupFfniF7+YG264IWuttVaKxWKuv/76nH/++fUau1r1XdyL/xwsbvHXjVatlv9nv/rrqc/dn4VCIUcccUTuu+++7Lzzzvn0009z5ZVX5tvf/na975xrCNVfU7t27WrVvrpd9SRmbVVvAzBmzJil7vzu06dPisVi/vznP6+wn2KxmPvuuy+FQiGbb755nWKoqx122CHnnHNOnnjiiZx99tmlu2Gr74B8880389vf/rZOfa6zzjpJktdff73G84vfBfvSSy8tt6/q83WdqKn++1abagvV2zIsPpG3uOqxlzWBQfMnp19ETl+zpsrpk6bL6z8POX0ir/8seX15eb2cfslxmmNOn8jrl6eh83o5Pc2RvH4ReX3NzNW3zLxeTr8kOb25+s/6POb1cvplM1cvrwdobiwmXIa+fftm7733TrFYzPjx4/Od73wnhx12WK699to8/fTTmTx5cubNm5eqqqpUVVVl3rx5mTx5cp5++ulce+21OfzwwzNgwIDSH+K99947++yzT53jqL5DcubMmfnPf/7ToF9jbWy77bYpFot56qmn6nxt9SRFsVjMtGnTcskll9Qrhi222CLFYnGZyU7Pnj1z55135o477lhhX6+99lqSZZeSr6sdd9wx999/f37wgx+kVatWeemllzJw4MBceOGFtX7DUhc/+clPsvXWWy/x8Y9//CNJ7SeRqp+D+txFc8opp5R+Jh566KF85StfyXHHHZdbb701hx9+eDbeeON88MEHOemkk9K7d+8MHjw4P/rRj3LooYemd+/e+fnPf54PPvgghUIhRx11VL0mzRrCGmuskSOOOCJ//vOfa/VzU23gwIGlu7ZOPfXUDBo0KP/7v/+b7373u/nlL3+ZQqGQrbbaKieffHJmzpyZgQMH5uqrr87LL7+ct99+O0899VR+9atf5dRTTy31+Z3vfKdOsXfv3j0//OEPUywWM2/evJx33nnp3bt39thjj+yxxx7p3bt3zj333MydO7dULr6m8uGffPJJHnvssRQKhVqVF/+s6tfHUaNG5dZbb63z9dVuvfXWjBo1KoVCIV/5ylfqdO12222XYrGYCRMmlLZ5WdmqX0uWNRlVk6222mqJSYobbrihrEmK6jdjDXFHePVdjuXcZbfRRhvl5ptvzmmnnZZ27drlzTffzODBg3PGGWfU+S7KhlB9R3Ft72atvhtvWXePLsv+++9fmjQ77rjjlpisHjx4cFZfffW88sorOeOMM7Jw4cIa+1i4cGHOOOOM0rVf//rX6xRDfa2++uoZOHBgbr/99vzlL3/JkUceWe+J/Oq/Effee+9Sk2azZs3KPffck0KhkNatW+eGG25YZj8zZszI/fffn0KhkK233rpOMWyzzTalGKonamuyYMGCUjybbbZZjW1WdDcxzZ+cfhE5/fKt7Jw+adq8/vOS0yfy+kRe3xDk9Etrbjl9Iq+vjYbK6+X0NEfy+kXk9ctnrr5l5vVyejl9Q5HXL6255fVy+hUzVy+vB2gubHO8HBdddFGGDBmSJ598MknyzDPP5Jlnnqn19dV3i+y+++656KKL6hXDtttuWzp+6aWX6nw3ULl69eqVW265Je+++27++c9/Ztddd63T9WeccUYKhUJuu+22esew3Xbb5Z577indmVWOJ598MoVCITvssEPZfVVbZZVVctJJJ+Ub3/hGfvnLX+b111/Ptddeu8K7iupjeXcgPfHEE1mwYEHatFn+r/U///nPFAqFfPGLX6zz+B06dMh1112XE044IU888UQ+/fTTjBgxIiNGjCi1KRQKKRaLmTVrVsaOHVtj7EcffXR++tOf1nn8xlCbu2SrbbDBBjn++ONz/vnnp1AoZNy4caWJoWKxmLZt2+a0007LjjvumF69emXMmDG5+OKLc/HFFy/RT7FYTKFQyMCBA+v1fTjhhBMye/bs0uRKsVgs3cm7+PO811575dxzz62xj1deeaW07UJ9Jk+/973vZejQoZk9e3bOOuusPPHEEzniiCPSs2fPFW4fUiwW8+yzz+a6664rbTfRqVOnfO9736tTDNtuu20efvjhLFy4MC+//PIyt5FoTFtssUUmTpy4xM96bWy55Za5/vrrc8QRR+SDDz7IDTfckDFjxtQrhvXXXz9vvvlmJk+eXOP5HXfcMVdffXWt+qq+86shSvYfcsgh+cpXvpJf/epXeeKJJ3LHHXfk0UcfzWmnnVa6M7ChPfjgg3nllVeWeKx6MuCNN96oVR+TJk1Ksmgisy5WXXXVnHbaafnxj3+c6dOnZ9CgQTn44IMzaNCgbLnlljnnnHNy0kkn5Y477sjTTz+dgQMHZtttt02HDh0ye/bsjBs3LsOHD89bb71VesNc1wnMhrDZZpvl5JNPzs9+9rP8/e9/z/Dhw+t0/Te+8Y089NBDmTNnTg477LCccMIJ2WSTTfLWW2/ld7/7XWbPnp3VV189//Vf/5VLL70055xzTk488cQltk6ZNGlSjj/++MycOTOFQiF77713nWLo27dvRo0alYkTJ+akk07Keeedt9TWLJ988kl+8YtflJ7vPn361NjXm2++maR+W8zQfMjp5fS1sTJz+qRp8/rPY06fyOsTeX19yemXrSly+kRe3xDKyevl9DRX8np5fW2Yq2/Zeb2cXk5fDnn9spmrr7ycPpHXA1AeiwmXo3379rn66qtzxx135I9//GOd7yTp0qVLfvKTn+S73/1uWrduXa8Yqu92TBZNUHzta1+rVz/1tfvuu2fVVVfN/Pnzc+2119Z5giJJTj/99LRq1Sq33HJLvWLYfvvts/rqq2fu3LkZP358vUtJjxkzJlOmTEmhUMguu+xSrz6Wp0ePHrn77rvzxz/+MVdfffVy77Coq9rejfbSSy8td/LlX//6V95+++2yJmk6d+6ca6+9NnfffXeuvfbapZL+QqFQmqRY/M1y9V11J5xwQqk8d0t05JFHpm3btrnkkktKd0Uli97QnXnmmaWtEC699NJ873vfW+aWIV/72tdy2mmn1SuGVq1a5de//nX69euXm266KU8//XTpjpy2bdvmS1/6Ug4++OB885vfXOZkwQ477JArr7yyXuMni8qjn3POOTn++OOzcOHC0hYE7du3z9Zbb51u3bplzTXXzKqrrppCoZCPP/44H3zwQSZNmpRXXnml9NwVi8W0adMm55xzTp3fAHz29bEpJih23HHHPPLII3n22Wczbdq0On0NW221VW688cbSJMVn31jX1nbbbZcnnnhimWXo11prrey555616uvFF19MoVBI9+7d6xXLZ33hC1/Itddem+HDh+f888/Pe++9l2OPPTb9+vVb4q7fhvLggw8u89zTTz9dqz6qJ8Pr8x8Ce++9d84666yceuqp+fTTTzN06NAMHTo0a621VjbbbLOsv/76mTRpUt58881ccMEFNfZRLBbTpUuX/O53v1vhhHNjatOmTfbdd9/su+++dbquX79+2WabbfLKK6/k1VdfzTHHHLPE+erJ2YMOOihXXnllhg4dmvvvvz877rhjOnTokClTpuT555/PwoULUygUsv7662e//farUwwHHHBArr766rz99tt56KGH8swzz+Qb3/hGunfvnkKhkDfffDMPPfRQpk6dmmTR37WDDjqoxr6qJ/WrtymiZZLTy+nrojFz+qT55PWVntMn8vpq8no5/Yqs7Jw+kdc3pPrk9XJ6mit5vby+LszVL/J5z+vl9IvI6ReR1y+fufrKyukTeT0A5bGYcAVat26dQw45JAcffHCefvrpjB49Oq+99lomTJiQ2bNnl5Ls9u3bp2PHjtl0002z5ZZbZs8998wuu+xS9h1vm222Wfr165eqqqq0b9++rL4GDhyY3XbbrU7XtG/fPscff3wmTJiQQqGQWbNmpVOnTnUe+9RTT02HDh3y3HPP1fnaHj165F//+ledr/usCRMmlO4cqX4T2dDatm2b//mf/8m+++6be+65Z7l3J9bFzTff3CD9jBs3rnSXUbmTNAMGDMiAAQPy3HPP5Zlnnsm4ceMyderUzJw5s/Tz2rlz53Tv3j1f/OIXs9dee2W99dYra8xjjz02SRrszVN9HXrooRk0aFCee+65TJ8+PWuvvXZ22mmn0rYKyaI7pe65557ccsstGTVqVN5///20b98+W221Vfbbb7/svvvuZcdRvV1CsVjMBx98UBq3sSrofFa/fv3ypz/9Kb/61a9Kd9rNmTMnY8eOXe7df4v/XnTt2jXnnHNOvSY/q+8GLxaLy3xzXlvdunWr1xYS1d/HhQsX5u67785//dd/1en6LbfcsjRJMWPGjDqPnyx6jUySV199NXPmzEmHDh3q1c/MmTNLb+IbehL3wAMPzF577ZXTTjstjz76aEaMGJGnnnqq3hPONVnR6+3LL7+ciRMnZuONN15mmzlz5uSpp55KoVCo053QizvwwAOzySab5Be/+EXp7tHp06eXvr+LTxrWFPPuu++eX//61+nWrVu9xm9qhUIhl112WQ477LAat3zq2bNnTjrppLRt2zZnn312/vd//zezZs3KqFGjSm2qn5fVVlstv/3tb7PaaqvVKYa2bdvm0ksvzWGHHZZZs2Zl2rRpNf4drZ4gveCCC9KxY8elzr/xxhulCatevXrVKQaaHzm9nL4uGiunT5pfXt8UOX0ir/8seX3T5vVy+tpZGTl9Iq9vDuT0NGfyenl9XZirN1dfTU7/+c/pE3l9bZmrr4ycPpHXA1CeQrEh/2cEgIrzySef5K677spDDz2U5557LlVVVctt36pVq+y444755je/mYEDBy4xsVNXr732WmlCbMMNN6x3P+XYd999M3HixKy55poZOXJkVl999Tr3MX78+BxxxBGZNm1aCoVCne58/PDDD3P33XcnSfr371/vicDLL788l19+eQqFQh566KFssskm9epnRf785z/n3HPPzQcffFC6M7quX/Nn1fZOxu7duy/3jtRrrrkmF154YQqFQq655pqyJhIXLFiQv/3tbxk+fHj+9a9/Zd68ectsu+6666ZPnz751re+Va+JsmrVW7H84Q9/aNRt52pj7ty5ufHGG/P4449n+vTp6dKlS/r165dDDjlkid/5YcOG5cILL8yHH364xPVf+tKX8qtf/WqJu5rr6o033sgpp5yS559/vsbzm222WX7961+nZ8+eNZ6fMWNGafJ1s802q9fvNgC0JJWc18vp66YxcvpEXl+tueT1cnoAaHkqOadP5PV1Za5+aZ+3nD6R1wNQPxYTAtBg5s6dmzfeeCNvvvlmZs+enY8++ihJ0q5du3Ts2DHdu3fPZpttVvbd283J7NmzM3/+/CTJmmuuWe+tct57771MnDgxScPfbVgb06ZNK30d9dk2oC5mzJiRX//61/nb3/6WJA3yH48N4e233y79zHbv3r2sybPFLVy4MOPHj8/UqVMza9as0qRap06d0r1796y55poNMk5L9cknn+Rf//pX3n///XTo0CFbbrllg/4M/vvf/85TTz2Vd999N8ViMeuss0569uyZnXfeeZnbywBApau0vF5OX3fNNadP5PVNQU4PAM1PpeX0iby+PpprXi+nbxryegCqWUwIADSJOXPmlMrk11S6HgAAaN7k9AAA0PLJ6wGAxVlMCAAAAAAAAAAAABWuVVMHAAAAAAAAAAAAADStNk0dAACVbcSIERk5cmQKhULOPfdcMYihSWNo6vHFIAYAaKmaw9/Npo6hqccXgxiaWwxNPX5ziQEAWorm8HdTDGJoLuOLQQwAlUxlQgCa1EsvvZR77rkn99xzjxjE0OQxNPX4YhADALRUzeHvZlPH0NTji0EMzS2Gph6/ucQAAC1Fc/i7KQYxNJfxxSAGgEpmMSEA/H/t3TFKa1EUheGTh0UgkxDSCGYE9hlAIHNwDI7K3sYp2ITUKey1TJP7qvf6JBf2Opzvq6zu+ruDsEUAAAAAAAAAgME5JgQAAAAAAAAAAIDBOSYEAAAAAAAAAACAwT1UBwDQn7e3t9m+dTweNWi4q6F6X4MGAOhVwrtZ3VC9r0FDWkP1fkoDAPQi4d3UoCFlX4MGAObhmBCAq72/v7fFYqFBQ0RD9b4GDQDQq4R3s7qhel+DhrSG6v2UBgDoRcK7qUFDyr4GDQDMwzEhADebpqk6QYOGmH0NGgCgVwnvZnVD9b4GDWkN1fspDQDQi4R3U4OGlH0NGgC4j2NCAK62XC7b+Xxuj4+P7fX19a5vfXx8tM/PTw0abm6o3tegAQB6lfBuVjdU72vQkNZQvZ/SAAC9SHg3NWhI2degAYB5OCYE4GpPT0/t6+ur/fz8tN1ud9e3TqfTTb8AaNCQsq9BAwD0KuHdrG6o3tegIa2hej+lAQB6kfBuatCQsq9BAwDz+FMdAEB/NptNa62139/f9v39rUFDaUP1vgYNANCrhHezuqF6X4OGtIbq/ZQGAOhFwrupQUPKvgYNAMzDMSEAV3t+fv7/8+Fw0KChtKF6X4MGAOhVwrtZ3VC9r0FDWkP1fkoDAPQi4d3UoCFlX4MGAObhmBCAq/37a6LW6n4B0KAhZV+DBgDoVcK7Wd1Qva9BQ1pD9X5KAwD0IuHd1KAhZV+DBgDm8VAdAEB/1ut122637XK5tNVqdde39vt9e3l50aDh5obqfQ0aAKBXCe9mdUP1vgYNaQ3V+ykNANCLhHdTg4aUfQ0aAJjHYpqmqToCAAAAAAAAAAAAqOPfHAMAAAAAAAAAAMDgHBMCAAAAAAAAAADA4BwTAgAAAAAAAAAAwOAcEwIAAAAAAAAAAMDgHBMCAAAAAAAAAADA4BwTAgAAAAAAAAAAwOAcEwIAAAAAAAAAAMDgHBMCAAAAAAAAAADA4BwTAgAAAAAAAAAAwOAcEwIAAAAAAAAAAMDgHBMCAAAAAAAAAADA4BwTAgAAAAAAAAAAwOAcEwIAAAAAAAAAAMDgHBMCAAAAAAAAAADA4BwTAgAAAAAAAAAAwOAcEwIAAAAAAAAAAMDgHBMCAAAAAAAAAADA4BwTAgAAAAAAAAAAwOD+AhNs4S4ZOzNDAAAAAElFTkSuQmCC\n",
- "text/plain": [
- "