diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index b18e1e4..532ef37 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -10,7 +10,7 @@ jobs: uses: actions/checkout@v2 - name: Setup latest deno version - uses: denolib/setup-deno@v2 + uses: denoland/setup-deno@main with: deno-version: v1.x @@ -28,7 +28,7 @@ jobs: uses: actions/checkout@v2 - name: Setup latest deno version - uses: denolib/setup-deno@v2 + uses: denoland/setup-deno@main with: deno-version: v1.x diff --git a/Cargo.lock b/Cargo.lock index 7784cff..6bfab53 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -21,12 +21,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3" [[package]] -name = "neo" +name = "neo_rust" version = "0.1.0" dependencies = [ "wee_alloc", ] +[[package]] +name = "neo_wasm" +version = "0.1.0" +dependencies = [ + "neo_rust", + "wee_alloc", +] + [[package]] name = "wee_alloc" version = "0.4.5" diff --git a/Cargo.toml b/Cargo.toml index 08db764..eddca67 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,8 @@ [workspace] members = [ + "backend/rust", "backend/wasm" +# TODO: "backend/native" ] [profile.release] diff --git a/README.md b/README.md index f7535fb..dc523ef 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ [![License](https://img.shields.io/github/license/denosaurs/neo)](https://github.com/denosaurs/neo/blob/main/LICENSE) `neo` is a module for working with matrices and other linear algebra, -accelerated using WebGPU and wasm. +accelerated using WebGPU. ## Maintainers @@ -21,4 +21,4 @@ Pull request, issues and feedback are very welcome. Code style is formatted with ### Licence -Copyright 2021-2022, the denosaurs team. All rights reserved. MIT license. +Copyright 2021, the denosaurs team. All rights reserved. MIT license. diff --git a/backend/rust/Cargo.toml b/backend/rust/Cargo.toml new file mode 100644 index 0000000..eaaba5c --- /dev/null +++ b/backend/rust/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "neo_rust" +license = "MIT" +version = "0.1.0" +authors = ["Elias Sjögreen"] +edition = "2021" + +[lib] +path = "lib.rs" + +[dependencies] +wee_alloc = "0.4.5" diff --git a/backend/rust/binary.rs b/backend/rust/binary.rs new file mode 100644 index 0000000..85975f1 --- /dev/null +++ b/backend/rust/binary.rs @@ -0,0 +1,50 @@ +macro_rules! binary_operator { + ($identifier:ident, $type:ty, $closure:expr) => { + #[no_mangle] + pub unsafe extern "C" fn $identifier( + a_data: *const $type, + b_data: *const $type, + c_data: *mut $type, + len: usize, + ) { + let a_data = &core::slice::from_raw_parts(a_data, len)[..len]; + let b_data = &core::slice::from_raw_parts(b_data, len)[..len]; + let c_data = &mut core::slice::from_raw_parts_mut(c_data, len)[..len]; + + for i in 0..len { + c_data[i] = $closure(a_data[i], b_data[i]); + } + } + }; +} + +binary_operator!(add_f32, f32, |a, b| a + b); +binary_operator!(add_u32, u32, |a, b| core::intrinsics::unchecked_add(a, b)); +binary_operator!(add_i32, i32, |a, b| core::intrinsics::unchecked_add(a, b)); + +binary_operator!(sub_f32, f32, |a, b| a - b); +binary_operator!(sub_u32, u32, |a, b| core::intrinsics::unchecked_sub(a, b)); +binary_operator!(sub_i32, i32, |a, b| core::intrinsics::unchecked_sub(a, b)); + +binary_operator!(mul_f32, f32, |a, b| a * b); +binary_operator!(mul_u32, u32, |a, b| core::intrinsics::unchecked_mul(a, b)); +binary_operator!(mul_i32, i32, |a, b| core::intrinsics::unchecked_mul(a, b)); + +binary_operator!(div_f32, f32, |a, b| a / b); +binary_operator!(div_u32, u32, |a, b| core::intrinsics::unchecked_div(a, b)); +binary_operator!(div_i32, i32, |a, b| core::intrinsics::unchecked_div(a, b)); + +binary_operator!(mod_f32, f32, |a, b| a % b); +binary_operator!(mod_u32, u32, |a, b| core::intrinsics::unchecked_rem(a, b)); +binary_operator!(mod_i32, i32, |a, b| core::intrinsics::unchecked_rem(a, b)); + +binary_operator!(min_f32, f32, |a: f32, b: f32| a.min(b)); +binary_operator!(min_u32, u32, |a: u32, b: u32| a.min(b)); +binary_operator!(min_i32, i32, |a: i32, b: i32| a.min(b)); + +binary_operator!(max_f32, f32, |a: f32, b: f32| a.max(b)); +binary_operator!(max_u32, u32, |a: u32, b: u32| a.max(b)); +binary_operator!(max_i32, i32, |a: i32, b: i32| a.max(b)); + +binary_operator!(prelu_f32, f32, |a, b| if a < 0.0 { a * b } else { a }); +binary_operator!(prelu_i32, i32, |a, b| if a < 0 { a * b } else { a }); diff --git a/backend/rust/lib.rs b/backend/rust/lib.rs new file mode 100644 index 0000000..fc5aeea --- /dev/null +++ b/backend/rust/lib.rs @@ -0,0 +1,5 @@ +#![no_std] +#![feature(core_intrinsics)] + +pub mod binary; +pub mod unary; diff --git a/backend/wasm/matmul.rs b/backend/rust/matmul.rs similarity index 73% rename from backend/wasm/matmul.rs rename to backend/rust/matmul.rs index 0dc3008..bfc27d1 100644 --- a/backend/wasm/matmul.rs +++ b/backend/rust/matmul.rs @@ -1,23 +1,23 @@ macro_rules! matmul_impl { ($identifier:ident, $type:ty) => { #[no_mangle] - pub extern "C" fn $identifier( - m: usize, - n: usize, - k: usize, + pub unsafe extern "C" fn $identifier( a_data: *const $type, b_data: *const $type, c_data: *mut $type, + m: usize, + n: usize, + k: usize, ) { let a_len = m * k; let b_len = k * n; let c_len = m * n; let a_data = - &unsafe { core::slice::from_raw_parts(a_data, a_len) }[..a_len]; + &core::slice::from_raw_parts(a_data, a_len)[..a_len]; let b_data = - &unsafe { core::slice::from_raw_parts(b_data, b_len) }[..b_len]; + &core::slice::from_raw_parts(b_data, b_len)[..b_len]; let c_data = - &mut unsafe { core::slice::from_raw_parts_mut(c_data, c_len) }[..c_len]; + &mut core::slice::from_raw_parts_mut(c_data, c_len)[..c_len]; for l_index in 0..m { for m_index in 0..k { @@ -27,10 +27,10 @@ macro_rules! matmul_impl { l_index * k + m_index, m_index * n + n_index, ); - unsafe { + *c_data.get_unchecked_mut(i) += a_data.get_unchecked(j) * b_data.get_unchecked(k) - }; + ; } } } diff --git a/backend/rust/transpose.rs b/backend/rust/transpose.rs new file mode 100644 index 0000000..3ca7035 --- /dev/null +++ b/backend/rust/transpose.rs @@ -0,0 +1,25 @@ +macro_rules! transpose_operator { + ($identifier:ident, $type:ty) => { + #[no_mangle] + pub unsafe extern "C" fn $identifier( + a_data: *const $type, + b_data: *mut $type, + w: usize, + h: usize, + ) { + let len = w * h; + let a_data = &core::slice::from_raw_parts(a_data, len)[..len]; + let b_data = &mut core::slice::from_raw_parts_mut(b_data, len)[..len]; + + for x in 0..w { + for y in 0..h { + b_data[y + x * h] = a_data[x + y * w]; + } + } + } + }; +} + +transpose_operator!(transpose_f32, f32); +transpose_operator!(transpose_u32, u32); +transpose_operator!(transpose_i32, i32); diff --git a/backend/rust/unary.rs b/backend/rust/unary.rs new file mode 100644 index 0000000..6c86e84 --- /dev/null +++ b/backend/rust/unary.rs @@ -0,0 +1,93 @@ +macro_rules! unary_operator { + ($identifier:ident, $type:ty, $closure:expr) => { + #[no_mangle] + pub unsafe extern "C" fn $identifier( + a_data: *const $type, + b_data: *mut $type, + len: usize, + ) { + let a_data = &core::slice::from_raw_parts(a_data, len)[..len]; + let b_data = &mut core::slice::from_raw_parts_mut(b_data, len)[..len]; + + for i in 0..len { + b_data[i] = $closure(a_data[i]); + } + } + }; +} + +unary_operator!(abs_f32, f32, |a: f32| if a < 0.0 { -a } else { a }); +unary_operator!(abs_i32, i32, |a: i32| if a < 0 { -a } else { a }); + +unary_operator!(linear_f32, f32, |a| a); +unary_operator!(linear_u32, u32, |a| a); +unary_operator!(linear_i32, i32, |a| a); + +unary_operator!(neg_f32, f32, |a: f32| -a); +unary_operator!(neg_i32, i32, |a: i32| -a); + +unary_operator!(inc_f32, f32, |a| a + 1.0); +unary_operator!(inc_u32, u32, |a| a + 1); +unary_operator!(inc_i32, i32, |a| a + 1); + +unary_operator!(dec_f32, f32, |a| a - 1.0); +unary_operator!(dec_u32, u32, |a| a - 1); +unary_operator!(dec_i32, i32, |a| a - 1); + +unary_operator!(relu_f32, f32, |a: f32| a.max(0.0)); +unary_operator!(relu_i32, i32, |a: i32| a.max(0)); + +unary_operator!(relu6_f32, f32, |a: f32| a.clamp(0.0, 6.0)); +unary_operator!(relu6_i32, i32, |a: i32| a.clamp(0, 6)); + +unary_operator!(ceil_f32, f32, |a: f32| core::intrinsics::ceilf32(a)); +unary_operator!(floor_f32, f32, |a: f32| core::intrinsics::floorf32(a)); +unary_operator!(round_f32, f32, |a: f32| core::intrinsics::roundf32(a)); +unary_operator!(sqrt_f32, f32, |a: f32| core::intrinsics::sqrtf32(a)); +unary_operator!(rsqrt_f32, f32, |a: f32| 1.0 / core::intrinsics::sqrtf32(a)); +unary_operator!(sigmoid_f32, f32, |a: f32| 1.0 + / (1.0 + core::intrinsics::expf32(-1.0 * a))); + +unary_operator!(square_f32, f32, |a| a * a); +unary_operator!(square_u32, u32, |a| a * a); +unary_operator!(square_i32, i32, |a| a * a); + +unary_operator!(cos_f32, f32, |a: f32| core::intrinsics::cosf32(a)); +unary_operator!(cosh_f32, f32, |a: f32| { + let e2x = core::intrinsics::expf32(-a); + (e2x + 1.0 / e2x) / 2.0 +}); + +unary_operator!(sin_f32, f32, |a: f32| core::intrinsics::sinf32(a)); +unary_operator!(sinh_f32, f32, |a: f32| { + let e2x = core::intrinsics::expf32(a); + (e2x - 1.0 / e2x) / 2.0 +}); + +unary_operator!(tan_f32, f32, |a: f32| core::intrinsics::sinf32(a) + / core::intrinsics::cosf32(a)); +unary_operator!(tanh_f32, f32, |a: f32| { + let e2x = core::intrinsics::expf32(-2.0 * if a < 0.0 { -a } else { a }); + (if a.is_nan() { + f32::NAN + } else if a.is_sign_negative() { + -1.0 + } else { + 1.0 + }) * (1.0 - e2x) + / (1.0 + e2x) +}); + +unary_operator!(exp_f32, f32, |a: f32| core::intrinsics::expf32(a)); + +unary_operator!(elu_f32, f32, |a: f32| if a >= 0.0 { + a +} else { + core::intrinsics::expf32(a) - 1.0 +}); + +unary_operator!(log_f32, f32, |a: f32| if a < 0.0 { + f32::INFINITY +} else { + core::intrinsics::logf32(a) +}); diff --git a/backend/wasm/Cargo.toml b/backend/wasm/Cargo.toml index f6fdac1..f0a865e 100644 --- a/backend/wasm/Cargo.toml +++ b/backend/wasm/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "neo" +name = "neo_wasm" license = "MIT" version = "0.1.0" authors = ["Elias Sjögreen"] @@ -10,4 +10,5 @@ crate-type = ["cdylib"] path = "lib.rs" [dependencies] +neo_rust = { path = "../rust" } wee_alloc = "0.4.5" diff --git a/backend/wasm/backend.ts b/backend/wasm/backend.ts index 95fb22e..5acbb6c 100644 --- a/backend/wasm/backend.ts +++ b/backend/wasm/backend.ts @@ -1,4 +1,3 @@ -// import { wasm } from "../../util.ts"; import { Backend, BackendRequest, DataType } from "../types.ts"; import { WasmData } from "./data.ts"; @@ -7,7 +6,7 @@ const decoder = new TextDecoder(); export interface WasmBackendRequest extends BackendRequest { func: string; - args: (number | bigint)[]; + args: number[]; data: WasmData[]; } @@ -18,11 +17,9 @@ export class WasmBackend implements Backend { instance!: WebAssembly.Instance; memory!: WebAssembly.Memory; + alloc!: (size: number) => number; - dealloc!: ( - pointer: number, - size: number, - ) => void; + dealloc!: (ptr: number, size: number) => void; async initialize(): Promise { if (this.initalized) { @@ -30,23 +27,20 @@ export class WasmBackend implements Backend { } const { source } = await import("./wasm.js"); - const { instance } = await WebAssembly.instantiate(source, { + const { instance: { exports } } = await WebAssembly.instantiate(source, { env: { - panic: (pointer: number, len: number) => { + panic: (ptr: number, len: number) => { const msg = decoder.decode( - new Uint8Array(memory.buffer, pointer, len), + new Uint8Array(this.memory.buffer, ptr, len), ); throw new Error(msg); }, }, }); - const memory = instance.exports.memory as WebAssembly.Memory; - - this.instance = instance; - this.memory = memory; - this.alloc = instance.exports.alloc as (size: number) => number; - this.dealloc = instance.exports.dealloc as ( - pointer: number, + this.memory = exports.memory as WebAssembly.Memory; + this.alloc = exports.alloc as (size: number) => number; + this.dealloc = exports.dealloc as ( + ptr: number, size: number, ) => void; @@ -55,10 +49,19 @@ export class WasmBackend implements Backend { // deno-lint-ignore require-await async execute(request: WasmBackendRequest): Promise { - // deno-lint-ignore no-explicit-any - (this.instance.exports[request.func] as (...args: any[]) => any)( - ...request.args, - ...request.data.map((data) => data.pointer), - ); + if (!this.initalized) { + throw new Error("WasmBackend is not initialized"); + } + + const func = this.instance + .exports[request.func] as (((...args: unknown[]) => unknown) | undefined); + + if (func === undefined) { + throw new Error(`Could not find wasm function ${request.func}`); + } + + const args = request.data.map((data) => data.ptr).concat(request.args); + + func(...args); } } diff --git a/backend/wasm/binary.rs b/backend/wasm/binary.rs deleted file mode 100644 index f13f99d..0000000 --- a/backend/wasm/binary.rs +++ /dev/null @@ -1,71 +0,0 @@ -macro_rules! binary_impl { - ($identifier:ident, $type:ty, $closure:expr) => { - #[no_mangle] - pub extern "C" fn $identifier( - len: usize, - a_data: *const $type, - b_data: *const $type, - c_data: *mut $type, - ) { - let a_data = &unsafe { core::slice::from_raw_parts(a_data, len) }[..len]; - let b_data = &unsafe { core::slice::from_raw_parts(b_data, len) }[..len]; - let c_data = - &mut unsafe { core::slice::from_raw_parts_mut(c_data, len) }[..len]; - - for i in 0..len { - c_data[i] = $closure(a_data[i], b_data[i]); - } - } - }; -} - -binary_impl!(add_f32, f32, |a, b| a + b); -binary_impl!(add_u32, u32, |a, b| unsafe { - core::intrinsics::unchecked_add(a, b) -}); -binary_impl!(add_i32, i32, |a, b| unsafe { - core::intrinsics::unchecked_add(a, b) -}); - -binary_impl!(sub_f32, f32, |a, b| a - b); -binary_impl!(sub_u32, u32, |a, b| unsafe { - core::intrinsics::unchecked_sub(a, b) -}); -binary_impl!(sub_i32, i32, |a, b| unsafe { - core::intrinsics::unchecked_sub(a, b) -}); - -binary_impl!(mul_f32, f32, |a, b| a * b); -binary_impl!(mul_u32, u32, |a, b| unsafe { - core::intrinsics::unchecked_mul(a, b) -}); -binary_impl!(mul_i32, i32, |a, b| unsafe { - core::intrinsics::unchecked_mul(a, b) -}); - -binary_impl!(div_f32, f32, |a, b| a / b); -binary_impl!(div_u32, u32, |a, b| unsafe { - core::intrinsics::unchecked_div(a, b) -}); -binary_impl!(div_i32, i32, |a, b| unsafe { - core::intrinsics::unchecked_div(a, b) -}); - -binary_impl!(mod_f32, f32, |a, b| a % b); -binary_impl!(mod_u32, u32, |a, b| unsafe { - core::intrinsics::unchecked_rem(a, b) -}); -binary_impl!(mod_i32, i32, |a, b| unsafe { - core::intrinsics::unchecked_rem(a, b) -}); - -binary_impl!(min_f32, f32, |a: f32, b: f32| a.min(b)); -binary_impl!(min_u32, u32, |a: u32, b: u32| a.min(b)); -binary_impl!(min_i32, i32, |a: i32, b: i32| a.min(b)); - -binary_impl!(max_f32, f32, |a: f32, b: f32| a.max(b)); -binary_impl!(max_u32, u32, |a: u32, b: u32| a.max(b)); -binary_impl!(max_i32, i32, |a: i32, b: i32| a.max(b)); - -binary_impl!(prelu_f32, f32, |a, b| if a < 0.0 { a * b } else { a }); -binary_impl!(prelu_i32, i32, |a, b| if a < 0 { a * b } else { a }); diff --git a/backend/wasm/data.ts b/backend/wasm/data.ts index b3de000..80bbb87 100644 --- a/backend/wasm/data.ts +++ b/backend/wasm/data.ts @@ -6,10 +6,11 @@ export class WasmData implements Data { type: T; backend: WasmBackend; + active = true; length: number; size: number; + ptr: number; data: DataArray; - pointer: number; static async from( backend: WasmBackend, @@ -33,30 +34,45 @@ export class WasmData implements Data { type: T, length: number, ) { + const Constructor = + DataArrayConstructor[getType(type)] as DataArrayConstructor; + this.backend = backend; this.type = type; this.length = length; this.size = this.length * - DataArrayConstructor[getType(type)].BYTES_PER_ELEMENT; - this.pointer = this.backend.alloc(this.size); - this.data = new DataArrayConstructor[getType(this.type)]( + Constructor.BYTES_PER_ELEMENT; + + this.ptr = this.backend.alloc(this.size); + this.data = new Constructor( this.backend.memory.buffer, - this.pointer, + this.ptr, this.length, ) as DataArray; } // deno-lint-ignore require-await async set(data: DataArray) { + if (!this.active) { + throw "WasmData is not active"; + } + this.data.set(data); } // deno-lint-ignore require-await async get(): Promise> { + if (!this.active) { + throw "WasmData is not active"; + } + return this.data.slice() as DataArray; } dispose(): void { - this.backend.dealloc(this.pointer, this.size); + if (this.active) { + this.backend.dealloc(this.ptr, this.size); + this.active = false; + } } } diff --git a/backend/wasm/lib.rs b/backend/wasm/lib.rs index 083ca15..aa075b1 100644 --- a/backend/wasm/lib.rs +++ b/backend/wasm/lib.rs @@ -1,22 +1,24 @@ #![no_std] -#![feature(default_alloc_error_handler, core_intrinsics)] +#![feature(default_alloc_error_handler)] extern crate alloc; extern crate wee_alloc; -pub mod binary; -pub mod matmul; -pub mod unary; +pub use neo_rust; +// pub mod matmul; #[global_allocator] static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT; +#[cfg(not(test))] const DEFAULT_PANIC: &str = "Panic occured"; +#[cfg(not(test))] extern "C" { fn panic(ptr: *const u8, len: usize); } +#[cfg(not(test))] #[panic_handler] #[no_mangle] fn panic_handler(panic_info: &core::panic::PanicInfo) -> ! { diff --git a/backend/wasm/mod.ts b/backend/wasm/mod.ts deleted file mode 100644 index 21a7a39..0000000 --- a/backend/wasm/mod.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { source } from "./wasm.js"; - -export const { instance: { exports } } = await WebAssembly.instantiate(source, { - env: { - panic: (ptr: number, len: number) => { - const msg = decoder.decode( - new Uint8Array(memory.buffer, ptr, len), - ); - throw new Error(msg); - }, - }, -}); - -export const memory = exports.memory as WebAssembly.Memory; -export const alloc = exports.alloc as (size: number) => number; -export const dealloc = exports.dealloc as ( - ptr: number, - size: number, -) => void; diff --git a/backend/wasm/operators/binary.ts b/backend/wasm/operators/binary.ts index 78a4f4b..37abf77 100644 --- a/backend/wasm/operators/binary.ts +++ b/backend/wasm/operators/binary.ts @@ -1,9 +1,9 @@ -import { DataPrimitive } from "../../types.ts"; +import { DataType } from "../../types.ts"; import { ensureType } from "../../util.ts"; import { WasmBackend } from "../backend.ts"; import { WasmData } from "../data.ts"; -export function binary(func: string) { +export function binary(func: string) { return async function ( backend: WasmBackend, a: WasmData, @@ -20,11 +20,11 @@ export function binary(func: string) { }; } -export const add = binary("add"); -export const sub = binary("sub"); -export const mul = binary("mul"); -export const div = binary("div"); -export const mod = binary("mod"); -export const min = binary("min"); -export const max = binary("max"); +export const add = binary<"f32" | "u32" | "i32">("add"); +export const sub = binary<"f32" | "u32" | "i32">("sub"); +export const mul = binary<"f32" | "u32" | "i32">("mul"); +export const div = binary<"f32" | "u32" | "i32">("div"); +export const mod = binary<"f32" | "u32" | "i32">("mod"); +export const min = binary<"f32" | "u32" | "i32">("min"); +export const max = binary<"f32" | "u32" | "i32">("max"); export const prelu = binary<"f32" | "i32">("prelu"); diff --git a/backend/wasm/operators/matmul.ts b/backend/wasm/operators/matmul.ts index 410fce2..eec658b 100644 --- a/backend/wasm/operators/matmul.ts +++ b/backend/wasm/operators/matmul.ts @@ -1,13 +1,11 @@ -import { DataPrimitive } from "../../types.ts"; import { ensureType } from "../../util.ts"; import { WasmBackend } from "../backend.ts"; import { WasmData } from "../data.ts"; -export async function matmul( +export async function matmul( backend: WasmBackend, a: WasmData, b: WasmData, - c: WasmData, { m, n, k }: { m: number; n: number; k: number }, ) { const type = ensureType(a.type, b.type); @@ -15,6 +13,6 @@ export async function matmul( await backend.execute({ func: `matmul_${type}`, args: [m, n, k], - data: [a, b, c], + data: [a, b], }); } diff --git a/backend/wasm/operators/transpose.ts b/backend/wasm/operators/transpose.ts new file mode 100644 index 0000000..fcb6157 --- /dev/null +++ b/backend/wasm/operators/transpose.ts @@ -0,0 +1,18 @@ +import { ensureType } from "../../util.ts"; +import { WasmBackend } from "../backend.ts"; +import { WasmData } from "../data.ts"; + +export async function transpose( + backend: WasmBackend, + a: WasmData, + b: WasmData, + { w, h }: { w: number; h: number }, +) { + const type = ensureType(a.type, b.type); + + await backend.execute({ + func: `transpose_${type}`, + args: [w, h], + data: [a, b], + }); +} diff --git a/backend/wasm/operators/unary.ts b/backend/wasm/operators/unary.ts index 5894b6e..bdc7ebe 100644 --- a/backend/wasm/operators/unary.ts +++ b/backend/wasm/operators/unary.ts @@ -1,9 +1,9 @@ -import { DataPrimitive } from "../../types.ts"; +import { DataType } from "../../types.ts"; import { ensureType } from "../../util.ts"; import { WasmBackend } from "../backend.ts"; import { WasmData } from "../data.ts"; -export function unary(func: string) { +export function unary(func: string) { return async function ( backend: WasmBackend, a: WasmData, @@ -20,10 +20,10 @@ export function unary(func: string) { } export const abs = unary<"f32" | "i32">("abs"); -export const linear = unary("linear"); -export const neg = unary<"f32" | "i32">("neg"); -export const inc = unary("inc"); -export const dec = unary("dec"); +export const linear = unary<"f32" | "u32" | "i32">("linear"); +export const neg = unary<"f32" | "u32" | "i32">("neg"); +export const inc = unary<"f32" | "u32" | "i32">("inc"); +export const dec = unary<"f32" | "u32" | "i32">("dec"); export const relu = unary<"f32" | "i32">("relu"); export const relu6 = unary<"f32" | "i32">("relu6"); export const ceil = unary<"f32">("ceil"); @@ -32,7 +32,7 @@ export const round = unary<"f32">("round"); export const sqrt = unary<"f32">("sqrt"); export const rsqrt = unary<"f32">("rsqrt"); export const sigmoid = unary<"f32">("sigmoid"); -export const square = unary("square"); +export const square = unary<"f32" | "u32" | "i32">("square"); export const cos = unary<"f32">("cos"); export const cosh = unary<"f32">("cosh"); export const sin = unary<"f32">("sin"); diff --git a/backend/wasm/unary.rs b/backend/wasm/unary.rs deleted file mode 100644 index f69e5bd..0000000 --- a/backend/wasm/unary.rs +++ /dev/null @@ -1,111 +0,0 @@ -macro_rules! unary_impl { - ($identifier:ident, $type:ty, $closure:expr) => { - #[no_mangle] - pub extern "C" fn $identifier( - len: usize, - a_data: *const $type, - b_data: *mut $type, - ) { - let a_data = &unsafe { core::slice::from_raw_parts(a_data, len) }[..len]; - let b_data = - &mut unsafe { core::slice::from_raw_parts_mut(b_data, len) }[..len]; - - for i in 0..len { - b_data[i] = $closure(a_data[i]); - } - } - }; -} - -unary_impl!(abs_f32, f32, |a: f32| if a < 0.0 { -a } else { a }); -unary_impl!(abs_i32, i32, |a: i32| if a < 0 { -a } else { a }); - -unary_impl!(linear_f32, f32, |a| a); -unary_impl!(linear_u32, u32, |a| a); -unary_impl!(linear_i32, i32, |a| a); - -unary_impl!(neg_f32, f32, |a: f32| -a); -unary_impl!(neg_i32, i32, |a: i32| -a); - -unary_impl!(inc_f32, f32, |a| a + 1.0); -unary_impl!(inc_u32, u32, |a| a + 1); -unary_impl!(inc_i32, i32, |a| a + 1); - -unary_impl!(dec_f32, f32, |a| a - 1.0); -unary_impl!(dec_u32, u32, |a| a - 1); -unary_impl!(dec_i32, i32, |a| a - 1); - -unary_impl!(relu_f32, f32, |a: f32| a.max(0.0)); -unary_impl!(relu_i32, i32, |a: i32| a.max(0)); - -unary_impl!(relu6_f32, f32, |a: f32| a.clamp(0.0, 6.0)); -unary_impl!(relu6_i32, i32, |a: i32| a.clamp(0, 6)); - -unary_impl!(ceil_f32, f32, |a: f32| unsafe { - core::intrinsics::ceilf32(a) -}); -unary_impl!(floor_f32, f32, |a: f32| unsafe { - core::intrinsics::floorf32(a) -}); -unary_impl!(round_f32, f32, |a: f32| unsafe { - core::intrinsics::roundf32(a) -}); -unary_impl!(sqrt_f32, f32, |a: f32| unsafe { - core::intrinsics::sqrtf32(a) -}); -unary_impl!(rsqrt_f32, f32, |a: f32| 1.0 - / unsafe { core::intrinsics::sqrtf32(a) }); -unary_impl!(sigmoid_f32, f32, |a: f32| 1.0 - / (1.0 + unsafe { core::intrinsics::expf32(-1.0 * a) })); - -unary_impl!(square_f32, f32, |a| a * a); -unary_impl!(square_u32, u32, |a| a * a); -unary_impl!(square_i32, i32, |a| a * a); - -unary_impl!(cos_f32, f32, |a: f32| unsafe { - core::intrinsics::cosf32(a) -}); -unary_impl!(cosh_f32, f32, |a: f32| { - let e2x = unsafe { core::intrinsics::expf32(-a) }; - return (e2x + 1.0 / e2x) / 2.0; -}); - -unary_impl!(sin_f32, f32, |a: f32| unsafe { - core::intrinsics::sinf32(a) -}); -unary_impl!(sinh_f32, f32, |a: f32| { - let e2x = unsafe { core::intrinsics::expf32(a) }; - return (e2x - 1.0 / e2x) / 2.0; -}); - -unary_impl!(tan_f32, f32, |a: f32| unsafe { - core::intrinsics::sinf32(a) / core::intrinsics::cosf32(a) -}); -unary_impl!(tanh_f32, f32, |a: f32| { - let e2x = - unsafe { core::intrinsics::expf32(-2.0 * if a < 0.0 { -a } else { a }) }; - return if a.is_nan() { - f32::NAN - } else if a.is_sign_negative() { - -1.0 - } else { - 1.0 - } * (1.0 - e2x) - / (1.0 + e2x); -}); - -unary_impl!(exp_f32, f32, |a: f32| unsafe { - core::intrinsics::expf32(a) -}); - -unary_impl!(elu_f32, f32, |a: f32| if a >= 0.0 { - a -} else { - unsafe { core::intrinsics::expf32(a) - 1.0 } -}); - -unary_impl!(log_f32, f32, |a: f32| if a < 0.0 { - f32::INFINITY -} else { - unsafe { core::intrinsics::logf32(a) } -}); diff --git a/backend/wasm/wasm.js b/backend/wasm/wasm.js index 2923d82..89f2e24 100644 --- a/backend/wasm/wasm.js +++ b/backend/wasm/wasm.js @@ -1,5 +1,5 @@ // deno-fmt-ignore-file // deno-lint-ignore-file -import { decode } from "https://deno.land/std@0.128.0/encoding/base64.ts"; +import { decode } from "https://deno.land/std@0.137.0/encoding/base64.ts"; import { decompress } from "https://deno.land/x/lz4@v0.1.2/mod.ts"; -export const source = decompress(decode("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")); \ No newline at end of file +export const source = decompress(decode("8AQAYXNtAQAAAAFGC2ACf38Bf2ABBQAxBH9/DQABCAAQABoAMQBgAwsAEAEPAGB9fQF9YAEFAAAVAEABf2AGKAAACgCfA1BPAQIDBAEDAQADHwUBAAvwAQMAAQYABwgICAgHBwcJCQoKAPINBAUBcAEICAUDAQARBhkDfwFBgIDAAAt/AEGsiwgAELAIAPIJB6YFPwZtZW1vcnkCAAVhbGxvYwAAB2RlCgCxAwdhZGRfZjMyAAUKAFF1MzIABgoAkWkzMgAHB3N1Yh4AEQgKAAAeABEJCgAAHgBRCgdtdWweABELCgAAHgARDAoAAB4AUQ0HZGl2HgARDgoAAB4AEQ8KAAAeAEIQB21veAAREQoAAB4AERIKAAAeAFETB21pbh4AERQKAAAeABEVCgAAHgBRFgdtYXgeABEXCgAAHgARGAoAAB4AcRkJcHJlbHUgABMaDAAAGABRGwdhYnMWABEcCgAAFACBHQpsaW5lYXIXABQeDQAAGgBRHwduZWcXABEgCgAAFABRIQdpbmMUABEiCgAAFABCIwdkZRQAESQKAAAUACElCHUAABUAEiYLAAAWACAnCQsAETYXABMoDAAAGABSKQhjZWlHAWIqCWZsb2+OAGIrCXJvdW4jAWEsCHNxcnQLADUtCXIMAIIuC3NpZ21vaSUAgS8Kc3F1YXJlDQAUMA0AAGIAQjEHY2/6AGEyCGNvc2gLADMzB3NjAVI0CHNpbhUAQjUHdGEVAEM2CHRhFQBRNwdleHAKACA4B80AAAoAQjkHbG8fARQ6agAAhgEUMUMBAA0AER8lAQAKAAIlAQAKAPEyJQpfX2RhdGFfZW5kAwELX19oZWFwX2Jhc2UDAgkNAQBBAQsHPjs8PQI/BAreqgFPlAMBBH8jgICAgABBEGsiASQLAPAAAkACQCAADQBBBCEADAELDQDwI0EDaiICQQJ2IgNBf2oiAEGAAkkNACABQQAoAqiDwIAANgIMAkAgAyABQQxqQbCAwIAALgNAgAAQgVEAECJNAPEAACEAIAJBfHEiAkGggAEgBgBgSxtBh4AEWwDwFRB2QAAiBEF/Rg0AIARBEHQiAEEANgIEIAAgASgCDDYCCCAAIEAA4ICAfHFqQQJyNgIAIAEgeAAPdgAGRCEAC0E/AAGlAGEMAQsgAUELAABRAIABIABBAnRBrBAAUGoiAigCTgAFxgB2IAFBCGpBmE8AAMUAISABFwBgIANBBBCCFQAB1gAxASgCHABBKAIEIgcAAbAACZ4AATcACE4AUyEACyACLAAQAJcAIhBqfQGgIAAL3gQBB38CQB4AYQAiBEUNAKkAsSEFA0AgBEEIaiEGoQGQBCgCCCIHQQFxMgHyASEIDAELA0AgBiAHQX5xNgLEAWAEKAIEIgd0AREGgQEAJQDwAEEAIAYgBi0AAEEBcRshCN4BEARoABAJJwAgCkUoAKAgCiAJQQJxGyIJfADACSAJKAIEQQNxIAZykgEFVQAgIQY9ABAGJABgBiAGKAIAJAAATABAQXxxcqABACoAoSEHCyAEIAdBA3E8AAAUADEAIgYPABAAPgAwQQJxQQAwCCAIOQAB2AFQCyABIAhAABEI7QBAIAghBB4ABO0AEAt2AAEuAEF8cSIHJQBzIgRrIAVJDfUAoSACIAAgAygCEBFRAQA8ARBqtQFwByAFayIHTS8BckEDcQ0CIAG2ABB8jAAEggAQAYIAAHMAAC0CEAeEArAAIAdBeGoiBEIAN9QAAicAATQAA4gAAQ0BASwBEEEuAREHOwEQB9YAMwcgBzsBEAQ7AQAKAQAUAQARABAIEQAEOAEBsgEDggABHQFRIARyIgdiAAMkAQC1ACIoAsIBYSAIIAdBfTMAAVAAADcBECIxAQBgABIIwgARCyoCEQ9LAQA7AREELgAAPQFoQQALvwIB9gMTBHkCEgRxAhQFCQMAAgDwACACQQJqIgIgAmwiAkGAEIEDdhBLGyIBIARzAwEGAALWAiAiAvcAEAWWABAMcgAQAbgCIAYMRAQA0AJQQQJ0Igb4AxEgBgAE/gMSB/4DEgL+AxAC/gMQAnoBAMoBAkoAeQggAiACIAf+A38EIAI2AgwgiwAFJyECiAAwAg0COQEFEQCBC0EBIQFBACEWABAC2gEAbAAzAiAGXQBQQQAhAQtwBACFADAAIAFEACQEQaMDVwvfBQEJQQESAhcAACgFAP8AIgFFigICAgCAIAFBA2pBAnY4BRMDOAUB3AQABwBCeGoiAXYBQQNBfnGmAQVTBSEhBT8AUQBBfGoiJgIA7wIAYAAQBzAAEQgMAwAiAACyBAAcABAJGwARIeUEIgchiwIRA4sCEAM1ABADEgMBegISB3oCAEUAATgAYQBFDQEgAF0CAYsAICEE+gAQCCsAIwRBygMALgByIQMLIAYgA7sDAAkFAEIAAPQDAA8AEQDIAyEBIPICAJECITYCigABYgBQB0UNAkEOAwWQADICIAOCBCINAqwDEghSAwEuBQDBAnAICyAFIQEMiwAOLAEUBSwBAFEABcEFEAOkAIAHIAJBDGoQhJABQEUNAQIeAQFCAQBbAwCMABAGDQEAzwAgIgl/AARCARAFHAAQChsAAkIBEQZCATEKIAWyABAFNQAzBSAFQgECCAUAUgARIjgAAGoAAkIBEQmhAAJCARAJKwAFQgEALgAgIQW8AxMFMwEDzQAMQgEDEwQFQgEBYgASBkIBFgaQADcCIAVCARYFQgEWBUIBUAchAQwCiwAQBUwAAQoAAFUEEAtmAQASABABDQYiATZvAjYLIALhAqAEAEEAC6gBAQV/XgIB2gQgIQQLACBBAaMDcANBAXEhBSC0AiAhBhsA0CACIQMgASEHIAAhCANCByAIKjgFUSoCAJI4pwFxBGogCEEEahYAAggAAxkAYAhqIQMgBwcAAssFYCEIIAYgBHUEkARHDQALIAVFDaMDABMAQHQiA2ouAgA+ACIgAQgAAEYAHwuqACoyBygCngEQaj4BAaoAAKIAARYAAggAAxkAD6oAHQCiAABGAACyAANGAA+qANUF/gESk+UBDv4BAxkAD6oAHQCiAABGAACyAANGAA+qACwA+ABSBygCAGs7AQOqAAEWAAIIAAMZAA+qACEARgAAqgADRgAPqgDWAKIBAP4BEpTlAQOqAAEWAAIIAAMZAA+qACEARgAAqgADRgAPqgArEAf4AABZARJsOwEOUgMDGQAPqgAdAKIAAEYAALIAA0YAD6oA1QX+ARKV5QEO/gEDGQAPqgAdAKIAAEYAALIAA0YAD6oALAD4AFIHKAIAbjsBA6oAARYAAggAAxkAD6oAIQBGAACqAANGAA+qADQSbZEADqoAAxkAD6oALABGAD8LC7eqACkAogEA/gEgEMZJCALqAQOvAAEbAAIIAAgeAA+0ACEASwAAtAAISwAPYwE0EnBKAQO0AAEWAAIIAAMZAA+vACEARgAArwADRgAPqgA0Em+RAA6qAAMZAA+qACwARgAPDQI1E8CkAQavAAEbAAIIAAgeAA+0ACEASwAAtAAISwBCCwvDAUURD7kAIRAHmQsRCWoBICIKDhEiSxtTAQZ3BQAfAAMKAAkiAA/BAB0AuQAARQARB8sAAAoAEAOBAAFPAA/FADwQSlQAD8UACgQiAA/FADQBTwAPQwI1E8faAQLBAAC3AAEbAAIIAAgeAA+9AB0AswAASwAAxQAISwAPfgErAXcBEgmFAVEKIAkgCtIBBr0AABgAACwSAgoACSIAD8EAIQBFABEHwwAACgBRAyAHIANPAA/FADwB0gEPxQAKBCIAD8UANAFPAJALC9oBAgV/AX28AA/HACESKqgA8AIqAgBDAACAPyAJQwAAAABdG0IKBs4AAyYAAgoADykAAg/VACECVgAA1QAPVgACbwsLxgEBBqEBEAjWAAAnAAHaABAHKxAB4xMA0BBQAEgbIAnCCQLUAADKAAMgAAIKAAsjAA/OAB0AxAACUAAA2AAAUAARA1AAEANQAGILC7EBAgSkAQAFFEBBACEDCwACygAQAsoAMAQgAsoAEAUbAKAgASECIAAhBgNAdhMAJAEgB4w9EgMaAQBvARACxAASBo4BDx4AAWAIaiECIAYHACAGICUBQQJqIgO4ABEEuAAQARMAMHQiAoYBHwJEAAIzCwusmgQPsQAeAP0AwAcgB0EfdSIHaiAHc1EBBbAADx0AAw+vABoAQwAwAiACQwBAAmogAkMANwsLya4AgiACQQNxIQNBMAJxAkF/akEDSRcAEnyxABACGwCRA0AgASACaiIGVQAQIgEDADwBAKUAAR4CBRAAEAgQABYIEAAQDBAAFAwQAAAZEgJPFSNBBB0CEQuvAhAgFhVAAnQiBh8AUAEgBmohIAE1BiACOQAQBBoAAHAAECE7FAADFQA9AA/LADAhKAIXFABbABAgywAFEAADywAFEAADywADEAAPywAfBTkAD8sABB/OywAuQCoCAIwuAQBcABAgzAAGEQADzQAGEQADzgAEEQAPzwAfBjoAD9AABB/Y0AAnEEF3AADSAANHEAFeAAD5FQKgAQMTABIIEwABowEDEwASDBMAAaYBARMAD9gAHSFBAKkBAzwAD9oABB/n2gAnA9gABMIFAHYUAWEAECDbAAsWAAa0AQgWAAa5AQYWAA/mAB0QIL4BCD8AD+kABA/DASgD6QAQKOcFAAgUAV4AECDmAAgTAAPjAAgTAAPgAAYTAA/dAB8IPAAP2gAED8MBNhG/QgEAYQAQIN0ACxYAA+AACxYAA+MACRYAD+YAHws/AA/pAAQPwwEzEX9OAQBeABAg5gAIEwAD4wAIEwAD4AAGEwAP3QAfCDwAD9oABC+AAtoALQJCARYAqgsBZgAQIOIADxsAAQPqAA8bAAED8gAOGwAP+gAfD0QAAQ8CAQQT+/EJDwIBJwAfCCAIQfsTMABKG24BAGUAECABAQ8aAAADAAEPGgAAA/8AABoAAEIFFAYaAA/+AB8AQwARB8QFBUMAD/0ABESpAQEE/QAAWAkACwAPcwkSBGEBdJdDAADAQJZiAQFjAA8cAAIPcQkaDkIANwsLwYQDAJAAAAsAD6sAAASnAAAjAAKrAAIOAX4GIAdBBkgbGAEBswAPJAAKD7sAGgBKAFECQQYgAkoAACccEwJKAA+dCDQQjVABALQAECBiAgYRAANZAgYRAANQAgQRAA9HAh8GOgAPPgIED9AAMhCOYwAAXAATINAAAxEABtAAAxEABtAAAREAD9AAIgM6AA/QAAQf59AAMSQQzXMEAGEAEyDVAAgWAAbaAAgWAAbfAAYWAA/kACIIPwAP6QAED7kBMhCRYwAAXAATIOQAAxEABt8AAxEABtoAAREAD9UAIgM6AA/QAAQfmscEIwD6BxE/zAQQkcAYAWAAAxQAA9IAAxcADwIEFQI9AAAiAQQ9AD8LC76cAC0wjBDE0QEBEQAQklQADqgADyMAAQ+0ACINSQBECwvkAe0RAMIADy4CJkAiCCAIYhEBswATIDICBxUABjYCBxUABjoCBRUADz4CIgc+AA9CAgQf4gYIMyAgCH4RAWAAECDkAAoVAAPkAAoVAAPkAAAVADEGIAYVAA/kAB8APgAzByAHPgAP5AAEH+f2AzEgEMEhAgBMAQBhABAg5QALFgAD5gALFgAD5wAJFgAP6AAfCz8AD+kABB/P/BIqAwQDECKcEsSAPyAHlZJDAAAAP5RzAAFxAA8oAA4PfwMVAVoBD04ACw+6ATUQzGEAAJ4AAMEAFCC6AQcWAAe6AQcWAAe6AQUWAA+6ASMHPwAPugEEH8y6ASoMQwEkk0NDAQFyAAFwAA8nAA0PuAEdCE0AG7+3AR+6zgAqIiIHMQEiIAfzAgCPBQnIAA8hAAQPwgAdD0cAAUULC28BuQAATAJQQwAAwH/kADA/IAA0ACADmMQoIlwbEwAgA4wOAAD6ACAAXRMAMwDAlBgBMQOTlBkAA08GICAA8wEwACABBwAAdi5Bf2oiAvoBH+fjAjIBdQAAaAAAIwEUIOMCBxYAB+MCBxYAB+MCBRYAD+MCIwc/AA/jAgQf5hUCIyMCQBUCYEMAAAAAYF4qAm0AAF0BIL+S2S0wAiAHegAA8gEBVQAAfAAPMwANAScBADYAEAIxAgCwAAQ4AgDxAAIzAiACQGMYAPMAAzACD1AABwCRAQFQAABVFg/oACIC+ggTf+0AIBDCYAAIJxgBswADIwAE4AAPJgACC88ADwcDBgJMAABDAg9MAAQxCwtumCoAfS0wdCICdCugdEGAgAFqIgMgAtkbEUE3LQM1MYEDQX9HDQBBAaQCEAMzKhADQi0hA0LWLACJHQk2MQDNAhALXwEAxCoQAOIscAALBQBBgAT1KbABCwIACwQAIAELFHYCABUdUAAgAV0brSqQXBsLCgAgABDOrwCAC4wCAgJ/An2nAAACAEAgALwiITVAgARIDW0DwP////sHSw0CQYF/IWABIQAAhANwgICA/ANHDZcqARotcv////8HcQ3QAQBxADCUlQ8NMVAASA0CIBYAkABMlLwhAUHofrUA8QoBQY32qwJqIgFBF3YgAmqyIgNDgHExP5QgSQChA3FB84nU+QNqvk4AsJIiACADQ9H3FzeUWQAATABUQJKVIgMNAEE/lJQiHwEwlCIAFADyAJQiAEPu6ZE+lEOqqio/kjUA8AYmnng+lEMTzsw+kpSSkpSSIASTkpK7MSAAD0QBEQDJBaUAlQviBAIEfwN9Ey4gIQERAUACQR92hQIKAgAgIAKuAMD/B3EiBEHP2LqVBEvdL4BBmOTF9QNLDc8ucYCAgMgDTQ2PBAFhACAhBasCEQxwMQEfABH8xzAgAA8RABACLgEAQgAwl+TFTQAQAmUDQX9KDQNEBTCAgCBgBXIIIAEqAggaTgAA5hugtOO/lgRLDQYMAyswYJKrlPwDS5ctgEEBcyADayEEGAABKAEgf5SSAQMMACCSOHIvQSoCDBoRADCAP5IIAWFDO6q4P5TfAjBByICNLQCaKyAiBjMAIM9gUwVQAkAgBosPACBPXdAEIQaoei8AygBygHghAgtBABMBAaoC8ACAgHggBBsgBkP///9OXhsRLSJcG1MtIASyVQBAcjG/lN4BwAZDjr6/NZQiBZMhBh4AEgYCABCUmArwAkMVUjW7lEOPqio+kpSTIgeUfQCAQCAHk5UgBZMyBzCAP5IIARVFAi5RBEH/AEpIAWCCf04NAiC+ADCADJQlAFBBm35NDZkBUOYAaiEESS0AHQBRAH+UIQY5ABCBVAZAQYABT2kEAiEAYARBgn5qIlQAAVkARkkbIQQ1AACkAwANAARfACG2fQUAYEsbQcwBauoAABUAEBfzA2CA/ANqvpTfABIGfQMQw2ECMQvtAzwMAgIAICABagIgAXRYLwCxAyABXBsC4bwiBEEXdkH/AXEiBUH/BAUQBCUAMAYgA8wAEwIdAADCAFACQCAFDRgEEQXOACEJdNgdAhIAcQNAIAVBf2qGHgBjAABZAiAAC+AAoQEgBWt0IQMgBg2nLxAEwgEgA3G0ACAEchcAMEUNA4kCCBYAEQJVAjAgAZTJLwDpAwBEAjEAAJS8AXADRhsPC0EAkQAgIAKFABQHhQAApAUQBoUAAC4TEAEZAAOFAIACQQEgBmt0IU0EAMUAYCAGTA0AAwsAUgMgAmsiQQAgIAfmHgGOAADDACEhA9EAQCIFIAZFAEEgBiEFPgAAAgARIDcAQAZBf0ykAgLFAAFPBQDFAAA2ATADIQfdAQO3ACgPCx4BUYCAgAJJeQcAowAAPQAQDaQAAa8DQYB4cSEIBDEgBUFlAhEHPwEwdiEFCwIQByMAoHxqIAVBF3RyIQWnMjYDcr4fATALDAA2ASEQxfwBERTkAREgEwAgXRsIAIFcGwu1AQEDf2EAMAJBD1AEAwoGAMUwggBrQQNxIgRq3wEAJAICqRRQAyABOgBnBwFYBgA/NRALewBgAiAEayIEdTAD1QcwAkEBRwEQAS8CgEGBgoQIbCEC+QABOwZAIAVBBE0BEgM/ABAERwkAjwEBgwcAUAERakQCD2wAAjEACw7GAEEgAhDI2wD1AMUiBwp/AXwIfwF8BH8CfKQ0UrAEayIGmjCCIAZCADcDmAEIABOQCAATiAgAE4AIABJ4BwAScAcAEmgHABJgBwASWAcAElAHABJIBwASQAcAEjgHABIwBwASKAcAEiAHABIYBwASEAcAEggHAAOQACK4AggAE7AIABOoCAAToAgAE5gIABOQCAATiAgAE4AIABP4uAAT8AgAE+gIABPgCAAT2AgAE9AIABPICAATwAgAE7gIABOwCAATqAgAE6AIACLYAwgAE9AIABPICAATwAgAE7gIABOwCAATqAgAE6AIABOYCAATkAgAE4gIABOACAAT+MgAE/AIABPoCAAT4AgAE9gIABPQCAATyAgA8ADAAiAGQeADakEAQdAAEMnhAYEaIAVBAnRB0EcGICgCZRAQAbAD8RoIaiEJIARBfWpBGG0iCkEAIApBAEobIgsgCGshCiALQWhsIQwgC0ECdGY2MWtB5EEAICENyjUQA7gLQQlPIQ46A1EJSWohDywDcApBAE4NAERlAwABAPAoIRAMAQsgDSgCALchEAsgBiABQQN0aiAQOQMAIA1BBGohDSAKQQFqIQogDyEBIA4gDyAJS3JBAeMJkEEAIQoDQCAKIKcAB1EAAH4AYAJAA0AgEOkCAE8AECs0AlMgCSABaw4AQKKgIRCmNyBPDZ0AoQEgCElqIgEgCE0jA3AGQcACaiAKKwABiAAAtQBAIAdPDZs04wogB0lqIgogB00NAQsLdQAj8H8JAMDgfyAMIARqIhFB6XcyCWP/B0siEhsdABQA9QD0AGADIBFBaGoiE0G5cEkiFCAA8BHwPyATQYJ4SCIVGyATQf8HSiIWGyARQepvaiIJQf8HIAUA4UkbIAEgEhsiFyATQfBoBQDwGEsbQZIPaiARQbEHaiAUGyIYIBMgFRsgFhtB/wdqrUI0hr+iIRkgB6UBAfcB8wNqQXxqIRpBDyARa0EfcSEbQRAKAMEcIBFBZ2ohHSAHIQ0/AQIIARANCAGQKwMAIR4CQCANYQQBRwBBIQkgDeUBEx6/AFNwPqIiEAwAUeDBZiEK7gEkEJkTACBBYzwAVRCqIQ8MhQiBDwsgHkEAQf+HCBIPFQBAIAobIEgA8wLA////30FkGyAQIBBiG7ciH0kAT3DBoqBpACEfCWkAEwBfBQA0AgL+ADBqQXj8AFAgH6AhHuQCUEkNASAJlgIQCTcCYEEBS2siATQCAIMAwgJAIBYNACAVDQEgEwQ2BBsBJ+B/GwH2AH+iIBAgEhshHiAXIQEMASYAJmADJgAgYAMmABAUJgAQGBU5AH0ABc8BISIQuAAAAQBDwD+inAsAKyDAGAECiDcPGAEAFgkYAUUJCyAQGAESCRUALyABGAEBYCIgt6EhEFMAAgIA+QAgE0EASiIhDQAgEw0CIA1fAoAoAgBBF3UhIt4AChoAAIQIAGAE4AEgASAcdSIBIBx0ayIJdAHwAQkgG3UhIiABICBqISALICKzBwBFAUFBACEijwAAAQCh4D9mRQ0BQQIhInIBISANqwgSCmgAQAFxISMOAEBBACEJHAAgQQGACRANfQ4QDBgAAoYAICEBIAASA+g9ICEO+wAUB5oEEA3KPmGACCEPIA7cDRAOWQBQASAPIA7kIkBBACEORwIRAv4BEEEuEABDABgKQwAmDkVEAABPAAOdAFEEIA8gCkQAMAEhClMNEAgXETAMIAnHBDALICOZAQGeAABfAEB0aiIPWQABYA0RB8wAAEsAAVYANgkgAVYAEQ/SBARWAEACQCAhfgBD////A/wBcB0OAgEAAgsTABABRgILjAEBZD5AACABcY4OxSAgQQFqISAgIkECR58F8wLwPyAQoSIQIBmhIBAgChshEHsBBZEBQAAAYg0gBTAHIA0wBjABSw2eABMJPwQA0QAAGQYAEQKQIAlyIQkgByABcwUhByAEAEJJayIBcwUWCQIBAKUAAJ8AECFHAyARA8kBEH8GBmIRQWhqIRG3ATIIIAEiAPABCEUNAAwECwsgGiEBIA0hCg8GIEEBLgYBKAAAqAEBKAAAYAAAAAEgAWqZASAhDZABMEsNAaYAQCAPIAhiBQDuBUAPIAtqCQcR4MgGAJQGAIcGQg8gCknUBgX2AAAKAx8DYQYsEA8rAAFhBlAgDyANarQBAWsAIA0AogAAtgtwASEPIAEgCjUAARMAFAFpBFFBGCARa2AGANgKdQFBgnhODQKVATBgA6J9AMJBuHBNDQFB4QcgEWuQBAQhAILgf6IhEEGZeEUAgoAISQ0BQZpwDgAQ//sHav8HSRshATAAAHICBBEABGIAIfBoBQACgwYQIUMSABwCAUEABKwEEx4zANBwQWYNACAeIRAgEyERTAAFGQALOAYCuwIPtwQAAIY/AAYDSIB4IQg4BhIIFQAPtwQDFbdcABBwOAYEdQAGaQAbHmkAHB5pAAiWAg9zAAAAUgAFcwAyHiAeQgYBagIWDTEBBnAAD9kADg9wAAwAUgAFcAAB4wAAvgMAWwBRAkAgEUESAgNiAGDwPyEQIBFTCEENASARAwIDGgAh4H8aACCBeKUIAQACACgAEHAOAAcAAgMtACHwf/0BAV8AAFMCdQAgEUHJB2ogACFgAyAAICARDwIABQATSw8CAyAAAC4DGgsWAgA/AxAC2gMRAYhCEg0JBwIXAwFwCCggEAgBAIkDEKIoAwD9AAABACBwPoACcQ0gDUEAR2t4AgGaCADPAwFEAAGUAwVEAASDBAJEAAMiAADwEkJHayIIKgAGWAAUIjYAGQg2ABAIwyMAbAAILABHIRAgCNEDAboAARgJMAgDQC8EIEF/+yPDIg8bIQsgDSAPayEKPAAAEwFDQQEhCEUEQAFB6IJxBABGBDAJIAEIAAFABEAIIAdLQAQCLwaACCAKTSEAIAhbAhAIKkYBeQAooAGrCkAgCUF4gwAAyQRUIQggDw0bAgAGD3QOBAEAAAIDBQIAhQABGQAArQIArg4WAIsBAcMAAUEBAGAAASUBMisDAJQAAQkBICIBhAAwQX9qNgAAlwQA/gARSYMBBDYAAYUBADYABBAAA3MBDxgAHQ9+AAAADgEAdwCgIAIgEJogECAiG/wAIAYrfA0REKcIARACMEEBIeMFDZEAALwEJCANmwURDZsFEA1mBQlRABYIMAMPKwG9JwwB2gAQGZIAA4cDAZECA1QAAEwAUCIIQXhqqxVwKwMAIhAgCAcAQB6gIh9vAZAIIB4gECAfoaANAAMcCwCJACMBSxULAL0DAM4GD1gAKxQDWAAQAlgAEEFjCBgLvgBDA0AgGVsAEA1bAAH/ABAZDAAAOQAAJAQAOQATDTkAAiUCAM4BICAiORQCNgNgAiAZOQMQkRtAKwOoAfsBEgExAQMdABeaHgAxmjkDpgUjsAS4QfQDICBBB3ELuAsFAX8BfAJ/AnwBQxFDEGsiASQAQAC7IQJCAgICAAAqFBID3AWAcSIEQdufpPoSAoAgBEHSp+2DBLkAsQRB1uOIhwRJDQIg5hOw+wdNDQMgACAAkyHyCDECQCDlEhHMOABgAiACoiIFBQAQBjJD8CCioiAFRKdGO4yHzcY+okR058ri+QAqv6CiIAYgBUSy+26JEBGBP6JEd6zLVFVVxRkAQQKgoLZZAADmEgAmFSIDlAgAInuSaQDiBEkbOAIIIAEqAggaDAOAAPQC5JfbgARJDQBEGC1EVPshCcAJABBAChtgShsgAqAijwBQIgIgBZqcAACoAD+iIAKcAAUfApwAAyEFoZwAAXUAEgNfFBMCagBA+b+gIlUAwyICRIFeDP3//9+/ohwCMfA/oHAAwCIFREI6BeFTVaU/ohIAEAWBAPMFaVDu4EKT+T6iRCceD+iHwFa/oKJlAAZcAB8/XAA5IIwhDUQBNwFH4Nu/hTcBFBk3ARAZ3wAGNwEBOQEPNgEOHwU4AQYC0gEBdAAFNgGP0iEzf3zZEsDaAD8GXQAfQF0AORAhrARxIAFCADcDCDoDcARB2p+k7gRvFaQCRIPIyW0wX+Q/YQA0OEOgCgBDw6AiBQwAAH0JAg8ZGwV9CSEFqrIVAOACVYB4IQMLcQkBWhYCExkARgAjwP9xCUAFIAViVhgRAhcAIABQggLxAKKgIAVEY2IaYbQQUb6ioGUZ8AYgASAEIARBF3ZB6n5qIgdBF3RrvrtNBCABQcsEoAhqQQEgB0EAEModBACdAASjAUEBKwMIQgBxQQAgBGshBBEAEZreFQICAAHuFWAOAwECAwCjBA9oATUAxQEA/AIAAgAwoiIFdwIAgQIPSQQGHwJLBAYEdwICSgAPnQAyAgUCAjUAISACSgQPnQAKD5sABSEgAkoEAIEPFBC9BYAACwoAIAAQyw0AYgsYACAAvPsBEHEKAq/3A3K+IACSjwuo3gUZAAIAD+IFLRAGtwMBeQUH4gUPTQE1EAagAgPeBQXVBQAPANA/IQAMBQsgBEHjl9uA1hwBmQIAmhkDowRf+T8gAqGdBDcQBTcEBFoAD/UEOAEbGxDfZwUIxAAGowQfwGwAOgVWAA8cATovAwv3BP8KAfQCAGQBAG4BDwkEBg+mBA0AgAIASgAPWQM1EwRQAB8FpgQwAAECAU0AD50AMgDgBSMCC2wDD6kJAgFRAA9sADYUAWwAD94IAgFRAA9sADINzgVAC7IDAS0VcsAAC6gDAQABAAAIALECAAAAAwAAAAQAABAAAAgAAAQAkwUAAAAGAAAABxgAAAEAAAgACDAAhAAAAD8AAAC/EAAABAAANADw+IP5ogBETm4A/CkVANFXJwDdNPUAYtvAADyZlQBBkEMAY1H+ALveqwC3YcUAOm4kANJNQgBJBuAACeouAByS0QDrHf4AKbEcAOg+pwD1NYIARLsuAJzphAC0JnAAQX5fANaROQBTgzkAnPQ5AItfhAAo+b0A+B87AN7/lwAPmAUAES/vAApaiwBtH20Az342AAnLJwBGT7cAnmY/AC3qXwC6J3UA5evHAD178QD3OQcAklKKAPtr6gAfsV8ACF2NADADVgB7/EYA8KtrACC8zwA29JoA46kdAF5hkQAIG+YAhZllAKAUXwCNQGgAgNj/ACdzTQAGBjEAylYVAMmocwB74mAAa4zAIAEQQMMFAAkA8AUtRHQ+AAAAgJhG+DwAAABgUcx4OxAAwIMb8DkAAABAICV6OBAA8w0iguM2AAAAAB3zaTUAgUwLLmRlYnVnX2luZm/FYwHAAAAEARs4AAAcAKI3DgCwAABZNwAAHDIAABShARCiBQAQw9QQEL4FAJDuAQAAA38MAAAJAIICAgEAAARkFQ4AQQFHAQEgABQFPQAgB+3MASAAnxUAYgFPAQZIAFkApxMAAAABUAERBzoRALEEGwEIuAAAACkyAC8CMAILCT0A8AgAAAJAAgAAAvY0AAACXwAAAAkHAwAAr4cAILoBQwIgAGw9ACAAkwYAA8kAYuA2AABpAckAUDEyAAAKRgAFyQBgAyMJAADdkwAAsQAACQAUBCUABLEAABUAYgFPAQUwAEEAAIoAALEAAB0AIADqagAgAOYGAANwAGJnNgAADQJwAFA9MgAADBwBCrYA8AQDBRAAAIMAAAACQQMBA6AJAACLDQARbj4DBpwAAmUBkAYCAAAEHgYAAAkAIAMZUwEiAiMOAAG0AAAJABQGaQAEtAAAFQBQAU8BB3QOABIAsABxCGYAAAAgAF0BMgk1AJ4AEBePACEcEhAAUKUyAAAIEACSKg4JQgAAANYydAMgAzXzAAABABCSIAEgAHUGAAPuAGI3MAAASwTuAFBLMwAAYukAD+4AFyACjYQB4EcdAACbLgAAA6UFAQKHFwABOADwAz0fAACPLgAABMIBAQM0CgAAwQ0AENtoAjAAAlpkABBvCgAQQ9MApQYmAACuLgAABts/AKGfFgAAsisAAAeOGwIMWAEQ/sYAURsiAAD+UwFAAQAC4gkABMUAkATtAAGfhwcAABYAMAEiBiEBI1sztQTAJRIGVgAAADU0AAANEAChWAkHrAAAAFE0AEEBVwFJIAiZEABnB5UBFAd6EQBXBuINCW0QAPABBOACEgAAAAfQAAAAEDUAAD0AQAFjCQaGATGlNQAeBUEFHAkAdgBQ6zMAABUhABA5fAAUAPQCEAi1AAOWAWIoMQAArAeWASKuNc8CBgABQgMiJQDXAABAAgAJABQEJQAEQAIAFQAE9AIAHAAAAQIARAIAHQAhAPlwABdbcABiEDMAAFAIcABQujUAAO1hAQ8GAgkEtwM9AroBEwIQtgUAAGgAsAPlIwAAmwIAAAPJSBUHwgACwgEQC4IABG8ABLoAQHQoAAAZADABBQWzAQAfAABbAUABBxMFTgEx0jUAUQSQAQ0ZBWgAAADUrgMAEAAhNg0QAEAHNwAA5gCxAUIJBU8AAACbNwB+ASABWDYABW0BEKx7AAP9AGJCLwAA5wr9AGioNwAADACrADMDxgeRAABtAQAJABQEJQAEswAAFQAEbQEAHAAnCwBtAQKaBRD/OAADcABiGDIAAIsLcAAxtTcAXQUGcAACGwEQ1XoAQN8TAAAJAAKaBSLADA4AAYgAAAkAFAU9AASIAAAVAASaBQAcAACJBQCIAAGaBQQRAASaBTHCNwBJAQ+aBRYgpQzJACaSA8kAYrAwAAD0DMkAAAEAJDAEyQAQurYAELQDAlD6EgAAYFkAMBwBAggAYAPpCwAA1CQAgB4BA8AkAAALKwCANgEDqAIAAEgMAPABKAEAA9kEAABtAgAAAnwBAggAYAM4GgAA5zYAgIABA0YDAAApKgCAmAEDRRAAAGMMAJCKAQADdBcAALolADDhAQIIAGAD9xwAAMQRAIDjAQO9GwAA+wwAEOxNAVf/////QXYCQIcgAAA/AjEBDAF3AgAgAKIzAQAABhoJBZcLEAABLgFHZyEGihAAcwNfBQ0ABUYyAAA6AFcCaAkF4iIAVwIfGAbVEACCBFIDEgAFPAwSAACOBFcCIxMGLxAAEAVNBAVEAAB8ATUCIhREAAAQAAFEADMABVJ3ABBYIwBHcg0F/CMAVwJSGgbvEAADMwATXjMAECwjABZwMwAAeAA1AjAZMwAAEAABMwAFIgAARQAvAi9VAAIJzQAvdQ/NAAAEIgAAqgMmAmoiAAAQAAIiAARDARAvIgAleAUyAABEAA8hASUD6AE1sAIA6AFQ3xQAACmvAzQMAQfIARAQ0QWAIRUIawAAAEAMAConDX8AH8d/AABRCHwAAAB5AYDNCQgJDAAAcAwAJYEahwAAVgNjBJIDEgm3EQAB/QFXkgMeBqoRAHAHOgUNAAAFQQAAEwAAvAArAoPMABCSzAAjBYghAQF0AEjXDQUWMwAbs5gBATMAUAiUAAAANwArAtUvAB+QLwABIwVJIwAAvwQmAs+lAQAQACAFIAwCAPQAABIAAKYKPwLdBbcAEQSmAQDqASYCxiMAABAAAqYBBXADEDFwAy8lDXAD/1wQLSIAD3ADNxDL1AYA2AIDcANA5SEAADYCAFgFkKEAAADWNwAAp2QDMC8JCegBFOSGBjEAARzpAQQRAAHpAaAJsgAAAOo3AAAnIwAiAQHqAQARAAAjADEC5BOFAAQQAAGFAAEiADEHOAD1BzEC5xEiAAQQAAEiADAACb5EDTA4AAC3BiMCBlYAABEAAOoCIgL1VgAEEAABNAABlgETRkYAMQL5F5YBBBAAASIAAqwAUFg4AAAlIwAxCgEFVgATcyQABIoABBAAAjQAMAAACkIBF0oxAVDwFgAAnMgHIQwBHAAXDhwAUpcnAACjHADBAzcgAAANLAAABksB5QQXuSgA4qoDAAD6NAAAAWEBBY0HpgEQuHUBMIsJCOgBEKAMADBQRwvkARTI4AGHAAADeQgAAJdUABfcVABTYCIAAHpUABPhVAAQ20gAgI8JCGMMAADwDACAUEcLVgwAABidCBLgVABvJCgAAOAtVAADYpIeAACQMlQANjUIAFQAgJMJCH0MAABAEQSHUEcLcAwAAGhUAF9VHAAAHFQABGLLJwAAuy9UABiJVACDlwkIlwwAAJBUAFeKDAAAuFQAUDYHAABV/AASWFQAF3QdCFAdBQAATMYLQ2EBBd1UABBzSAASoFABEOAMACFmS1ABAMYLAVQAARoAYjACAAAGYBoAFFgaAIcAAAO0DwAA4W4AF7VuAFNXJQAAzGoBIksJbgAQrWIAEqRqARCAVAAhZktqAQA1CQFUAAEaABDQGgASYBoAFPAaAIAAAAOOEwAAKlwND24AAFPJCAAA4oQBGLluABKohAEiEANuAACEASM4A1QAARoAEGAaABJgGgAUgBoAgAAAAxIPAABmngEPbgAAYiAUAAANMG4AJycKbgASrJ4BEKBUACFmS54BFMhUAAEaABDwGgASYBoAIxAEGgCAAAADkRoAADFKASFvAW4AF7YMAlKNDQAAI7gBIweVbgAAnQSnBrUJAAN6JgAAvDkAF905AFLKJgAAo4MBIwfOOQAAZQJgBrkJAAOJfgAATgEDOQAX3zkAUjcjAAC5TgEjBwcgBRDeOQCQvQkAA5IfAABBGQEDOQAX6DkAUoMRAADktwIjB0A5ABDnOQAQwUgIApsLELboCnZMAAAADFgJWA1gDNwRAADIqAtQXgUBAALjCzIMMhsgAHIHiQQBDA0cIAAwBzkFQQAAsQ8gAn8FAADmC/MSDAMEAAD6KwAABMwBAQx3HQAABSwAAARNAwEMZxIAANcqGgBQPw0AABAnAAAaAFDqGQAAeicAkI0DAQwmFwAAGxoAEY39DQX+DzIMDyFaAHIFwgEBDMwFWgByBdsCAQziCUAAoAUbAwEMBRkAAIINAAAnAFAnGAAAjg0AAScAUx8AAMstGgBQpRwAANcNAAAaAFBKFgAABw0AABoAUOseAAATDQAQ2ycNQAAAAE1gBUUAWgQAqQxx7jUAADgcAKkMQIE4AABVBSACogUAAakMAKEGFAMYAASSAQAVACEBFFIAIJENUQAXi1EAUwE0AADHUQBkkTgAAEURpQEBXwEFBQEyA7ElRQGBAsIBAQPADgBFAbMC2wIBAzQOAACjLRoAUL0gAADCDQAAGgBj+goAAGcuGgBQ+BUAAIYNAAHeAAa5ATIDTwtAAHIFzAEBAxYVQAByBU0DAQMtKUAAARoAIuYNQAAAGgA8AAAAdxHwDiMnAAD7KgAAC9sBBLUoAACMLQAAC+cBBIYKAACvDACS2wEEsxcAAHMuDABQxR0AAFAMABXniQDwA+EaAAAmKwAADI4BAQOQIwAAQg0AkLQBAQM9EwAAYA0AABoAVGMPAACYDQBQdwUAAHoNACC0AUgAEJcFABBUmgAA3wLwBANaGQAAxioAAAPtAwEDXQYAAOUNAGAaBAEAAjkgAFCmEAAAyxMAEEwTABAmEwBQwSkAAOoTABCoEwAA2wAzA/wHRgBQbAIBAAKcDzMDKyQ5ABDGEwAAWgNgBJoVAAB7SwMQvYQAEJUZARB1BQAQVh0AoGQhAADMKwAADSA8ATAAAqQkAADXDiACHE8AUHoUAAB5KAAQdFoDMAACngUAAccAEDFSAKB5GAAAtioAAAYbuwFEAAIMMzMBIrgSMREgCH6VAQbZA7AD9gwAAI0CAAAKzRgBA6QCBhYQkKgBAAAEfikAAAkAEAfEABCREgBAxBgAAAkAYAkKAQACRfkFBJQCkATtAAafPR4AABYAsAHiBh0BAACYOgAAtBJmAfUOB9oAEAB2DJUBFAZHABEAVwviDQg6EAAhAuBzBfAUCY8BAADABAAAAQQBDglvAQAA4AQAAANNBAkIFwIAAOc6AABSDbID8QMcCDYCAAA7O5sS8AAD7gMMAAAHKgEAACI7AAAiElABBQEJB3wVBBEAUAy7ARgGKAoEEQAxC+sNxwwEEAAwBVIDhABjBzcBAABxFAB2AREBEwfyABEAAcoAF2ERAADKABdUEAADygABRgATfxQAQQERAR5GAAQRAAVGAAQRAARGAAQQAARGAAAQAdCIOwAAGAAAAAEQARIIFAEEEQAAGAEC9QBQoDsAAAwjABMT9QAEEQAF9QAEEQAE9QAEEAAE9QAAaQBAsTsAAE0MQQEOAQ5pAAQRAAFpACAJ+DcC8xEFAAABHAESCqIBAAAYBQAADSEJC3wBAAAwBQAAA6kECfoAIqY9mQFBAR8BEfoABBEABfoABBEABPoABBAABPoAAEYAIqQ88AFBARsBDUYABBEABUYABBEABEYABBAABEYAAPEC8QXUPQAAegAAAAEkAQ0MUAIAAD8+ACkLsgcgCQAInwIAAE8+fACkASUBFAdEAQAA2BEAZjABEgf+ABEAAXkAF3sRAAB5ABduEAAEeQAARgAT8hQAQQErARFGAAQRAAVGAAQRAARGAAQQAANGABAJXAcQSHMBQDkBFgntCBBoZwGxxwIJB9sBAADBPwBzFncDbwIeDGkCEQAzvxYAhAAiFkDoAUEBOwEZhAAEEQAFhAAEEQAEhAAEEAAEhAAA9wEQiIQAMVwBFvcBEqD3ARAJ9wEQuJAAMakECY4DUNpAAAADfwAgGwRBAAGAACLjQJEBQQFdARaAAAQRAAWAAAQRAASAAAQQAASAAACaAhDQgAAxZgEaEwQQ8HQAABMEAHQAIYRBlAIBAgQBJARAsEEAAP4AACQEAxMEMZhBAFUDQQFoARUeAwQRAAUeAwQRAAQeAwQQAAQeAwDKAFKhQQAACEYAESbKAAQRAAXKAAQRAATKAAQQAAPKAAHTAhPSWgBBAWsBH9MCBBEAAUYAANMCBBEAAEYAF1QQAAhGABPgFABBAWsBKkYABBEABUYABBEABEYABBAABEYAAFYBIulBSARBAWoBHvADBBEAAF4BAjsBIgFCDQIjAW07AQQRAAU7AQQRAAQ7AQQQAAQ7AQCCA1BNQgAAqxwAE4GCA0TrQgAAggNwB1EBAACuQ/sIhwAAAYQBDQcKEQABaAAmuwARAABoABeuEAAIaABAX0QAABwAQQGOAQpoACYBRWgAAckCkBAGAAABjwEOCskCJjgGyQIiYAbJAhALRAIQiA0AIB4EXwAQCQYBEKg2AECQAQkJAgEi0AaWABAK/gAh+AaSABAL+gAlIAeOABAJMQIhSAc2ACAbCS0CImgHnQEQCikCIYgHmQEQCyUCJqgHlQEAbAAiS0ZAASMBnMsFBBEAAHQAAXIBBBEAAAoBAHgABBAABHwAAOgAEMh8ABOV6AAh4AfoABAL6AAi+AfoAAMoAGMQCAAAAarZAyFICCgAARABIoAIKAABEAEQuA0AAxABAH8CEOg2AECrARcJewIjMAnaAAB3AiJ4CdoAAHMCJsAJ2gAANgAxbkcA2QNBAbIBF7UCBBEAAD4AAbUCBBEABLUCBBAABEYAALUCIoRH4ANBAbEBFrUCBBEAAbUCAdUAYwgKAAABo9UAJkAK1QAneArVABCwDQAH1QAQ4DYAE6TVACIoC5cAAdUAIXALkwAB1QAluAuPAAFsAAB6ASMBuGwAIRgMbAABaQEiMAxsAANeABBIKAAxuQEmXgAnYAxeACZ4DF4AJZAMXgABMwEisEjAAkEBuQEWMwEEEQAAPgABMwEEEQAEMwEEEAADRgABpAAQqHwAE72kABLApAABEAET2KQAAUoFE+06AAO+BQG2ABDwOgATvrYAIggNeAABtgAhIA10AAG2ACU4DXAAAbYAIghJSgAjAb62AAQRAAA+AAG2AAQRAAS2AAQQAAhGACJPSf0BIwHELwIEEQAFRgAEEQAERgAEEAAERgAA/ABAaUkAAMgaUAHDARYGAAEEEQBADSEJCAQBBBAAAAgBEwABAIauAQAABABLBZUNYogzAAAMKpUNIthJ+AYClQ0F1RoKxRwLuBwAuw0Fyx4wBKUFFAALgQsA9gxQBHMqAAAJAFADGAEAAuQHUAQkEgAACQAQBRIAEB/rG0C5IgAACQBgBiMBAALpGwAEkgABmB5AQAwAABYAQAEcBjWRHbBJAAAVAAAAASESBlEMUFJKAABLEAChMRAGVgAAALxKAKUGQAEqDQcgAJBQDQAAAT0QBotRAUBLAABPHAAhOhgQACOrSzwAITgZTAAjJEwQABJNMAAUhRAAIUoZEAAj4kxAAIBIGAidAAAAaFwAIVYSux4x900A8wFBBj0NAC0AI0pOPQAhWw9dABSbEAAhWA4gACPnTk0AIVkOqQAQgE0AEFpXDxQAeh0QyQQBA7IBccouAAD7LgCyASORT1cJBXMBMwNUBCYBMUcBAUUBFAQlAASlDwAVADEBTwF6HQAcAAAeAhQBeh0QJzIANgAcBnAAYqExAACfL3AAIpxPSAcPIgIYB5wAAg8CEPRiAECgCwAACQAQA38REBH9AUHzBgAACQBQBgEAAhgJAEB6GwAACQAQBQgfMgWJDiAAAdgAAAkAFAaNAATYAAAVAAD/ISKYAKkAIhcA2AAnCHgRADEGGwETIgAQABATXAEwBxAJTgIAEAAAJQEiAwcHIiKuT8YBowMKBQAJigAAALIRACAEB5YJAAEAELLJACcArysBYnY1AAA8MSsBX7ZPAACoTQM/ADIDBTsDAU0DAFYDBV8DD00DBBDdGwAEkgABTQNARBEAABYAA00DZtdPAAAZAE0DIzRQlAISLU0DUJFQAAAPEAAhKg20AiPBUMQCITcUEAAjGVEQABI1EAAUhRAAEkIQABTdEAAwQBQHMQMQmOQCEkwxAyLuUloBBTEDI0FTLQAhUQ6NACONU40AME4OCCAAELA9ABJPHAAjKlQsABJQXQMUlhAAITMVEAAiAlXcEiABPgwFAAEAUZ4CDy5kBCaxcHVidHlwZXMOAABDCjAAAMkFABIA1BIRAg4AEHAPAAUSAFA5AQAA7g8ABRIAUCcCAACWvgAFEgAsvQM2AFAtBAAA/Q8ABRIALCoFJAAsmgV+AFBjBgAAqbEGBRIAUAwTAABRDwAFEgBgXRMAAJUNEAAEEgAi8iCZAgABAAISACykImwAWRQjAAArJABAPyQAAFERAQEAM9YbDSEBYHJhbmdlcxQAYlcAAABdAA0gAK0BFAstAAMBAA8gAAlI/v///wQAABQAAAEAAAwACAQAABQAAAEAAAwACAQAABQAAAEAAAwACAQAABQAAAEAAAwADwQACQAkAAABAAAMAA8EAAkAJAAAAQAADAAPBAAJACQAAAEAAAwADwQACQAkAAABAAAMAA8EAAkAJAAAAQAADAAPBAAJACQAAAEAAAwADwQACQAkAAABAAAMAA8EAAkAJAAAAQAADAAPBAAJACQAAAEAAAwADwQACQAkAAABAAAMAA8EAAkAJAAAAQAADAAPBAAJACQAAAEAAAwADwQACQAkAAABAAAMAA8EAAkAJAAAAQAADAAPBAABABwAAAEAAAwADwQAAQAcAAABAAAMAA8EAAkAJAAAAQAADAAPBAAJACQAAAEAAAwADwQAAQAcAAABAAAMAA8EAAEAHAAAAQAADAAPBAAJACQAAAEAAAwADwQACQAkAAABAAAMAA8EAAEAHAAAAQAADAAPBAABABwAAAEAAAwACAQAbss3AACAOBgADwQATQCMAAABAPIGQgIAAHECAACcAgAAowIAAKoCAAC88AUBAQAPIAAN1CgEAAAvBAAAKwUAAEP9Bw8YACDwBrUGAAC9BgAAMAcAADcHAAB0BwAAgNYSAwEADyAADdBJCAAATggAAGoIAACC2goDAQAPGAAdwPMIAAD6CAAAHwkAAOUqUIEJAACqBQoDAQAPIAAN8gt8DAAAgAwAAL0MAADJDAAA+QwAAP8MAAApDTINBAEADygAPQAgABO+IAAT+iAAFyogAFOHDAAAk0QAU9cMAADtLAAATAAfDCgAcAAkABOhJAAQ5a0OTw0AABsgAFjfXw0AAHoNAADPDQAA3RgAKPAeAw4AAAsOAAAyDgAATA4AAGwOAAByDgAAhA4AAIoOAACcDgAAog4AALAOAAC4YAgDAQAPOABdADAAEzMwABNtMAAThTAAE50wABexMABiFg4AACYOZABiXA4AAGAOPAAAbABTdA4AAHhEAAB0AGKMDgAAkA5MAAB8AB+kSADQ8B4uDwAANg8AAF0PAAB3DwAAlw8AAJ0PAACvDwAAtQ8AAMcPAADNDwAA2w8AAOMtDAMBAA84AF0AMAATXjAAE5gwABOwMAATyDAAF9wwAGJBDwAAUQ9kAGKHDwAAiw88AABsAFOfDwAAo0QAAHQAYrcPAAC7D0wAAHwAH89IANDQABAAAAcQAABHEAAAXIcSBAEADxgAHN8LEAAAGRAAABoQAAAfGABAAGwAn18QAACfEAAAvhgAKN9jEAAAcRAAAHIQAAB3GABA1xUBAAAaAQAAHwEAAGEoDdJeAwAAQQQAAEIEAABdmDQBAQDXXwUAAGQFAABpBQAAqVAI0XcCAABaAwAAWwMAAHYDEQIBANcnBAAALAQAADEEAABzSAA0ALsO2Q3wEGFiYnJldgERASUOEwUDDhAXGw60QhkRARIGAAACOQFyBfUBAy4Abg4DDjoLOwsgCwAABA8AMAU/GREAMAUuATAAJEAYFQBwAAAGHQExExUAUFgLWQVXQygHEQAQCxEAOggdABEAFglXAABVAB8AkwAUA4QAHgSEABcFYgABhAAPUwAWAlEABA8AAfUAFQUPAANxAB4GcQAB5AAkVRdvABUIDwAC4AAHjwABEQAPjwArA34ABBUAAHMBC2AAAY8ACBEAAZEAAxEAAaIACJMAAREAD5MAFgIEAQ91AUADUQADFQAA6gAHUQABxgAPUQAWD6QAPwF7AQaKAQNiAAWMAQQVAACMAQtqAQ+MAQAGhAABEQAP/wIPL1UXkwAHA4IAAxUAAYQAHAVzAAghAgOVAAYRAAEiAAEhAgiyAgZCAAExADAKLgAPAApoABALRgABNQABJAAVDJsAD8gABRkSWwEAEAAIOwEPMQAOCF4ABowBAQgBBYoBBBUAAPUABsQAAdUACIoBAbEACIoBAREAAfcABtEAFQoPAAFAAAzvAAAPAAM+AAEgAA/AAD4LYAABtQEBgAABDwALswEPfgAWArsCBTkCBBUAADcCBnEAAeIAD1MAFgJRAAQPAAPRAAQPAANxAA82BQUAFQAEcQAB0wADEQAB1QAIpwQBEQAPkwArA4IABBUAD2QBAglVAQEiAgYPAFMAAJFsCz4HUGxpbmVldhewADIBAAABAQH7Dg0HAADMBwARAPA5L2NhcmdvL3JlZ2lzdHJ5L3NyYy9naXRodWIuY29tLTFlY2M2Mjk5ZGI5ZWM4MjMvY29tcGlsZXJfYnVpbHRpbnMtMC4xLjcwOQAfAE0AOYEvLi4vbGlibQwA8CVtYXRoAC9ydXN0Yy9lNzU3NWY5NjcwZjNjODM3ZGVmM2QxODZhZTA5MzY2Yzc1Yzc2MzJlPgCRcmFyeS9jb3JlRgDgbnVtAABtYWNyb3MucnP/AFBmbWluZgwAYAIAAGYzMgoAEAMjACB0aAsAACQB8B4ABQIcMgAAA84CAQQCBQkKA7x9IAQDA7ADugQCA9B8WAQBBQ4DxgIgAgEAAQF4LxEEMigPaQFMCsYAC7AAFjGwAGEBCgP9fSCkADGFAoKkABA6cRkgADGTAA+kAEsPrwEyD5IAOQ5SAgpHAQMBAmECAABsb2cWAg4MAhY9XAHxKhIKA/QDWAQDBQgD3HkIIAYDYTwFDwYDK4IGA1U8BgMtCDwGA1NYBQwGAyGsBgNfPAUaBgMiWAUUBjQCgAYDrwIgBgOvTgIAJADAJFgGA1w8BQkGAyl0XQDwCQOaBiAGA715ggQDBQUGAzKCBQtZBQUGIDoA0Qw8BS+DBQoDdIIFBQYuAEAGA70GSQD0Gg0DxnlmBRYDCZ4FEQN4ngUNBiAFEAbABQ0pdQUZ2AUSBmYFDiAFGQadCwBgDQYiBQkjWQAyA0CQmAAS0ZgAgjwEAwUUBgMlPgIxrAKsPgIQXR46AUUaDz4CSw6sAQ9PAjMPRQAtP3B0ckUAL6FzbGljZQAAZXhwZgIJewIwbW9kCgDDAwAAY29uc3RfcHRyEABSc2NhbGKuBAAyIUBuZGV4DAAASTsCNAABPw2DBQJLMwAAAyGiAvIDoQbyBAEFEAPjeXQFBQigBQiTngJxxQCCBgO7f7ICENEMADCvfzyHAvEZLQisBgNTPAUCBgPlAC4GA5t/IAUXBgMndAUMAwogBgNPLgMxggNPPBUA8QlYBQwDECAGA0kuBRkGAzl0BAMFCQPwCmZyAHGRdQhKBgNGAQPwAMcAkAYDuX88BREGA8sASpcC0gO1f3QGAzSCBQIDMSBoAGEVBgPYAJ5FADHRCkpFAHOwdcgFAgMMIQCwEgYDyQCCBAQD/gJEA/APIAOCfYIFEQY8BQ2CA7d/CJADyQAgA7d/ggPJAAgSEgAQPDMA8AHNACC7BQkGIAafIQYDsH9Y5ALxI90AIAUcCD0FFgZmBREgBQ0gBRMGIQUbBoIFEzwFEkoFDWYFCAY9BgOgf1gEBQazBgN5KgFREVgGA2+lA4ASdAUMhAYDbA0A8RsIKJ8FDGcGA3Y8BQ0GAwy6BRCtBQ2qBgN1WAYDFYIFEMoGA2mCBRgGAxysA/IDA9UGggQFBQUDq3kgBgNkPAQBbgFPIAIDAEMGdSWuNecEQwEKA8xDBhO2QwYRk0MGEN+WAA+kAEovLy4FBEJUAGZtb2RIAwZ6A1Z1aW50XxUBAVUZIAUCn0AQFrcB8AUKA74GPAQBBQgDynnkBAIFCQOuA+oC8BEIA9J8WAYDcy4DDQgSA3M8BgMRSgYDb4IGAxqsBgNmgi4CgRueBQ9ZBgNkIQLwBh2edQUPVgURlQUJBjwFCAZCBgNZZiYAoCOCZwUIPwYDWVgOAPAJMIJnBgNPWAUQBgMOIAUCA8sAngYDp38gUANgEpAFAgPHtwMAEQBRCQYDKKxhABFXYQARKmEAAQ4AQBEGAy5cAJI8A1I8BQsGAzUlBvAAlQmsBAEFDAPtdsgGA0k8ZABROEoGA0h5AOA9WHYFCwN2IAYDS7oEA1EAIMoJAAJQCAP5dghqBgIqBIDEAEoGA7x/WFcAEMqLADC2fzwxBoXFANYFAgMUIJwAwMwAdAULnAUJdQULVyYAkEoFCAYD0AAISo4DAaMAMdQASqQAMax/WI4EMAUQWbEDQAOufzz8BjDWACCBASEDmzoHMAID6DgDAF0AnxgGAzmCBQIDIH4JeS+oNzsDAxGepAAfZYsL/wkhYXiVAw+LCwkA5EIDXQEfCYsLCyBAD2kBEKBYAQ9pAZgvbWWkCDAAXAEPRQAuAOkICqEBQWltcGwMAA4sBQCpASR1dKwIGwS8CAaiCBACuAgLOQAA1wEADTkhA4vXAaAICgPYfqwGA5x/gQoBfQTwCKwEAgUhA513WAQEBRID7AIgBAIFDwPNdgUgYHQ2CIAhggUNBpAEBe4HcKYDdAQEAwxqBwAkAPICIAUJA8sAkAUXrgUABgOTfyAmAPAJxwNYBAIFIAOnfcgFDCEGA5F/PAUPBgPI1ATxEbh/PAPIAAhKBR0GxHwFHI4FMloFHQZYBQ0GJQUPA3d0hgAiiwNiAOH1fCAFDAMnkAUPA75/ZjsJQBsGAy7jCBCQKQBRBgOlA3SkC0EPBgPajwAwyQDIhQCDA9ECPAYDuXwcACUgIM4AEXQ9AAGoAAzOAJAEAQUKA+4BkAIrCAg5AfIAAwUNCgO+BzwEBgUMA9h2YgA0pQNYPgCiCAP2fcgGA7d+PJYAItMDVgGi+X2QBAcFDQO+B1YBlPh3WAYD/n4IEicA8whmBAIFFQOyfSAFDQZ0BQ8GcQUJA84AulEBJa5+UQERulEBMYx+rFEBMKx+PNYAsqoBSgYD1n48A6oBUQFBBgPafkIBBFwApB0D230gBRxyBURmAfAAJgUPA3Z0BQwDKroFDwO7VgE48X7INAA2GwO/kAAB8gAgk39/ADAIA8IlBw87AuIRWM4ADzsCCMAD7wCQBQkDzABmBQ8+BwDnAYZYA4IBCC4D/hYCAF8BCe8BAXICNIwBunICEMuCBQByAvgAAgUPCgNxrAUIBiADg34ucgFCHAO2eHIBItMBcgFwkn5YBgObfp8AQQPmAUocADPtAcgcAADbABAeaQEBGAATzjQAEKQHBDCJfjw0ADH4AdYcABPbNAARpDQAYRHIBgP4fX8BIOUBJAwEYQARdC0AB2EAAcYAHik3AxAGxQChq350BRV1kQUQdbAM8AEPBgM3SgUQCFsFGC8GA0V0PABCBgOOAqALCj4AQwkKA7leAEDJAboCeQYEIQAR4CEA8AUPCgPufTwGA7F/dAPPAEoDsX8ILgkAAqQBoPgCdAQGBTEDiX25ABK6FQAV9xUAADkCAyoADxUAEZAGkQUPHgUxCJEFAkEFDwZzmABPlAIISpkACwCDCWDNAEoFD5IPAFAIggPPAKEMAaAAE6xhAA+gADEAkwBgBQ2SBQ8eaACfugPPAGYFMQbJrgD/bvAHDAoD+n08BRMDCqwGA5t/WAPlAEoDm6gCFOWoAhHibQBANQOffdEAA6wAFeEVADRYBRGXAA8VABFUBpEFEx5rAPAUdAU1BtcFEQaQBRMGcwUMA3YISgUTMQYDon9YA94ASgOif+QIAAJJADHpAp5JABGZiABgggZzBRNzKwAf1iMAAUG6BREGLwUzBgPngQASmYEADxUAAmAFNTwFEXRTABEfLgE/hQJmLQEAmREKA/l9dAUMPTABEIIwARCCCQACWwAR4twBAPEAAKgADzABLQEaAScRkjUBb8gFNQbJBTUBDVNmBTUG9CYAR3IFEdctAVJmA6J/8m0AMccDZm0AAwcBAhUACxwBDxUAAgIxAQVcAA82Af//d/AFDwoDoH48BgP/fnQDgQFKA/9+CC4JAHAFDQZ1AloTIwdhDQgvBQ/HRAA/4gHWRAALAMEFIPQAigogDZARACMIgk0AdAghBQ8CUxF1Bb//froDgQFmBQ0GS1wAHB/WXAA8EFgxAANcAC8IPF0ABB9UXQAREYtREQAgOx8BRA9LCmkOABIO8QCBOAAAA5MCAQURCiEFDruPABFBpkUvCAOPAE0P7xBAP3B0ckUALz9pdGVGAC8PQQAuTy9vcHNFAC8fbqQQMQJIGQ9HAC4AWAHyCy9hZGFwdGVycwAAcmVtX3BpbzJfbGFyZ2UulAIJ0RBiAgAAcmFuHABgAwAAY21wCgAA5xAfdSQAAkEFAABzvRkADQBgAQAAZjY0CgBxBgAAZmxvby8AHQFUERAGLBED5BkVB0IREAegABB2CgASCCkDEJEpA8HhAQEFHQoDEALxAwErFTLVAQgPE/EBrn6ClAUNAwogBRcDd5AFEnIW4JEFETUFF6gEAwUMA/AFLQ1QNAOGAwg2D/ECEQP+fPIEAQUYA5N6rAYD+31/DVCIAtYGWGsNAp0FINMDFQ0xCQOy9w1ADAPpBTscsQkDnHp0BAYDkgJ0FgCA0gOeBgOSeIKRAAD7BfIAAiQBBAEFEwPKfi4FJAY8FwAgtgE7ABEeFQAQE8oZAKEWYAwGA90FPHYPIJJ4CRAj7gfsBiDley4AYAkDwH66BGMAMtsFWCYAEpAmAAAwADAD7geRDdAXBgOQegguBRIGAioShxYyHgJxHAFAqwECLIoAUQ0D1H7yRwBwgAZYBgPld9UA8AcSBgOdAgiCBgPjfQIqAQOdAiAD432CFADwEC4FDQhYBSgGuwUjBiAFDboD4n0IyAOeAiAD4n2CA54hAEEXBgi7YwAgqAGDAEARA9h+gx0AWAFgDAYD/AWQZgDwCDwDmwjkBAcFCAYD7ndmBQ8DCp4GA21KowCgCgggBQzKBgN0yA4AIRa6DQAgaKxdG4AgggUYBiAECKEAoOEGSgQHBQUDn3lmALMaA4UC1gQJBR0D62wWQJUCngXwGkC7BgPapACQpgIgA9p9ggOmpABQDgYIWQV5GMAMBggiBRNQBgPRfUpiADGwAkq8ABCXvAAhA+m6AFBYA9B9WGcXIKsC9RAwEgOcHQBBBRED5B8AUHQFIAZ2JwBgBmdyBgPUrAjyBwYDtQJYBgPLfVgFEwYDsQLyBgPPfUoBAaDtBFgGA5N7ggQBKBjAvAKsBgPEfQg8A7wCgQDwAwgtBgPFfQh0BAoFFgYD0AMCJaUBgBkD6350BRTlKwAQkIoAZr0CdAYDw1MAEAgSAlEUA899uqEAIIsB+AKAGQP0froFFNc2ABhmNgAA6hiQxQIIWAYDu3106x4xAkMB7R4ALwew0gKQBRSDBgOtfaxcAPAC2gLWBgOmfTwFHAYD3AKCBAZ5AhEBoAJAA/8DPMwBEC50AADcApBKBAEFFgOWf/KPHAAiADIGA76cAiDld8ICUJsIngQBfQDwBMR6dAUPAxxYBgOFfQhKA/sC8qwXAHBkngYDoX2etgKh4gJmBjysBRoGzHIAMLYBdFAAMAPSA9kAUBsD+nouDAOxA+sAyAQBBTADlX+FADAD3wC/ApAmA6F/ggUVBjzUAzAGA4xlGTGMdQi9AQCoALS6BAEFHwOkfy4FMIIDINwAQgERKhUAUR8GPAUZ4gA/BgODggMIQBUDmn+CA4ARA4UFWAUMcCcAsJAD7gesA5J41gQBPAEAcQQQJ1wU8AMIA4h9ggYDdzwFDwYDE1gGA200HTEDFqxBHRFoDQChCghYZwUMgwYDdG8E8AIOPAUQyQUN4gYDc1gGAxm6BUMdIGWCpgIvILoIAwWRDAPiAroGA/589R0ggwPlASD9fMUDcIMDIAP9fIIUAALFA1IgBrsFG8UDs/x8CMgDhAMgA/x84gAg0wNOABANrg+ArAi7BgP7fDzGAGUGAwkCdQHIABTyyABlCwhmBQxnugDxAFgFEK0GA3EIEgUMBgMYguEAsRAGAxsI5AYDZQguwwAPywMEAOYBMPsHrDMCAwULAGgFMAIDdLUB0BsDSdYFGgY8BQkgBuXdAUED4weQggGAq30gBgPhdzxxACGbCKUUMQO4ezkAGtY5AAAbAFEGA8MASkAAIqEHwgEhq30ZADADtHthAlAJA75/yBkCIAM2BwEIPgABUgIg5AehHwI2AAAuAHDyetYGA+98KxSQA5gDLgYD6HwIywBgEQYDnwi6mQAB+gKAEwYDmQPWBSFhDICCBQ0gBQ8GOywAQ3QDmAPtADE7CGZSABBJlwCADAP/BJAFEUBBAAGNA1CbCAImARsBBU8GAMIcMhcDZHIDAZwAJckHEgEwBQyMLQBDWAObCDEAOKx7PDEAARQAERzVACcDrQoBAPoAEagKAU8XA2QuKwBIDLIAAOoAAMID8AccBgOvAy4FDQaeBRIGPQUNBmYD0Hy6QgAA9QAAaAQyFwNrxAABpwMqvASnAwAKAAJHABK0RwBCA8x8WCsAMZsICLYEAxIBBEMBEl1OAAGRABbQkQAPQwEHAzEAARQAHyPtAAsSXe0ADysAQwyyAAdDAROm/AAW2vwAELrOAAAOFwH7AABJAUAdA3LWEABAAw4gBlkAkBYGA3IgBSYGdAgSQD4FH1fQDgI/ADDhBII/AAC8BwEJBkAGA4F8CQMACgYQIBoAAYUFBlkAEndZABUJWQAfd1kABBbcWQAD5QEgrHuACSEX7+MAASQANtcEdCQAMAEFAJYBAFUEoMYDggURZ3YFHXMNEzADuHx5B2EDIIQFHoERAPEBtHxKBQIGA9YDIAUF8QUCIUUNIOsERQ0QRTQND0UNnQ80DDIAig0jAHP2KQCMCyAzMgoAVwIAAGtfFwADbwsQAxcANGNvcxcABBwMBBAAAIILAPhFgAMbAQUPCgitwwEhA6b1AfAGBQPgeQhKBQiSBgNbPAYDM4IGA008fwURgkMhEgbpIGA9BgOuf5DmAfACJ6wEAwUNA3I8W1YFIHcFErjBAuAFIAYiBRUG1gUPngULIP8nQAU8A2MpBRAc6CEA+gMgVggtA6AJBgOpCzwGA9d0XwmBDAYDNawGA0t8BnAiCFgFGgMblgUwDQNcoAIwGgMkFwNvDQNfWB4FbAAQAEUAcHQDFSAGA0kkCFADOqwEBT4A8QsgBQ71BQcGngUNBh4FGPQFBgYgBSIgBRIG8VAAkCIGIQUFBiADZEQAQCAGAzidEj8NA2E3ABMAhQxQBgMcLgaXImIMBgPFAKyyJgCOAAHTABIr0wBcTEp3OgXGABfyxgAYIMYAcCUgBgO5fy6QACLKAMgAH0+RABlwLi4GA7Z/WAcBIsgA0QAfUUAAEwAIARAGuAGQJ1gFCOgGA1U8FwfxKS6sCEEFEbsGA0wIyAM0IANMggM0CBIFIwIlEgUdIAUyugUdIANMWAUPBgM8kAUOBkoFIQZZBRwGEgXwAQYDtAYgBAYFBQPMeSAFDYPmACEDZKMEwAgDHSAFCTEGA75/kI4H8ADAADwFFgZYBRVYA0A8BAG2I4DXAMgGA6l/dMUAPwYDGcYAE8EEAQUOBgM/LgYDpX9FAgA6AA+BAREPZQAZACsBA1sAAW4KIcEAawAvA0KwAg8A4AIgAgbhJz8CDgAUJHWgkU8AAAPOAgEEAhQkEf08CRUOki0RmRQkEFCTAA+kAEsPPQUuAYIFD5IAOA4lBgpHAQadBXJjb3B5c2lnoAWEAwAAcm91bmQNAFR0cnVuYw0AAEcAAAsAAEIBRgAFApx7AVASCgP0AzQEZQsDxnmQBTstIOgGQgVADAOWeQoLIR0/nQETx0gkH8UwB/EHAgcGkwEJGQcIMAcHRwcPMAcBELaSAQ8wBwQVgjAH8AAvggYDUTwGAzqCBgNGPAbuKAEuBxu4LgcPUAQWEAF8DSAqniwHQAP/CkorBxLkKwdSMZAGA09YBvABZgUTAxIgBgNMLgUbBgM3kLYEPwNiPOAEERABMgASNRIGL2QgMgATEAzVBTYGA0R9AFEdIAYDQX0AE8KeBh9XTAAUYRsGA8AAnjMAH1mxABIvBgWMBngQzYwGJbN/jAYPwQAREgMrAA8CAhYDWwABUgYgNlgPAC8DTVEGDw9oABsAPARgBgM0LgYDai4A1gFgCGYFHwMRdwRPDQNmSkUAFYUUBgMXLgYDTUQAEB5YDgBEAB9bRAATIwNkCgcT0woHYQDncAouZBQ2wnN0cntpbXBsIzh9AAkAJDM1CgAGCQAUNAoAJDEzCgAFCQAkMTIKAAUJACUxMQoABAkAoTB9AG1lbWNweQDKFnAAcmV2AGx0FADyAXNldAB0b19iaXRzAGZyb20KAAWEF01vcHMALQUCgSiXAHNldF9ieXRlCgACBgABJAaIX2ZvcndhcmQTAEdiYWNrFAAGNwBDd29yZCQABDcAqG1pc2FsaWduZWQeAAVCAA8fAAMEPQAPGwAABToAChwAAykYFQBXGAIKGCAAaeMZgG1lbWNtcABiBQARczgYgABpc19uYW4A0gUAIyoAKQYB6QbSAHdyYXBwaW5nX25lZ0MrEgCYBQFeMgONBQLnNgGRAAFEBwNWACBmAOg0cgBmbW9kZgBRBwNLBwa4BQBvAPUJbW92ZQBSYW5nZUluY2x1c2l2ZQBjb3JlJgAgX2wqGSAAciMAUABzbGljIAAGGAECDQAECgETABYAtV91bmNoZWNrZWQACgBGX2FkZNMAnXN1YgBfWk4xNwsCUTNtZW01DwIhMTJdAANUACgyNg4ACnQB8AUxN2hmN2YzMzlhYTQ1OGViNmZmRV8AEDTLALAzZjMyMjFfJExUJFcA0iR1MjAkZjMyJEdUJDZ8AfIDMTdoNzgwODVkYjc4OWUwM2JlPwAfMZ4AChEzkAAE+wApMzAPAA1OAgCjAO8wNDA1NDA1ZmMyOWJkOGQACpA0MF9fbGx2bV8xAvADcHlfZWxlbWVudF91bm9yZGVyTwHyCnRvbWljXzExN2g5NWJmMWY2ODNhZmViYjRZAAL8AFJwdHI3bZECGzMEAXEkQlAkbXV0DAARVA4B8glvZmZzZXQxN2hjYjU4OTBkYjRjMDY0MDNRAB4xqgBgNG1hdGg0hwL/AzE3aDI5ZDYzZGYxZTkwNjNiMjUABgDfADEzMW0pBA/YAAYALwHfODE4Y2IzNzdhMjc4OVAACw+TAQL/AzE3aGRmZDQ2MDY1ZjBlYWNkMEQACiY0MXMBABcDD5wABgF0AeNiOTkxZTIzMTVhZGQ4OFoAAXQBETUmAysyOW4BoHU1YiRUJHU1ZCRsAUAxN2dlWgAiY2gdAyBtdXgB9gFmMjQzNDJmN2JlY2NlZmJlVQAAyQEVOVIEKzMzXQAxQlAkHQABDgABzQEwM2FkAQHxAWZlMzE2MGEwYzQwYWE2ZGRSAB4xAQECygFQbGlibTQ5BAEFAADUAeM0ODQ1Yjc5YWFmNjliYj8AITA3fwAAmABxLi5vcHMuLh8EKi4uSQQAJAABjAABlgAhYXMHAAI1AE9pdGVyNgAEkEl0ZXJhdG9ySd0AACoBoTRzcGVjX25leHTaAfMDMTdoYTIwOGEwYWFmODJhMGJhlgAP1QAJEjYDBQMHAP8DMTdoMTcwNmJjOGY0NGZiZWM5QwAGABkCLzMyEgINAFEA72Y1MTYxODUwNjZiMWU0UQAGBpQAEDTGBQEFAP8EMTdoNDg2MWU0NDBmYjgxMGRmYz8AChE11wUAdQBgMGY1NWI3OABCZDdlZTYAEjh6AgJpAQ2eAQAbAA+VARcLjAEVOYsBALMA4mMxZjc0YTMxMjc0OWI2fQAPswAAAUMBAPADD8gECQCrAu82YTM5YTBhOGRlZmQwMlAACg+sAxf/BDQxN2gwMzRmZmFlYjNhMzkwOTFaAAYBXQFANGNvc1wB8gA4OGU2OTBiMzExNjc0OTA1AAKMA0tudW0yggNQdXNpemUjASgxMuQGAH0A2Tc1Y2RjMzViZWVmODJIAA+ZBgcVOTkJ9wQxN2hlNTgwZmM0NzJiYmI1MGViQgAPFgQeApQA/wA0MGMwZTZhYTNjNTc3NmRSACoCaATyADAzZmZiYTg5ODNjYTg1YVIAITc1PwACHAEAMgAJbwIBJwUhLi4/CjAuLlMOABBJDAAAMwAaJC4FAAQAKTEzMgXyAzE3aGQ5YjVmZWY0N2U3MmI0OHQAD8YAIwb7BvsAM2RlYmJiMzgxYTM5NTY1VQAPTAcg8gAyMDBmNjk1ZmVlOGExZDNRAB8xfQIFABkEEDnGBgHNCQYKAAAHAu8zNzdiMjUxOTMwZTRhMUkABgAgAwMQBwlBCSgxOA4AAicLALoB7zczYjlkNDRmNDZjYWYwVwAGBqAAAfEHAQUAAIME3zVmZDFjMTQzOTlkZmI/ABERNbIKAgYAAPcD3zE4OTE5MWM5ZTE5NDVBAAwRNQcLALYA8QA2NjNkN2EwYTZiNzhhZWE2AAKnAQ+eAwoVM0ECEl+5AvcBMzAzZDZmMmI3YmJlOGZjYUkAD/ABGQQHA+JiNGEzYjdlODdkMTI0Yk4AHjHNAACkAQjjCQ8LCQkBbwhwNGMzM2MwNjEEQjE5YjlZAA+nACbsZTg3ZWQ4MDZjYzY2MDFOAA86AyTxATg5NGE0Y2Q0MjQyOTU5OGFVAB4x/AAByQEVNooH8gBjYmRiOTljMjEyMzMxYjY3AA+MACMD3gDxATQyODY3MmM5MmE4YWVlNWFSAB4xiQAAhQEP3AcS4zZmMGVlMjFiMmNiMTdiUQABowAP7AkTMDNnZVgAA3kCABQEADIDomU4NDcwNGFiYTJRAB8xogAo8QFiOGI0ZDVjYzk0YjliY2Y5UQABogAPZQYIEzemDwCRAOIwZGQwNzg5NzU0ODYwZEAAHzGRAAMDXAQgM2NOBACSCQBPBCkyNw8ADZ8N8gBjNDZhMDJiMzA4YTU3ZGNhAAGhAGE0aXRlcjV2CDoxMTCpAAAgABMumAhidHJhaXRzDgAAlAgkLi6eCAErABNmCAACMwAcb/cIBV8KAGAAEEH+AAAEABM0ywgwNmQy+QBzYWUzMzM4Yp4AHjH/AAG7AgHFBAEmCAEFAAD2A+82M2ZlMThlYjUxOWMzYj8ABgA+AQ/2AxYQOJ0E4jg3YTMxMzMyMjdmNDdhWQABNgEfM+YECgaECDBuZWfeDuI3ZWI0NDc4NThkN2Q0MUgAHjGhAAbgADA2a1/dAAMHAADBAfEAMWIxMjQ2OWI5ZWI5OWY4QwACiwAPgQQZBi8E+ABiNTI1YjM2NWQxYjYwZGVRAD1mNjSzAiA2ND8AChgJ4mUzYTlmOWNlNTBjYzlkQgAeMdYAAHcBA7UCChEHMDdoOJkJMGNhNowDMmRlNkMAAYUAD9oDJLA3NzZhZDU1NmVhMZIDAlEAHzGUAAMP2gMS/wAxYWEzNDIwYmFlZDRlYTNRAAYGuwECJAcCBgAAuQHfZjI5ZWU0OTQyYWZmM0EABwCSAA9XCxcQOFoA4jM5MTE4Nzc4NDY3YjQxWgABPQFCM2NtcHIBEjUrDgAMAAFBAQAeAPECLi5jbXAuLlBhcnRpYWxPcmQaAATBAwXGAiAybCcC8gA5M2FhNTYyOThjYTljYTBlAB8xvwADEze3AAAcAvEAYTAwMTQyYmRhYjVlY2Q3NwACnAAPrwIZA1IG8gAxNzZjMDUwMWFjNDc4NmNOAB4xhQABhQEG2gjiMzBjNWE0MWY4ZDc1Y2E2ABI0UgIC5gAAaAAJFAsRaesEA7kEQFN0ZXCFACMxN7ECGF9qAuRhZGY4Zjk5MDhiNGUyNl4AAEcAAOIADzgHIu9hMjc5Y2M3Y2Y5NWQ3NlIAKQbnA+g3ZWEzMGVhNzg0NGY2NVUAD2IDJPIAYjVhNmNmYzZjNWVjZmYyUQAeMYwBABECITZtbxUA3ADTNzg3NjI1NDk0MGZkZDYAAYcAANwADxACFwJADfIAZjhmOGIzZjg0MTM1YzExTgAfMYQAAwIIAxA57AUEcwvxATlhM2I0MmYwYmU2MzhmZTY/AA8tDUzxAWVkNDg5YTc3MmIxMzIyYzZ0AAUBAQ/dARoDLwJwZmY4YjFiZY4MSDZmZGJSADJvcHPSBy4yNX4HMElkeEYAkDhpc19lbXB0eX8I8QBhNTY4MzM5ZjlkY2JlOTZLAB4xUAEBYAMD5QQAVBcCBgAAFQKAODM3Njc4MDQpBRM5QQACjAAP3gAdBrsC8gA0ZDU0MmQ4MjA0M2QyOTdVAA/9ElsYOXER8QE2OTEyNDIyNjM0ZjZhZGY1kAAF5QAPxAId8gBjMzJhNDgwNDFiOTQ0ZGVOAB4xdAEGxAIaMfMJETGeDgUPAAXeAv8AN2Q1ZTE5ZjQ0MzZiOWRiWQAKARgSABsDD2kGBQD3APEAODAyOGU1ODY0OWY2ZWE1UAAB9wAPQgQkUDU0NmRmkQ9nZmMyODMzUQAfM1YJABFpkQMASQAGVgkCQgHxAWE1MjhmOWFhNjlmOWMyZjRIAB4x6QAGtgISNoMZAwcAAGMC3zczNGFkMDhmMDE1YzFDAAcALAEChQEHSQQVNQsABWcLgDRkZjdiOWM38gcyOGNlUAAP2wAaAjEKkGVhOTU3ZWQ1ZGQPEzNIAB8xmAADAcQBD9wTDPIAOTRmMTFhMzNiNTc1ODBjUAACmAAPoAMdA34E8QEzZjNkODcyMGRhYWM4MDc0UgAfMaIAAw86AQkBBgAAOgHiN2M4MmQzMmQ5ZTJhYzNQAAWiAOAxM3JlYWRfdm9sYXRpbGEI7GRkZjA1MDA0N2U0OWJiMAAPjQMXAs4A8QE0YzJkNTI4OGQzZWU4YmUzTgAfNxIGOhk3BwMwX211UwTyADc5MTE0ZmEwNWI4ZjBlY3gAHjFGAQbDAioxNBocDRAA/wI3aDA1ZWFkNjk4YzZmOGQ5N1UABgCbAQgPDQ9EAgkwXzQxdAHSMTAxNmQ5ZGNhMWMzNlkABXQBD0YCIYA3MjExMTcwMTcGHzBSACsGOAbyADkyMjEwZWFiYjMzMTkyNVUAHzEAAQMBPQMAjgIP+QAFAI0D4mY5NGUxOWRhMDU3NjkxUAAPpQAuAHkQojFkZDg5MTE0ZDBVAB8xpQAID54BCQBKAf8AODI3M2UyZjRmMTk1ZTgyUAAJAZcJEHD5B/IAMDY1MTM2YzEwMzZmYjk3NgAP2wAjA9IB/wA2YjBkNGZmNzM5MTZmNzZSACkGLQHjZWRlYTE3NTE1NWJjMTVVACE5OEIAAFsAEy7UBwTlIKAuLnJldi4uUmV2IgAQSU0AAVcACcEDAjMAL3Ry1xAGB6EQUGUxYWRjUhRiN2ZmM2Q1gQAfMV4BBwK3AP8ANzU3MzIzZjI1NWJlMjkyNgAGBt4DEzc+IAQIAP8CMTdoZjQwMjBlYTAzNDQ3NjZFAAcAewAPzgMWETI/B981OTZiOTExMjUyNGIwWQAGBp4AFDlrBBZmCgD/BDE3aGI5NTFmOGMwZmZhYWQxYzFJAAwC2hz/AGM2ZmI1OWY4ZTU2NmU4YjUABgzXAA+sAwkBpQTyAGUxYzIyNTA1MWRlODY5OVkAAYECD68IEx83qAUB9wBjNDM1NmQ5Y2JkNjZmOThVAAHYBwtmBhJ14BMH1gcgc3WxCOhiMTIwYzNkZTI2NGM2MkYAEDR/AgKzCysxME4AACAAAqACD64CCgArAATEDwIzABxvHQsAVwANfBPyAGFlYjEwZjc4ZDJkMjQ3N5UAHzGJAQMQNZUAC8YREjKHCgMOAC5fbXghQThkM2ZgBG9iMmMzNzZiAAYCIAISZZEd/wBiYjFlYjczMGUwYzc0YzQ1AAYAlwAPNxEXEDJRAzBjZjTDFxA2WgAiOTRaAAGGAQ+iBCjyADY0N2IyMGYyNDdiMzFkMVUAD0EIOxkzmQIAIwHiODRhMDA0ZmUwMzUwYTB0AB8xIwEDAUMGDzwDCQCvBP8AMjA3MmE4NmIyNjY2MGUwUAAJD5MDFgByAfIAOTQyZWIzMjcwZTZlYWNjWQAPHQFM4zc2NGIyMTczN2MxOGM5dAAPzQAFAA8mAJkMoGY5MTc0ZTNlYmSKGw80AAsHAQEPawUKEDgCAzBmY2MpC382ZDc2NGE4WQAKAaoBD1IACQCwD+9kMzc1NzE4OTJlZjE0NlAABgJSAwC7BRE1syACBgAAHgHTY2YyODllOTFhNmQ5M0EAD5IBOw9IBQPiZGVkOTQ2YWI1N2FkMTV4AAV8Aw+2CxYHeAPiZDFiMTUyNDgzODNkYjRRAB8xCgEJEjZbBwMHAAAMAVBmZmQ3ZNYFUmE4YWEyQwABlAAIlgUSMh0BBZQAACAAES6IBQaWBfEAZG91YmxlX2VuZGVkLi5EDgAQRQ0AD6UFGQWMEABvAAWuBRA5rgUB7A8AfA3iM2QxMjNkMzIyNWU3ZjGyAB8x9QAKIGtfMB4DBwAA+QlAMzE0MM8cUGEwMGFkQwAEDxIRPAACJT4A+hAEEQACdAEEDgAFHwABlQAEFgAJ9AEEFQAlYWQLADRzdWILAA8rAAAhLCAHAAscAAA7Ak88ZjY0HgADDxoABwE4AD9pMzIeAAMPGgAIF2YaAADiABA8qgFxOjpvcHM6OqoBKjo6qgECvgAWPiMBEzj1ACA4PuQpD80DCQQkAA9EBQkEJAAP2wYKASUAAV8BFjiIACMxNokAAAkAH22KAA0DJQAPiwALAyUAD4wADAAmAASFACM2NIUAAAkAH22FAA0DJQAPhQALAyUAD4UADAAmAAnaAQESAhBmFwADnAABDAAJIwACEwAArwABCQADKAAydTMyFQABCQAfbcQADQMlAA/EAAsDJQAPxAAMACYACaEAAcQAEGkXAAOcAAEMAAkjAAITAACvAAEJAAMoABBmDAAJRhECEwAKOwABEwAAOwABCQAfL4UzOY5saWIucnMvQCYA/wEuNTk2ZTM4NjYtY2d1LjY5eABjXzIyOQBf1AcUBykAL3Nl5gEHCSkAD+oBCi9fOPUAYz8xNjd5AGMfNXgAZC8yMnkAZA93AGQnNDaDAg/VAgoXNCkAL3Nl1QIICCkAD9UCC180AGY2NPgAYx8xeABlLzkzeQBkJzczmAEP6gEKFzIpAC9zZeoBCAgpAA/qAQtIMgBmMy4AD4AAChcxKQAPgAAKCCkAD4AACx8xdQFjHzl4AGQvMjR5AGQfMXkAZh8zeQA3D0kANgE5AA/CABbxADEwAGNsYW5nIExMVk0gKD489QogdmVyc2lvbiAxLjYyLjAtbmlnaHRseSAoVjz3AiAyMDIyLTA0LTE0KSkAAPIhtoSAbmFtZXNpAAAzPJAAAADJAAAAWgDvYVBpbmYAJnt2DJMAUAAwAAAAEg5AALgAAPQNUW5hbgCpKgBScmUAKwDkPSAArkYAgDMyALMAAAB79A4wIzB9YgAhADZtAABpAD9wAABjAAQFRgARQh8AIHNmOQAhAHc6ALU5AQAA7gAAADUAAKU4EVInAAxGAAA9AAVuJiQAXLcAEIYJAABbNwJ8AERyZQBXbwAAeAAAtQAA4wAJtQAgIwF7AL8nAgAAlgEAAFYAAAgLARG8UAAMhgAQxm8AAHgACo8ABX0APqwAAEILBT4OBJIAOW0AAIcLFMGzAB+ZPwABVj4AegAAhQtQigAAAHNvEUIA4gAAezgIPgEACYZQcHRyAI/QARBuCzoQ0DEAAd4QMWYAY6kAEm7SFCgApxoBFZQNABIyJwEC3AExvQMA3AEA8QABbQAC7AAMGQEA2wABwwAAAQAAQQIzAgAt34YfeDEAAgCKAAJvAEA4fQBPGQEFTgEUgmUBAmsAMHJlAJEAAV4AAGcAAEIBEIwIAAC9EkEAXgAArDkAegAIYBcJFQEAvQAD3QINDgIgNwCtACIqBecAAnMADK0AAHcAI21hwwICeAAAAQACawMEo4cCawMvYXgjAQUAegAB1wAQuDsAAo4AACoBAeIABWIAD2sDBiCwBm0AtmMGAACpDAAAtwsA7wAxbmVnXgAALwBycwDLCwAAbToTbwA1CAAAbX8HCwJVDi/hBykAEFExNj4AQbIAJHB54hcvAIljABEAPQ81SQwAkhBUrQAAAHP1HzIA/AvgAgMnAwAbBAFjAABLEgFkACVwDDEDAa4AF1YQAACVAAE+AUhlbQC+VwACcRgnAIosAACHAA+dAQMS3cYAD1YICgG6ABAHXgEPqAgLAqQAAOyeDykADgC9AB9AUgARALoAFBZBAQInARFGyQAGigEC9gAQAHmgD8oADwCiACW0AioALwBLNgASAK8AEifYAA8qAAwAsAAnKgzDAiN9DOQBAHoAFGMNAABRAAAdngHIAATvAQPJADftBwDwCQ9gAglEXzIAl1IAAHkAHYhSABtthxpCAHEHAPY9L5UIZgAWPzgAQS0AF0A0AHsLhgBJcmUA6TYADzkBCkJfMQDMzAJvY3B5AFcJOQAXPzIAxS4AGD80AJleARdEMQCFC8oBVDExfQA8bAFIOD4AqogEaHN1YgAzClgAD4YAC0I4AMYLrgYfjX8EEUM4PgBVKABJbXAAoWkADz4DCU9fMQDaLQAXNTIApe4AXzV9ABMLOgAWPzQATC0AF0E4ACQGzABXc2V0AC+kBFI4PgCAC9QGABmnBBcAAvQDAO4GAdoCBPQDCtYCKLIAAAUBBgADTwkHMwANDAMUlCIABS8DCiAAICUMIAAENQgklQq3AA/dAAYBxQAAAQACXAcTDKCOD3oFAwCoBwJQAAXHBQABACDLAzsAv10TAACVDQAAfAEAYxgEEA3pagH4BhzmPQkBHBUBuBUANAkTbRMHK0QBJwAYPPsXAH8HA3MBAS4VMUYCALUQJJ0BFAIAo0MAPAoAOUMUYZkJAGUAE0cNAANKAEVpAgAAZAAA3jY3ALUBxQAEJwA/2wEAp0EASjECAABVGFAACAIAAPgCFcOKAEAzfQB5FQANUwEygwIAaggAWZoJ7AABEwEB2QAgsQL3CjVtX3ArJlgAyAEAAJsAHB0+AAIZAAUsASTLAIoKALCaAPsAAVoAHTc3AAiUGRzapgECVQBgPgBgAQAAQBs0ABIC4QBdNTR9APIwAAFtARVLJQBAMH0An6UBAHssLABRfAAE8QAFgAAU+OUAAJsFD8YZEhEmtwJTcmUAfgKkCUEsAgAANAAlAGSHAAAZBR3+rAABEQEQNqMCC08bIOkBMgECnyQB+AIAmwIk1gFOAFMzNX0AoqoACe8CFfMjAEAxfQAX6AE/dAAq9QACCHUBEFAhAQVgCyDuAfsBRXYAigFMAFUyfQA6APoCAzYAFlQSAAF0AVGNAgAAc0kMQQBfAgCiBABcDAJmDACACgYlBBWwWwADTQwRugoEb/IgAACyAXQNBgAClASUAjFmAGVSAAzcAiNvANwCAYsLBdQABaUBI2oApQEAVQFQZjMyAK+mAgABDwBpBAQRDGGLAAAAa1+NDgCaBACzAAC5TgIQHQHMAAK+AAN8CwILDQQykwB6AAEoAAJ1AAyiAAB5AAGCAAABABGSOgAEWpMRZjEAEnBEPAGWBBF0eywJnAARUiUADFYAAHUABu8AFFwGAQKDAB9y9w4NJKoAyE0AlQADjgFAPyQAAN6TD44BXQF3AQjyAAJ7AQEXAASOAQKhAQFmAQnJAAEBADCqDwTrEPEGAYIPTwAFYWxsb2MBMl9aTjl3ZWVfDwAhMTUHAKBfZmlyc3RfZml02STwBGEzYTA0ODBhYWFhOTNiY0UCiQGfQRE4yR8FOwAgLi79AvAAX2NsYXNzZXMuLlNpemVDDQAQQR4AYVBvbGljebAfAw4hBzkACCIA0EdUJDIybmV3X2NlbGx7B5BfZnJlZV9saXOMAPEGMTc3MWU1MGI5NWNiMDVjN0UDB2RlRgAvBJOVAEvwBTMyc2hvdWxkX21lcmdlX2FkamFjwwcBngAArAAAoiXxDDAyMGI4ZmY5MWVkOGU2ZWVFBQdhZGRfZjMyBgkAQXUzMgcJAIBpMzIIB3N1YhsAEQkJAEF1MzIKCQCAaTMyCwdtdWwbABEMCQBBdTMyDQkAgGkzMg4HZGl2GwARDwkAQXUzMhAJAHFpMzIRB21vbAAREgkAQXUzMhMJAIBpMzIUB21pbhsAERUJAEF1MzIWCQCAaTMyFwdtYXgbABEYCQBBdTMyGQkAoGkzMhoJcHJlbHUdABMbCwCAaTMyHAdhYnMUABEdCQCwaTMyHgpsaW5lYXIVABQfDACAaTMyIAduZWcVABEhCQCAaTMyIgdpbmMSABEjCQBxaTMyJAdkZRIAESUJAFFpMzImCGoAQmYzMicKAFBpMzIoCQoAEDYVABMpCwCQaTMyKghjZWlsFQAhKwnGBgALACEsCa8DAAsAYC0Ic3FydAoANC4JcgsAgS8Lc2lnbW9pIgCAMApzcXVhcmUMABQxDABxaTMyMgdjb+QAYDMIY29zaAoAMjQHc0MBUTUIc2luEwBBNgd0YRMAQjcIdGETAFA4B2V4cAkAIDkHuwBxZjMyOgdsbwUBfDt3X1pONzCgAhBMQggIbAIAhwIPjgIODyMDCP8ENjgwM2Y3N2Q3YTNlYTcyNUU8bnkAOCAxMzgCAXkAAFoD8AcxN2g1MGIzZTM3ZDlkMmM1ZDg1RT2BigMPcQA1D3gDEvQEYWZjYjdhNDEzNDMxMTQ2NUU+UnwkABAl4TQ4ZHJvcF9pbl9wbGFjESQHcQANmAAA5wDwBjdoNzk0MjNlYmQyYTI3Mzg3ZEU/gNgAD2IERw5bAfALN2M4ZWVkMTk5ZGYzZDY5NUVABWZtaW5mQQTzBSBCBMAVL0M+tCQNEDR+FAEFAAChMSo4NqBHIEQEGgAvRUBGAA0RNb4TAgYAAZsAGmb5JiFGBRsAIUcFyhMvSDVQAAMAmScP2C0IIkkGHAAvSlQ/AAMGjwANrzEMEAAPvzEAH0srAQ8AOAcBBQAAbAZINWZkMRJEIEwEGgAwTQZyYQQvZk5OAA8ApgEBBQAAjgAMXD/xPQcSAQAPX19zdGFja19wb2ludGVyCQoBAAcucm9kYXRhAFUJcHJvZHVjZXJzAghsYW5ndWFnZQEEUnVzdAAMcHJvY2Vzc2VkLWJ5AQUDGR8l+xgSAA==")); \ No newline at end of file diff --git a/core/mod.ts b/core/mod.ts new file mode 100644 index 0000000..d875418 --- /dev/null +++ b/core/mod.ts @@ -0,0 +1 @@ +export * from "./neo.ts"; diff --git a/benchmarks/deps.ts b/core/ndarray/mod.ts similarity index 100% rename from benchmarks/deps.ts rename to core/ndarray/mod.ts diff --git a/core/neo.ts b/core/neo.ts new file mode 100644 index 0000000..f3a7fab --- /dev/null +++ b/core/neo.ts @@ -0,0 +1,4 @@ +export class Neo { +} + +export const neo = new Neo(); diff --git a/deno.json b/deno.json new file mode 100644 index 0000000..5d86479 --- /dev/null +++ b/deno.json @@ -0,0 +1,20 @@ +{ + "tasks": { + "check": "deno task check:deno && deno task check:rust", + "check:deno": "deno check --unstable mod.ts", + "check:rust": "cargo check --target wasm32-unknown-unknown --release", + "fmt": "deno task fmt:deno && deno task fmt:rust", + "fmt:deno": "deno fmt --unstable", + "fmt:rust": "cargo fmt", + "lint": "deno task lint:deno && deno task lint:rust", + "lint:deno": "deno lint --unstable", + "lint:rust": "cargo clippy --target wasm32-unknown-unknown --release -- -D clippy::all -A clippy::missing_safety_doc -A clippy::undocumented_unsafe_blocks", + "build": "deno task build:wasm", + "build:wasm": "deno run --allow-run --allow-read --allow-write scripts/build_wasm.ts neo_wasm backend/wasm/wasm.js" + }, + "fmt": { + "files": { + "exclude": ["target/"] + } + } +} diff --git a/deps.ts b/deps.ts index f5a653d..3297d25 100644 --- a/deps.ts +++ b/deps.ts @@ -1,2 +1 @@ -export * from "https://deno.land/x/byte_type/mod.ts"; export { enableValidationErrors } from "https://crux.land/gpu_err@1.0.0"; diff --git a/scripts/build.ts b/scripts/build_wasm.ts similarity index 70% rename from scripts/build.ts rename to scripts/build_wasm.ts index fe7ff6d..35357cc 100644 --- a/scripts/build.ts +++ b/scripts/build_wasm.ts @@ -1,7 +1,8 @@ -import { encode } from "https://deno.land/std@0.128.0/encoding/base64.ts"; +import { encode } from "https://deno.land/std@0.137.0/encoding/base64.ts"; import { compress } from "https://deno.land/x/lz4@v0.1.2/mod.ts"; -const name = "neo"; +const name = Deno.args[0]; +const output = Deno.args[1]; await Deno.run({ cmd: ["cargo", "build", "--release", "--target", "wasm32-unknown-unknown"], @@ -12,8 +13,8 @@ const wasm = await Deno.readFile( ); const encoded = encode(compress(wasm)); const js = `// deno-fmt-ignore-file\n// deno-lint-ignore-file -import { decode } from "https://deno.land/std@0.128.0/encoding/base64.ts"; +import { decode } from "https://deno.land/std@0.137.0/encoding/base64.ts"; import { decompress } from "https://deno.land/x/lz4@v0.1.2/mod.ts"; export const source = decompress(decode("${encoded}"));`; -await Deno.writeTextFile("backend/wasm/wasm.js", js); +await Deno.writeTextFile(output, js); diff --git a/tests/wasm_matmul_test.ts b/tests/wasm_matmul_test.ts deleted file mode 100644 index 1094712..0000000 --- a/tests/wasm_matmul_test.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { WasmBackend } from "../backend/wasm/backend.ts"; -import { WasmData } from "../backend/wasm/data.ts"; -import { matmul } from "../backend/wasm/operators/matmul.ts"; -import { assertEquals } from "./deps.ts"; - -const backend = new WasmBackend(); -await backend.initialize(); - -const uniform = { m: 2, n: 2, k: 2 }; - -const a: WasmData<"f32"> = await WasmData.from( - backend, - new Float32Array(uniform.m * uniform.k).fill(2), -); -const b: WasmData<"f32"> = await WasmData.from( - backend, - new Float32Array(uniform.n * uniform.k).fill(2), -); -const c: WasmData<"f32"> = new WasmData(backend, "f32", uniform.m * uniform.n); - -Deno.test({ - name: "Matrix Multiply", - async fn() { - await matmul(backend, a, b, c, uniform); - const expected = new Float32Array(4).fill(8); - assertEquals(await c.get(), expected); - }, - sanitizeResources: false, -}); diff --git a/util.ts b/util.ts index f44cb1a..8e5769e 100644 --- a/util.ts +++ b/util.ts @@ -1,4 +1,4 @@ +// @ts-ignore TS2551 export const unstable = typeof Deno.dlopen !== "undefined"; -export const webgpu = unstable && - typeof navigator.gpu === "object" && +export const webgpu = unstable && typeof navigator.gpu === "object" && typeof navigator.gpu.requestAdapter === "function";