commit dd62f2b9f693da4401abf89a703c21991c7c2278 Author: Bel LaPointe Date: Sun Nov 26 16:59:22 2023 -0700 whisper.cpp from 73e33a182c3e608ac5947375b4ca3f8ee0ad4253 and patched to support diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml new file mode 100644 index 0000000..99aab40 --- /dev/null +++ b/.github/workflows/pr.yml @@ -0,0 +1,76 @@ +name: Check code +on: + push: + pull_request: + workflow_dispatch: + +jobs: + rustfmt: + runs-on: ubuntu-latest + steps: + - name: Check out code into the proper directory + uses: actions/checkout@v3 + with: + submodules: 'recursive' + + - name: Cache rust + uses: Swatinem/rust-cache@v2 + + - name: Install rust + uses: dtolnay/rust-toolchain@master + with: + toolchain: stable + components: rustfmt + + - name: Check formatting + run: cargo fmt --check + + + clippy: + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + rust-version: [stable, nightly] + runs-on: ${{ matrix.os }} + steps: + - name: Check out code into the proper directory + uses: actions/checkout@v3 + with: + submodules: 'recursive' + + - name: Cache rust + uses: Swatinem/rust-cache@v2 + + - name: Install rust + uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ matrix.rust-version }} + components: clippy + + - name: Check clippy lints + run: cargo clippy + + build: + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + rust-version: [stable, nightly] + runs-on: ${{ matrix.os }} + steps: + - name: Check out code into the proper directory + uses: actions/checkout@v3 + with: + submodules: 'recursive' + + - name: Cache rust + uses: Swatinem/rust-cache@v2 + + - name: Install rust + uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ matrix.rust-version }} + + - name: Check build + run: cargo build --verbose diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c3e612d --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +**/target +**/Cargo.lock +/.idea diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..0863136 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "sys/whisper.cpp"] + path = sys/whisper.cpp + url = https://github.com/ggerganov/whisper.cpp diff --git a/BUILDING.md b/BUILDING.md new file mode 100644 index 0000000..0820aab --- /dev/null +++ b/BUILDING.md @@ -0,0 +1,47 @@ + +# Running on Windows using MSYS2 + +The following are instructions for building whisper-rs on Windows using the msys2 set of compilers. + +1. install msys2/mingw by following [https://code.visualstudio.com/docs/cpp/config-mingw](`https://code.visualstudio.com/docs/cpp/config-mingw`) + 1. Install g++ and make within msys2 ucrt64 + - `pacman -S --needed base-devel mingw-w64-x86_64-toolchain` + 2. Add the msys2 ucrt64 bin folder to path `C:\msys64\ucrt64\bin` +2. Install make by running `pacman -S make` in msys2 ucrt66 +3. Set rust to use msys2: by running `rustup toolchain install stable-x86_64-pc-windows-gnu` in Windows Powershell/Cmd +4. Add `.cargo/config.toml` file in the project with the following contents: +``` +[target.x86_64-pc-windows-gnu] +linker = "C:\\msys64\\ucrt64\\bin\\gcc.exe" +ar = "C:\\msys64\\ucrt64\\bin\\ar.exe" +``` +5. Run `cargo run` in Windows Powershell/Cmd + +# Running on Windows using Microsoft Visual Studio C++ + +It has been reported that it is also possible to build whisper-rs using Visual Studio C++. + +Make sure you have installed and in the path: + +- Visual Studio C++ +- cmake +- LLVM(clang) + +# Running on M1 OSX + +To build on a M1 Mac, make sure to add the following to your project's `.cargo/config.toml`: + +``` +[target.aarch64-apple-darwin] +rustflags = "-lc++ -l framework=Accelerate" +``` + +See https://github.com/tazz4843/whisper-rs/pull/2 for more information. + +You also need to have CMake installed. You can obtain this using homebrew: + +``` +brew install cmake +``` + +CMake can also be installed from https://cmake.org/download/ but `cmake` binary needs to be in your PATH. \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..0b2d5a1 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,41 @@ +# Version 0.8.0 (-sys bindings 0.6.1) (2023-06-18) +* Fix CUDA and OpenCL build broken due to missing API headers. +* Use PIC when building whisper.cpp (fixes building a cdylib on x86 Linux) + +# Version 0.8.0 (2023-05-14) +* Update upstream whisper.cpp to v1.4.2 (OpenCL support) +* Add CUDA and OpenCL support to bindings + * No MacOS testers were able to test CoreML support, so it may be broken. Please open an issue if it is. + * Enable CUDA support by enabling the `cuda` feature. + * Enable OpenCL support by enabling the `opencl` feature. +* Add `FullParams::set_detect_language` + +# Version 0.7.0 (2023-05-10) +* Update upstream whisper.cpp to v1.4.0 (integer quantization support, see last point for CUDA support) +* Expose `WhisperState` as a public type, allowing for more control over the state. + * `WhisperContext::create_state` now returns a `WhisperState` instead of `()`. + * All methods that took a key argument in v0.6.0 have been moved to `WhisperState`. +* Generic key argument on `WhisperContext` has been removed. +* Note: CUDA and OpenCL acceleration is supported on the `cuda-and-opencl-support` branch of the git repo, + and will probably be released in v0.8.0. + +# Version 0.6.0 (2023-04-17) +* Update upstream whisper.cpp to v1.3.0 +* Fix breaking changes in update, which cascade to users: + * `WhisperContext`s now have a generic type parameter, which is a hashable key for a state map. + This allows for a single context to be reused for multiple different states, saving memory. + * You must create a new state upon creation, even if you are using the context only once, by calling `WhisperContext::create_key`. + * Each method that now takes a state now takes a key, which internally is used to look up the state. + * This also turns `WhisperContext` into an entirely immutable object, meaning it can be shared across threads and used concurrently, safely. +* Send feedback on these changes to the PR: https://github.com/tazz4843/whisper-rs/pull/33 + +# Version 0.2.0 (2022-10-28) +* Update upstream whisper.cpp to 2c281d190b7ec351b8128ba386d110f100993973. +* Fix breaking changes in update, which cascade to users: + * `DecodeStrategy` has been renamed to `SamplingStrategy` + * `WhisperContext::sample_best`'s signature has changed: `needs_timestamp` has been removed. +* New features + * `WhisperContext::full_n_tokens` + * `WhisperContext::full_get_token_text` + * `WhisperContext::full_get_token_id` + * `WhisperContext::full_get_token_prob` diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..2f56bc4 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,34 @@ +[workspace] +members = ["sys"] +exclude = ["examples/full_usage"] + +[package] +name = "whisper-rs" +version = "0.8.0" +edition = "2021" +description = "Rust bindings for whisper.cpp" +license = "Unlicense" +documentation = "https://docs.rs/whisper-rs" +repository = "https://github.com/tazz4843/whisper-rs" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +whisper-rs-sys = { path = "sys", version = "0.7" } + +[dev-dependencies] +hound = "3.5.0" + +[features] +default = [] + +simd = [] +coreml = ["whisper-rs-sys/coreml"] +cuda = ["whisper-rs-sys/cuda"] +opencl = ["whisper-rs-sys/opencl"] +openblas = ["whisper-rs-sys/openblas"] +metal = ["whisper-rs-sys/metal"] +test-with-tiny-model = [] + +[package.metadata.docs.rs] +features = ["simd"] diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..3c577b0 --- /dev/null +++ b/LICENSE @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..49ab481 --- /dev/null +++ b/README.md @@ -0,0 +1,82 @@ +# whisper-rs + +Rust bindings to [whisper.cpp](https://github.com/ggerganov/whisper.cpp/) + +## Usage + +```bash +git clone --recursive https://github.com/tazz4843/whisper-rs.git + +cd whisper-rs + +cargo run --example basic_use + +cargo run --example audio_transcription +``` + +```rust +use whisper_rs::{WhisperContext, FullParams, SamplingStrategy}; + +fn main() { + let path_to_model = std::env::args().nth(1).unwrap(); + + // load a context and model + let ctx = WhisperContext::new(&path_to_model).expect("failed to load model"); + + // create a params object + let params = FullParams::new(SamplingStrategy::Greedy { best_of: 1 }); + + // assume we have a buffer of audio data + // here we'll make a fake one, floating point samples, 32 bit, 16KHz, mono + let audio_data = vec![0_f32; 16000 * 2]; + + // now we can run the model + let mut state = ctx.create_state().expect("failed to create state"); + state + .full(params, &audio_data[..]) + .expect("failed to run model"); + + // fetch the results + let num_segments = state + .full_n_segments() + .expect("failed to get number of segments"); + for i in 0..num_segments { + let segment = state + .full_get_segment_text(i) + .expect("failed to get segment"); + let start_timestamp = state + .full_get_segment_t0(i) + .expect("failed to get segment start timestamp"); + let end_timestamp = state + .full_get_segment_t1(i) + .expect("failed to get segment end timestamp"); + println!("[{} - {}]: {}", start_timestamp, end_timestamp, segment); + } +} +``` + +See [examples/basic_use.rs](examples/basic_use.rs) for more details. + +Lower level bindings are exposed if needed, but the above should be enough for most use cases. +See the docs: https://docs.rs/whisper-rs/ for more details. + +## Building + +See [BUILDING.md](BUILDING.md) for instructions for building whisper-rs on Windows and OSX M1. Linux builds should just work out of the box. + +## Troubleshooting + +* Something other than Windows/macOS/Linux isn't working! + * I don't have a way to test these platforms, so I can't really help you. + * If you can get it working, please open a PR with any changes to make it work and build instructions in BUILDING.md! +* I get a panic during binding generation build! + * You can attempt to fix it yourself, or you can set the `WHISPER_DONT_GENERATE_BINDINGS` environment variable. + This skips attempting to build the bindings whatsoever and copies the existing ones. They may be out of date, + but it's better than nothing. + * `WHISPER_DONT_GENERATE_BINDINGS=1 cargo build` + * If you can fix the issue, please open a PR! + +## License +[Unlicense](LICENSE) + +tl;dr: public domain diff --git a/examples/audio_transcription.rs b/examples/audio_transcription.rs new file mode 100644 index 0000000..71dec68 --- /dev/null +++ b/examples/audio_transcription.rs @@ -0,0 +1,98 @@ +// This example is not going to build in this folder. +// You need to copy this code into your project and add the dependencies whisper_rs and hound in your cargo.toml + +use hound; +use std::fs::File; +use std::io::Write; +use whisper_rs::{FullParams, SamplingStrategy, WhisperContext}; + +/// Loads a context and model, processes an audio file, and prints the resulting transcript to stdout. +fn main() -> Result<(), &'static str> { + // Load a context and model. + let ctx = WhisperContext::new("example/path/to/model/whisper.cpp/models/ggml-base.en.bin") + .expect("failed to load model"); + // Create a state + let mut state = ctx.create_state().expect("failed to create key"); + + // Create a params object for running the model. + // The number of past samples to consider defaults to 0. + let mut params = FullParams::new(SamplingStrategy::Greedy { best_of: 0 }); + + // Edit params as needed. + // Set the number of threads to use to 1. + params.set_n_threads(1); + // Enable translation. + params.set_translate(true); + // Set the language to translate to to English. + params.set_language(Some("en")); + // Disable anything that prints to stdout. + params.set_print_special(false); + params.set_print_progress(false); + params.set_print_realtime(false); + params.set_print_timestamps(false); + + // Open the audio file. + let mut reader = hound::WavReader::open("audio.wav").expect("failed to open file"); + #[allow(unused_variables)] + let hound::WavSpec { + channels, + sample_rate, + bits_per_sample, + .. + } = reader.spec(); + + // Convert the audio to floating point samples. + let mut audio = whisper_rs::convert_integer_to_float_audio( + &reader + .samples::() + .map(|s| s.expect("invalid sample")) + .collect::>(), + ); + + // Convert audio to 16KHz mono f32 samples, as required by the model. + // These utilities are provided for convenience, but can be replaced with custom conversion logic. + // SIMD variants of these functions are also available on nightly Rust (see the docs). + if channels == 2 { + audio = whisper_rs::convert_stereo_to_mono_audio(&audio)?; + } else if channels != 1 { + panic!(">2 channels unsupported"); + } + + if sample_rate != 16000 { + panic!("sample rate must be 16KHz"); + } + + // Run the model. + state.full(params, &audio[..]).expect("failed to run model"); + + // Create a file to write the transcript to. + let mut file = File::create("transcript.txt").expect("failed to create file"); + + // Iterate through the segments of the transcript. + let num_segments = state + .full_n_segments() + .expect("failed to get number of segments"); + for i in 0..num_segments { + // Get the transcribed text and timestamps for the current segment. + let segment = state + .full_get_segment_text(i) + .expect("failed to get segment"); + let start_timestamp = state + .full_get_segment_t0(i) + .expect("failed to get start timestamp"); + let end_timestamp = state + .full_get_segment_t1(i) + .expect("failed to get end timestamp"); + + // Print the segment to stdout. + println!("[{} - {}]: {}", start_timestamp, end_timestamp, segment); + + // Format the segment information as a string. + let line = format!("[{} - {}]: {}\n", start_timestamp, end_timestamp, segment); + + // Write the segment information to the file. + file.write_all(line.as_bytes()) + .expect("failed to write to file"); + } + Ok(()) +} diff --git a/examples/basic_use.rs b/examples/basic_use.rs new file mode 100644 index 0000000..f0d81e0 --- /dev/null +++ b/examples/basic_use.rs @@ -0,0 +1,73 @@ +#![allow(clippy::uninlined_format_args)] + +use whisper_rs::{FullParams, SamplingStrategy, WhisperContext}; + +// note that running this example will not do anything, as it is just a +// demonstration of how to use the library, and actual usage requires +// more dependencies than the base library. +pub fn usage() -> Result<(), &'static str> { + // load a context and model + let ctx = WhisperContext::new("path/to/model").expect("failed to load model"); + // make a state + let mut state = ctx.create_state().expect("failed to create state"); + + // create a params object + // note that currently the only implemented strategy is Greedy, BeamSearch is a WIP + // n_past defaults to 0 + let mut params = FullParams::new(SamplingStrategy::Greedy { best_of: 1 }); + + // edit things as needed + // here we set the number of threads to use to 1 + params.set_n_threads(1); + // we also enable translation + params.set_translate(true); + // and set the language to translate to to english + params.set_language(Some("en")); + // we also explicitly disable anything that prints to stdout + params.set_print_special(false); + params.set_print_progress(false); + params.set_print_realtime(false); + params.set_print_timestamps(false); + + // assume we have a buffer of audio data + // here we'll make a fake one, integer samples, 16 bit, 16KHz, stereo + let audio_data = vec![0_i16; 16000 * 2]; + + // we must convert to 16KHz mono f32 samples for the model + // some utilities exist for this + // note that you don't need to use these, you can do it yourself or any other way you want + // these are just provided for convenience + // SIMD variants of these functions are also available, but only on nightly Rust: see the docs + let audio_data = whisper_rs::convert_stereo_to_mono_audio( + &whisper_rs::convert_integer_to_float_audio(&audio_data), + )?; + + // now we can run the model + // note the key we use here is the one we created above + state + .full(params, &audio_data[..]) + .expect("failed to run model"); + + // fetch the results + let num_segments = state + .full_n_segments() + .expect("failed to get number of segments"); + for i in 0..num_segments { + let segment = state + .full_get_segment_text(i) + .expect("failed to get segment"); + let start_timestamp = state + .full_get_segment_t0(i) + .expect("failed to get segment start timestamp"); + let end_timestamp = state + .full_get_segment_t1(i) + .expect("failed to get segment end timestamp"); + println!("[{} - {}]: {}", start_timestamp, end_timestamp, segment); + } + + Ok(()) +} + +fn main() { + println!("running this example does nothing! see the source code for usage"); +} diff --git a/examples/full_usage/2830-3980-0043.wav b/examples/full_usage/2830-3980-0043.wav new file mode 100644 index 0000000..d6b8463 Binary files /dev/null and b/examples/full_usage/2830-3980-0043.wav differ diff --git a/examples/full_usage/Cargo.toml b/examples/full_usage/Cargo.toml new file mode 100644 index 0000000..97020b0 --- /dev/null +++ b/examples/full_usage/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "full_usage" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +hound = "3" +whisper-rs = { path = "../.." } diff --git a/examples/full_usage/src/main.rs b/examples/full_usage/src/main.rs new file mode 100644 index 0000000..c5eca17 --- /dev/null +++ b/examples/full_usage/src/main.rs @@ -0,0 +1,75 @@ +#![allow(clippy::uninlined_format_args)] + +use hound::{SampleFormat, WavReader}; +use std::path::Path; +use whisper_rs::{FullParams, SamplingStrategy, WhisperContext}; + +fn parse_wav_file(path: &Path) -> Vec { + let reader = WavReader::open(path).expect("failed to read file"); + + if reader.spec().channels != 1 { + panic!("expected mono audio file"); + } + if reader.spec().sample_format != SampleFormat::Int { + panic!("expected integer sample format"); + } + if reader.spec().sample_rate != 16000 { + panic!("expected 16KHz sample rate"); + } + if reader.spec().bits_per_sample != 16 { + panic!("expected 16 bits per sample"); + } + + reader + .into_samples::() + .map(|x| x.expect("sample")) + .collect::>() +} + +fn main() { + let arg1 = std::env::args() + .nth(1) + .expect("first argument should be path to WAV file"); + let audio_path = Path::new(&arg1); + if !audio_path.exists() { + panic!("audio file doesn't exist"); + } + let arg2 = std::env::args() + .nth(2) + .expect("second argument should be path to Whisper model"); + let whisper_path = Path::new(&arg2); + if !whisper_path.exists() { + panic!("whisper file doesn't exist") + } + + let original_samples = parse_wav_file(audio_path); + let samples = whisper_rs::convert_integer_to_float_audio(&original_samples); + + let ctx = WhisperContext::new(&whisper_path.to_string_lossy()).expect("failed to open model"); + let mut state = ctx.create_state().expect("failed to create key"); + let mut params = FullParams::new(SamplingStrategy::default()); + params.set_progress_callback_safe(|progress| println!("Progress callback: {}%", progress)); + + let st = std::time::Instant::now(); + state + .full(params, &samples) + .expect("failed to convert samples"); + let et = std::time::Instant::now(); + + let num_segments = state + .full_n_segments() + .expect("failed to get number of segments"); + for i in 0..num_segments { + let segment = state + .full_get_segment_text(i) + .expect("failed to get segment"); + let start_timestamp = state + .full_get_segment_t0(i) + .expect("failed to get start timestamp"); + let end_timestamp = state + .full_get_segment_t1(i) + .expect("failed to get end timestamp"); + println!("[{} - {}]: {}", start_timestamp, end_timestamp, segment); + } + println!("took {}ms", (et - st).as_millis()); +} diff --git a/src/error.rs b/src/error.rs new file mode 100644 index 0000000..5807a90 --- /dev/null +++ b/src/error.rs @@ -0,0 +1,113 @@ +use std::ffi::{c_int, NulError}; +use std::str::Utf8Error; + +/// Whisper tends to output errors to stderr, so if an error occurs, check stderr. +#[derive(Debug, Copy, Clone)] +pub enum WhisperError { + /// Failed to create a new context. + InitError, + /// User didn't initialize spectrogram + SpectrogramNotInitialized, + /// Encode was not called. + EncodeNotComplete, + /// Decode was not called. + DecodeNotComplete, + /// Failed to calculate the spectrogram for some reason. + UnableToCalculateSpectrogram, + /// Failed to evaluate model. + UnableToCalculateEvaluation, + /// Failed to run the encoder + FailedToEncode, + /// Failed to run the decoder + FailedToDecode, + /// Invalid number of mel bands. + InvalidMelBands, + /// Invalid thread count + InvalidThreadCount, + /// Invalid UTF-8 detected in a string from Whisper. + InvalidUtf8 { + error_len: Option, + valid_up_to: usize, + }, + /// A null byte was detected in a user-provided string. + NullByteInString { idx: usize }, + /// Whisper returned a null pointer. + NullPointer, + /// Generic whisper error. Varies depending on the function. + GenericError(c_int), + /// Whisper failed to convert the provided text into tokens. + InvalidText, + /// Creating a state pointer failed. Check stderr for more information. + FailedToCreateState, +} + +impl From for WhisperError { + fn from(e: Utf8Error) -> Self { + Self::InvalidUtf8 { + error_len: e.error_len(), + valid_up_to: e.valid_up_to(), + } + } +} + +impl From for WhisperError { + fn from(e: NulError) -> Self { + Self::NullByteInString { + idx: e.nul_position(), + } + } +} + +impl std::fmt::Display for WhisperError { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + use WhisperError::*; + match self { + InitError => write!(f, "Failed to create a new whisper context."), + SpectrogramNotInitialized => write!(f, "User didn't initialize spectrogram."), + EncodeNotComplete => write!(f, "Encode was not called."), + DecodeNotComplete => write!(f, "Decode was not called."), + UnableToCalculateSpectrogram => { + write!(f, "Failed to calculate the spectrogram for some reason.") + } + UnableToCalculateEvaluation => write!(f, "Failed to evaluate model."), + FailedToEncode => write!(f, "Failed to run the encoder."), + FailedToDecode => write!(f, "Failed to run the decoder."), + InvalidMelBands => write!(f, "Invalid number of mel bands."), + InvalidThreadCount => write!(f, "Invalid thread count."), + InvalidUtf8 { + valid_up_to, + error_len: Some(len), + } => write!( + f, + "Invalid UTF-8 detected in a string from Whisper. Index: {}, Length: {}.", + valid_up_to, len + ), + InvalidUtf8 { + valid_up_to, + error_len: None, + } => write!( + f, + "Invalid UTF-8 detected in a string from Whisper. Index: {}.", + valid_up_to + ), + NullByteInString { idx } => write!( + f, + "A null byte was detected in a user-provided string. Index: {}", + idx + ), + NullPointer => write!(f, "Whisper returned a null pointer."), + InvalidText => write!( + f, + "Whisper failed to convert the provided text into tokens." + ), + FailedToCreateState => write!(f, "Creating a state pointer failed."), + GenericError(c_int) => write!( + f, + "Generic whisper error. Varies depending on the function. Error code: {}", + c_int + ), + } + } +} + +impl std::error::Error for WhisperError {} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..36995dd --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,28 @@ +#![allow(clippy::uninlined_format_args)] +#![cfg_attr(feature = "simd", feature(portable_simd))] + +mod error; +mod standalone; +mod utilities; +mod whisper_ctx; +mod whisper_params; +mod whisper_state; + +pub use error::WhisperError; +pub use standalone::*; +pub use utilities::*; +pub use whisper_ctx::WhisperContext; +pub use whisper_params::{FullParams, SamplingStrategy}; +pub use whisper_state::WhisperState; + +pub type WhisperSysContext = whisper_rs_sys::whisper_context; +pub type WhisperSysState = whisper_rs_sys::whisper_state; + +pub type WhisperTokenData = whisper_rs_sys::whisper_token_data; +pub type WhisperToken = whisper_rs_sys::whisper_token; +pub type WhisperNewSegmentCallback = whisper_rs_sys::whisper_new_segment_callback; +pub type WhisperStartEncoderCallback = whisper_rs_sys::whisper_encoder_begin_callback; +pub type WhisperProgressCallback = whisper_rs_sys::whisper_progress_callback; +pub type WhisperLogitsFilterCallback = whisper_rs_sys::whisper_logits_filter_callback; +pub type WhisperAbortCallback = whisper_rs_sys::whisper_abort_callback; +pub type WhisperLogCallback = whisper_rs_sys::ggml_log_callback; diff --git a/src/standalone.rs b/src/standalone.rs new file mode 100644 index 0000000..bf456d5 --- /dev/null +++ b/src/standalone.rs @@ -0,0 +1,113 @@ +//! Standalone functions that have no associated type. + +use std::ffi::{c_int, CStr, CString}; + +/// Return the id of the specified language, returns -1 if not found +/// +/// # Arguments +/// * lang: The language to get the id for. +/// +/// # Returns +/// The ID of the language, None if not found. +/// +/// # Panics +/// Panics if the language contains a null byte. +/// +/// # C++ equivalent +/// `int whisper_lang_id(const char * lang)` +pub fn get_lang_id(lang: &str) -> Option { + let c_lang = CString::new(lang).expect("Language contains null byte"); + let ret = unsafe { whisper_rs_sys::whisper_lang_id(c_lang.as_ptr()) }; + if ret == -1 { + None + } else { + Some(ret) + } +} + +/// Return the ID of the maximum language (ie the number of languages - 1) +/// +/// # Returns +/// i32 +/// +/// # C++ equivalent +/// `int whisper_lang_max_id()` +pub fn get_lang_max_id() -> i32 { + unsafe { whisper_rs_sys::whisper_lang_max_id() } +} + +/// Get the short string of the specified language id (e.g. 2 -> "de"). +/// +/// # Returns +/// The short string of the language, None if not found. +/// +/// # C++ equivalent +/// `const char * whisper_lang_str(int id)` +pub fn get_lang_str(id: i32) -> Option<&'static str> { + let c_buf = unsafe { whisper_rs_sys::whisper_lang_str(id) }; + if c_buf.is_null() { + None + } else { + let c_str = unsafe { CStr::from_ptr(c_buf) }; + Some(c_str.to_str().unwrap()) + } +} + +/// Callback to control logging output: default behaviour is to print to stderr. +/// +/// # C++ equivalent +/// `void whisper_set_log_callback(whisper_log_callback callback);` +pub unsafe fn set_log_callback(_callback: whisper_rs_sys::ggml_log_callback) { + //unsafe { whisper_rs_sys::whisper_log_set(callback, None) } +} + +/// Print system information. +/// +/// # C++ equivalent +/// `const char * whisper_print_system_info()` +pub fn print_system_info() -> &'static str { + let c_buf = unsafe { whisper_rs_sys::whisper_print_system_info() }; + let c_str = unsafe { CStr::from_ptr(c_buf) }; + c_str.to_str().unwrap() +} + +/// Programmatically exposes the information provided by `print_system_info` +/// +/// # C++ equivalent +/// `int ggml_cpu_has_...` +pub struct SystemInfo { + pub avx: bool, + pub avx2: bool, + pub fma: bool, + pub f16c: bool, + pub blas: bool, + pub clblast: bool, + pub cublas: bool, +} + +impl Default for SystemInfo { + fn default() -> Self { + unsafe { + Self { + avx: whisper_rs_sys::ggml_cpu_has_avx() != 0, + avx2: whisper_rs_sys::ggml_cpu_has_avx2() != 0, + fma: whisper_rs_sys::ggml_cpu_has_fma() != 0, + f16c: whisper_rs_sys::ggml_cpu_has_f16c() != 0, + blas: whisper_rs_sys::ggml_cpu_has_blas() != 0, + clblast: whisper_rs_sys::ggml_cpu_has_clblast() != 0, + cublas: whisper_rs_sys::ggml_cpu_has_cublas() != 0, + } + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_openblas() { + let info = SystemInfo::default(); + assert_eq!(info.blas, cfg!(feature = "openblas")); + } +} diff --git a/src/utilities.rs b/src/utilities.rs new file mode 100644 index 0000000..d233c9c --- /dev/null +++ b/src/utilities.rs @@ -0,0 +1,152 @@ +#[cfg(feature = "simd")] +use std::simd::{f32x16, i16x16, SimdInt}; + +/// Convert an array of 16 bit mono audio samples to a vector of 32 bit floats. +/// +/// This variant does not use SIMD instructions. +/// +/// # Arguments +/// * `samples` - The array of 16 bit mono audio samples. +/// +/// # Returns +/// A vector of 32 bit floats. +pub fn convert_integer_to_float_audio(samples: &[i16]) -> Vec { + let mut floats = Vec::with_capacity(samples.len()); + for sample in samples { + floats.push(*sample as f32 / 32768.0); + } + floats +} + +/// Convert an array of 16 bit mono audio samples to a vector of 32 bit floats. +/// +/// This variant uses SIMD instructions, and as such is only available on +/// nightly Rust. +/// +/// # Arguments +/// * `samples` - The array of 16 bit mono audio samples. +/// +/// # Returns +/// A vector of 32 bit floats. +#[cfg(feature = "simd")] +pub fn convert_integer_to_float_audio_simd(samples: &[i16]) -> Vec { + let mut floats = Vec::with_capacity(samples.len()); + + let div_arr = f32x16::splat(32768.0); + + let chunks = samples.chunks_exact(16); + let remainder = chunks.remainder(); + for chunk in chunks { + let simd = i16x16::from_slice(chunk).cast::(); + let simd = simd / div_arr; + floats.extend(&simd.to_array()[..]); + } + + // Handle the remainder. + // do this normally because it's only a few samples and the overhead of + // converting to SIMD is not worth it. + for sample in remainder { + floats.push(*sample as f32 / 32768.0); + } + + floats +} + +/// Convert 32 bit floating point stereo PCM audio to 32 bit floating point mono PCM audio. +/// +/// This variant does not use SIMD instructions. +/// +/// # Arguments +/// * `samples` - The array of 32 bit floating point stereo PCM audio samples. +/// +/// # Returns +/// A vector of 32 bit floating point mono PCM audio samples. +pub fn convert_stereo_to_mono_audio(samples: &[f32]) -> Result, &'static str> { + if samples.len() & 1 != 0 { + return Err("The stereo audio vector has an odd number of samples. \ + This means a half-sample is missing somewhere"); + } + + Ok(samples + .chunks_exact(2) + .map(|x| (x[0] + x[1]) / 2.0) + .collect()) +} + +/// Convert 32 bit floating point stereo PCM audio to 32 bit floating point mono PCM audio. +/// +/// This variant uses SIMD instructions, and as such is only available on +/// nightly Rust. +/// +/// # Arguments +/// * `samples` - The array of 32 bit floating point stereo PCM audio samples. +/// +/// # Returns +/// A vector of 32 bit floating point mono PCM audio samples. +#[cfg(feature = "simd")] +pub fn convert_stereo_to_mono_audio_simd(samples: &[f32]) -> Result, &'static str> { + let mut mono = Vec::with_capacity(samples.len() / 2); + + let div_array = f32x16::splat(2.0); + + let chunks = samples.chunks_exact(32); + let remainder = chunks.remainder(); + for chunk in chunks { + let [c1, c2] = [0, 1].map(|offset| { + let mut arr = [0.0; 16]; + std::iter::zip(&mut arr, chunk.iter().skip(offset).step_by(2).copied()) + .for_each(|(a, c)| *a = c); + arr + }); + + let c1 = f32x16::from(c1); + let c2 = f32x16::from(c2); + let mono_simd = (c1 + c2) / div_array; + mono.extend(&mono_simd.to_array()[..]); + } + + // Handle the remainder. + // do this normally because it's only a few samples and the overhead of + // converting to SIMD is not worth it. + mono.extend(convert_stereo_to_mono_audio(remainder)?); + + Ok(mono) +} + +#[cfg(feature = "simd")] +#[cfg(test)] +mod test { + use super::*; + + #[test] + pub fn assert_stereo_to_mono_err() { + // fake some sample data + let samples = (0u16..1029).map(f32::from).collect::>(); + let mono = convert_stereo_to_mono_audio(&samples); + assert!(mono.is_err()); + } +} + +#[cfg(feature = "simd")] +#[cfg(test)] +mod test_simd { + use super::*; + + #[test] + pub fn assert_stereo_to_mono_simd() { + // fake some sample data + let samples = (0u16..1028).map(f32::from).collect::>(); + let mono_simd = convert_stereo_to_mono_audio_simd(&samples); + let mono = convert_stereo_to_mono_audio(&samples); + assert_eq!(mono_simd, mono); + } + + #[test] + pub fn assert_stereo_to_mono_simd_err() { + // fake some sample data + let samples = (0u16..1029).map(f32::from).collect::>(); + let mono_simd = convert_stereo_to_mono_audio_simd(&samples); + let mono = convert_stereo_to_mono_audio(&samples); + assert_eq!(mono_simd, mono); + } +} diff --git a/src/whisper_ctx.rs b/src/whisper_ctx.rs new file mode 100644 index 0000000..350e534 --- /dev/null +++ b/src/whisper_ctx.rs @@ -0,0 +1,496 @@ +use crate::error::WhisperError; +use crate::whisper_state::WhisperState; +use crate::WhisperToken; +use std::ffi::{c_int, CStr, CString}; + +/// Safe Rust wrapper around a Whisper context. +/// +/// You likely want to create this with [WhisperContext::new], +/// then run a full transcription with [WhisperContext::full]. +#[derive(Debug)] +pub struct WhisperContext { + ctx: *mut whisper_rs_sys::whisper_context, +} + +impl WhisperContext { + /// Create a new WhisperContext from a file. + /// + /// # Arguments + /// * path: The path to the model file. + /// + /// # Returns + /// Ok(Self) on success, Err(WhisperError) on failure. + /// + /// # C++ equivalent + /// `struct whisper_context * whisper_init_from_file(const char * path_model);` + pub fn new(path: &str) -> Result { + let path_cstr = CString::new(path)?; + let ctx = unsafe { whisper_rs_sys::whisper_init_from_file_no_state(path_cstr.as_ptr()) }; + if ctx.is_null() { + Err(WhisperError::InitError) + } else { + Ok(Self { ctx }) + } + } + + /// Create a new WhisperContext from a buffer. + /// + /// # Arguments + /// * buffer: The buffer containing the model. + /// + /// # Returns + /// Ok(Self) on success, Err(WhisperError) on failure. + /// + /// # C++ equivalent + /// `struct whisper_context * whisper_init_from_buffer(const char * buffer, int n_bytes);` + pub fn new_from_buffer(buffer: &[u8]) -> Result { + let ctx = unsafe { + whisper_rs_sys::whisper_init_from_buffer_no_state(buffer.as_ptr() as _, buffer.len()) + }; + if ctx.is_null() { + Err(WhisperError::InitError) + } else { + Ok(Self { ctx }) + } + } + + // we don't implement `whisper_init()` here since i have zero clue what `whisper_model_loader` does + + /// Create a new state object, ready for use. + /// + /// # Returns + /// Ok(WhisperState) on success, Err(WhisperError) on failure. + /// + /// # C++ equivalent + /// `struct whisper_state * whisper_init_state(struct whisper_context * ctx);` + pub fn create_state(&self) -> Result { + let state = unsafe { whisper_rs_sys::whisper_init_state(self.ctx) }; + if state.is_null() { + Err(WhisperError::InitError) + } else { + // SAFETY: this is known to be a valid pointer to a `whisper_state` struct + Ok(WhisperState::new(self.ctx, state)) + } + } + + /// Convert the provided text into tokens. + /// + /// # Arguments + /// * text: The text to convert. + /// + /// # Returns + /// Ok(Vec) on success, Err(WhisperError) on failure. + /// + /// # C++ equivalent + /// `int whisper_tokenize(struct whisper_context * ctx, const char * text, whisper_token * tokens, int n_max_tokens);` + pub fn tokenize( + &self, + text: &str, + max_tokens: usize, + ) -> Result, WhisperError> { + // convert the text to a nul-terminated C string. Will raise an error if the text contains + // any nul bytes. + let text = CString::new(text)?; + // allocate at least max_tokens to ensure the memory is valid + let mut tokens: Vec = Vec::with_capacity(max_tokens); + let ret = unsafe { + whisper_rs_sys::whisper_tokenize( + self.ctx, + text.as_ptr(), + tokens.as_mut_ptr(), + max_tokens as c_int, + ) + }; + if ret == -1 { + Err(WhisperError::InvalidText) + } else { + // SAFETY: when ret != -1, we know that the length of the vector is at least ret tokens + unsafe { tokens.set_len(ret as usize) }; + Ok(tokens) + } + } + + /// Get n_vocab. + /// + /// # Returns + /// c_int + /// + /// # C++ equivalent + /// `int whisper_n_vocab (struct whisper_context * ctx)` + #[inline] + pub fn n_vocab(&self) -> c_int { + unsafe { whisper_rs_sys::whisper_n_vocab(self.ctx) } + } + + /// Get n_text_ctx. + /// + /// # Returns + /// c_int + /// + /// # C++ equivalent + /// `int whisper_n_text_ctx (struct whisper_context * ctx);` + #[inline] + pub fn n_text_ctx(&self) -> c_int { + unsafe { whisper_rs_sys::whisper_n_text_ctx(self.ctx) } + } + + /// Get n_audio_ctx. + /// + /// # Returns + /// c_int + /// + /// # C++ equivalent + /// `int whisper_n_audio_ctx (struct whisper_context * ctx);` + #[inline] + pub fn n_audio_ctx(&self) -> c_int { + unsafe { whisper_rs_sys::whisper_n_audio_ctx(self.ctx) } + } + + /// Does this model support multiple languages? + /// + /// # C++ equivalent + /// `int whisper_is_multilingual(struct whisper_context * ctx)` + #[inline] + pub fn is_multilingual(&self) -> bool { + unsafe { whisper_rs_sys::whisper_is_multilingual(self.ctx) != 0 } + } + + /// Get model_n_vocab. + /// + /// # Returns + /// c_int + /// + /// # C++ equivalent + /// `int whisper_model_n_vocab (struct whisper_context * ctx);` + #[inline] + pub fn model_n_vocab(&self) -> c_int { + unsafe { whisper_rs_sys::whisper_model_n_vocab(self.ctx) } + } + + /// Get model_n_audio_ctx. + /// + /// # Returns + /// c_int + /// + /// # C++ equivalent + /// `int whisper_model_n_audio_ctx (struct whisper_context * ctx)` + #[inline] + pub fn model_n_audio_ctx(&self) -> c_int { + unsafe { whisper_rs_sys::whisper_model_n_audio_ctx(self.ctx) } + } + + /// Get model_n_audio_state. + /// + /// # Returns + /// c_int + /// + /// # C++ equivalent + /// `int whisper_model_n_audio_state(struct whisper_context * ctx);` + #[inline] + pub fn model_n_audio_state(&self) -> c_int { + unsafe { whisper_rs_sys::whisper_model_n_audio_state(self.ctx) } + } + + /// Get model_n_audio_head. + /// + /// # Returns + /// c_int + /// + /// # C++ equivalent + /// `int whisper_model_n_audio_head (struct whisper_context * ctx);` + #[inline] + pub fn model_n_audio_head(&self) -> c_int { + unsafe { whisper_rs_sys::whisper_model_n_audio_head(self.ctx) } + } + + /// Get model_n_audio_layer. + /// + /// # Returns + /// c_int + /// + /// # C++ equivalent + /// `int whisper_model_n_audio_layer(struct whisper_context * ctx);` + #[inline] + pub fn model_n_audio_layer(&self) -> c_int { + unsafe { whisper_rs_sys::whisper_model_n_audio_layer(self.ctx) } + } + + /// Get model_n_text_ctx. + /// + /// # Returns + /// c_int + /// + /// # C++ equivalent + /// `int whisper_model_n_text_ctx (struct whisper_context * ctx)` + #[inline] + pub fn model_n_text_ctx(&self) -> c_int { + unsafe { whisper_rs_sys::whisper_model_n_text_ctx(self.ctx) } + } + + /// Get model_n_text_state. + /// + /// # Returns + /// c_int + /// + /// # C++ equivalent + /// `int whisper_model_n_text_state (struct whisper_context * ctx);` + #[inline] + pub fn model_n_text_state(&self) -> c_int { + unsafe { whisper_rs_sys::whisper_model_n_text_state(self.ctx) } + } + + /// Get model_n_text_head. + /// + /// # Returns + /// c_int + /// + /// # C++ equivalent + /// `int whisper_model_n_text_head (struct whisper_context * ctx);` + #[inline] + pub fn model_n_text_head(&self) -> c_int { + unsafe { whisper_rs_sys::whisper_model_n_text_head(self.ctx) } + } + + /// Get model_n_text_layer. + /// + /// # Returns + /// c_int + /// + /// # C++ equivalent + /// `int whisper_model_n_text_layer (struct whisper_context * ctx);` + #[inline] + pub fn model_n_text_layer(&self) -> c_int { + unsafe { whisper_rs_sys::whisper_model_n_text_layer(self.ctx) } + } + + /// Get model_n_mels. + /// + /// # Returns + /// c_int + /// + /// # C++ equivalent + /// `int whisper_model_n_mels (struct whisper_context * ctx);` + #[inline] + pub fn model_n_mels(&self) -> c_int { + unsafe { whisper_rs_sys::whisper_model_n_mels(self.ctx) } + } + + /// Get model_ftype. + /// + /// # Returns + /// c_int + /// + /// # C++ equivalent + /// `int whisper_model_ftype (struct whisper_context * ctx);` + #[inline] + pub fn model_ftype(&self) -> c_int { + unsafe { whisper_rs_sys::whisper_model_ftype(self.ctx) } + } + + /// Get model_type. + /// + /// # Returns + /// c_int + /// + /// # C++ equivalent + /// `int whisper_model_type (struct whisper_context * ctx);` + #[inline] + pub fn model_type(&self) -> c_int { + unsafe { whisper_rs_sys::whisper_model_type(self.ctx) } + } + + // token functions + /// Convert a token ID to a string. + /// + /// # Arguments + /// * token_id: ID of the token. + /// + /// # Returns + /// Ok(&str) on success, Err(WhisperError) on failure. + /// + /// # C++ equivalent + /// `const char * whisper_token_to_str(struct whisper_context * ctx, whisper_token token)` + pub fn token_to_str(&self, token_id: WhisperToken) -> Result<&str, WhisperError> { + let c_str = self.token_to_cstr(token_id)?; + let r_str = c_str.to_str()?; + Ok(r_str) + } + + /// Convert a token ID to a &CStr. + /// + /// # Arguments + /// * token_id: ID of the token. + /// + /// # Returns + /// Ok(String) on success, Err(WhisperError) on failure. + /// + /// # C++ equivalent + /// `const char * whisper_token_to_str(struct whisper_context * ctx, whisper_token token)` + pub fn token_to_cstr(&self, token_id: WhisperToken) -> Result<&CStr, WhisperError> { + let ret = unsafe { whisper_rs_sys::whisper_token_to_str(self.ctx, token_id) }; + if ret.is_null() { + return Err(WhisperError::NullPointer); + } + Ok(unsafe { CStr::from_ptr(ret) }) + } + + /// Undocumented but exposed function in the C++ API. + /// `const char * whisper_model_type_readable(struct whisper_context * ctx);` + /// + /// # Returns + /// Ok(String) on success, Err(WhisperError) on failure. + pub fn model_type_readable(&self) -> Result { + let ret = unsafe { whisper_rs_sys::whisper_model_type_readable(self.ctx) }; + if ret.is_null() { + return Err(WhisperError::NullPointer); + } + let c_str = unsafe { CStr::from_ptr(ret) }; + let r_str = c_str.to_str()?; + Ok(r_str.to_string()) + } + + /// Get the ID of the eot token. + /// + /// # C++ equivalent + /// `whisper_token whisper_token_eot (struct whisper_context * ctx)` + #[inline] + pub fn token_eot(&self) -> WhisperToken { + unsafe { whisper_rs_sys::whisper_token_eot(self.ctx) } + } + + /// Get the ID of the sot token. + /// + /// # C++ equivalent + /// `whisper_token whisper_token_sot (struct whisper_context * ctx)` + #[inline] + pub fn token_sot(&self) -> WhisperToken { + unsafe { whisper_rs_sys::whisper_token_sot(self.ctx) } + } + + /// Get the ID of the solm token. + /// + /// # C++ equivalent + /// `whisper_token whisper_token_solm(struct whisper_context * ctx)` + #[inline] + pub fn token_solm(&self) -> WhisperToken { + unsafe { whisper_rs_sys::whisper_token_solm(self.ctx) } + } + + /// Get the ID of the prev token. + /// + /// # C++ equivalent + /// `whisper_token whisper_token_prev(struct whisper_context * ctx)` + #[inline] + pub fn token_prev(&self) -> WhisperToken { + unsafe { whisper_rs_sys::whisper_token_prev(self.ctx) } + } + + /// Get the ID of the nosp token. + /// + /// # C++ equivalent + /// `whisper_token whisper_token_nosp(struct whisper_context * ctx)` + #[inline] + pub fn token_nosp(&self) -> WhisperToken { + unsafe { whisper_rs_sys::whisper_token_nosp(self.ctx) } + } + + /// Get the ID of the not token. + /// + /// # C++ equivalent + /// `whisper_token whisper_token_not (struct whisper_context * ctx)` + #[inline] + pub fn token_not(&self) -> WhisperToken { + unsafe { whisper_rs_sys::whisper_token_not(self.ctx) } + } + + /// Get the ID of the beg token. + /// + /// # C++ equivalent + /// `whisper_token whisper_token_beg (struct whisper_context * ctx)` + #[inline] + pub fn token_beg(&self) -> WhisperToken { + unsafe { whisper_rs_sys::whisper_token_beg(self.ctx) } + } + + /// Get the ID of a specified language token + /// + /// # Arguments + /// * lang_id: ID of the language + /// + /// # C++ equivalent + /// `whisper_token whisper_token_lang(struct whisper_context * ctx, int lang_id)` + #[inline] + pub fn token_lang(&self, lang_id: c_int) -> WhisperToken { + unsafe { whisper_rs_sys::whisper_token_lang(self.ctx, lang_id) } + } + + /// Print performance statistics to stderr. + /// + /// # C++ equivalent + /// `void whisper_print_timings(struct whisper_context * ctx)` + #[inline] + pub fn print_timings(&self) { + unsafe { whisper_rs_sys::whisper_print_timings(self.ctx) } + } + + /// Reset performance statistics. + /// + /// # C++ equivalent + /// `void whisper_reset_timings(struct whisper_context * ctx)` + #[inline] + pub fn reset_timings(&self) { + unsafe { whisper_rs_sys::whisper_reset_timings(self.ctx) } + } + + // task tokens + /// Get the ID of the translate task token. + /// + /// # C++ equivalent + /// `whisper_token whisper_token_translate ()` + pub fn token_translate(&self) -> WhisperToken { + unsafe { whisper_rs_sys::whisper_token_translate(self.ctx) } + } + + /// Get the ID of the transcribe task token. + /// + /// # C++ equivalent + /// `whisper_token whisper_token_transcribe()` + pub fn token_transcribe(&self) -> WhisperToken { + unsafe { whisper_rs_sys::whisper_token_transcribe(self.ctx) } + } +} + +impl Drop for WhisperContext { + #[inline] + fn drop(&mut self) { + unsafe { whisper_rs_sys::whisper_free(self.ctx) }; + } +} + +// following implementations are safe +// see https://github.com/ggerganov/whisper.cpp/issues/32#issuecomment-1272790388 +unsafe impl Send for WhisperContext {} +unsafe impl Sync for WhisperContext {} + +#[cfg(test)] +#[cfg(feature = "test-with-tiny-model")] +mod test_with_tiny_model { + use super::*; + const MODEL_PATH: &str = "./sys/whisper.cpp/models/ggml-tiny.en.bin"; + + // These tests expect that the tiny.en model has been downloaded + // using the script `sys/whisper.cpp/models/download-ggml-model.sh tiny.en` + + #[test] + fn test_tokenize_round_trip() { + let ctx = WhisperContext::new(MODEL_PATH).expect("Download the ggml-tiny.en model using 'sys/whisper.cpp/models/download-ggml-model.sh tiny.en'"); + let text_in = " And so my fellow Americans, ask not what your country can do for you, ask what you can do for your country."; + let tokens = ctx.tokenize(text_in, 1024).unwrap(); + let text_out = tokens + .into_iter() + .map(|t| ctx.token_to_str(t).unwrap()) + .collect::>() + .join(""); + assert_eq!(text_in, text_out); + } +} diff --git a/src/whisper_params.rs b/src/whisper_params.rs new file mode 100644 index 0000000..73e57be --- /dev/null +++ b/src/whisper_params.rs @@ -0,0 +1,538 @@ +use std::ffi::{c_float, c_int, CString}; +use std::marker::PhantomData; +use whisper_rs_sys::whisper_token; + +#[derive(Debug, Clone)] +pub enum SamplingStrategy { + Greedy { + best_of: c_int, + }, + BeamSearch { + beam_size: c_int, + // not implemented in whisper.cpp as of this writing (v1.2.0) + patience: c_float, + }, +} + +impl Default for SamplingStrategy { + fn default() -> Self { + Self::Greedy { best_of: 1 } + } +} + +pub struct FullParams<'a, 'b> { + pub(crate) fp: whisper_rs_sys::whisper_full_params, + phantom_lang: PhantomData<&'a str>, + phantom_tokens: PhantomData<&'b [c_int]>, + progess_callback_safe: Option>, +} + +impl<'a, 'b> FullParams<'a, 'b> { + /// Create a new set of parameters for the decoder. + pub fn new(sampling_strategy: SamplingStrategy) -> FullParams<'a, 'b> { + let mut fp = unsafe { + whisper_rs_sys::whisper_full_default_params(match sampling_strategy { + SamplingStrategy::Greedy { .. } => { + whisper_rs_sys::whisper_sampling_strategy_WHISPER_SAMPLING_GREEDY + } + SamplingStrategy::BeamSearch { .. } => { + whisper_rs_sys::whisper_sampling_strategy_WHISPER_SAMPLING_BEAM_SEARCH + } + } as _) + }; + + match sampling_strategy { + SamplingStrategy::Greedy { best_of } => { + fp.greedy.best_of = best_of; + } + SamplingStrategy::BeamSearch { + beam_size, + patience, + } => { + fp.beam_search.beam_size = beam_size; + fp.beam_search.patience = patience; + } + } + + Self { + fp, + phantom_lang: PhantomData, + phantom_tokens: PhantomData, + progess_callback_safe: None, + } + } + + /// Set the number of threads to use for decoding. + /// + /// Defaults to min(4, std::thread::hardware_concurrency()). + pub fn set_n_threads(&mut self, n_threads: c_int) { + self.fp.n_threads = n_threads; + } + + /// Max tokens to use from past text as prompt for the decoder + /// + /// Defaults to 16384. + pub fn set_n_max_text_ctx(&mut self, n_max_text_ctx: c_int) { + self.fp.n_max_text_ctx = n_max_text_ctx; + } + + /// Set the start offset in milliseconds to use for decoding. + /// + /// Defaults to 0. + pub fn set_offset_ms(&mut self, offset_ms: c_int) { + self.fp.offset_ms = offset_ms; + } + + /// Set the audio duration to process in milliseconds. + /// + /// Defaults to 0. + pub fn set_duration_ms(&mut self, duration_ms: c_int) { + self.fp.duration_ms = duration_ms; + } + + /// Set whether to translate the output to the language specified by `language`. + /// + /// Defaults to false. + pub fn set_translate(&mut self, translate: bool) { + self.fp.translate = translate; + } + + /// Do not use past transcription (if any) as initial prompt for the decoder. + /// + /// Defaults to false. + pub fn set_no_context(&mut self, no_context: bool) { + self.fp.no_context = no_context; + } + + /// Force single segment output. This may be useful for streaming. + /// + /// Defaults to false. + pub fn set_single_segment(&mut self, single_segment: bool) { + self.fp.single_segment = single_segment; + } + + /// Print special tokens (e.g. , , , etc.) + /// + /// Defaults to false. + pub fn set_print_special(&mut self, print_special: bool) { + self.fp.print_special = print_special; + } + + /// Set whether to print progress. + /// + /// Defaults to true. + pub fn set_print_progress(&mut self, print_progress: bool) { + self.fp.print_progress = print_progress; + } + + /// Print results from within whisper.cpp. + /// Try to use the callback methods instead: [set_new_segment_callback](FullParams::set_new_segment_callback), + /// [set_new_segment_callback_user_data](FullParams::set_new_segment_callback_user_data). + /// + /// Defaults to false. + pub fn set_print_realtime(&mut self, print_realtime: bool) { + self.fp.print_realtime = print_realtime; + } + + /// Print timestamps for each text segment when printing realtime. Only has an effect if + /// [set_print_realtime](FullParams::set_print_realtime) is set to true. + /// + /// Defaults to true. + pub fn set_print_timestamps(&mut self, print_timestamps: bool) { + self.fp.print_timestamps = print_timestamps; + } + + /// # EXPERIMENTAL + /// + /// Enable token-level timestamps. + /// + /// Defaults to false. + pub fn set_token_timestamps(&mut self, token_timestamps: bool) { + self.fp.token_timestamps = token_timestamps; + } + + /// # EXPERIMENTAL + /// + /// Set timestamp token probability threshold. + /// + /// Defaults to 0.01. + pub fn set_thold_pt(&mut self, thold_pt: f32) { + self.fp.thold_pt = thold_pt; + } + + /// # EXPERIMENTAL + /// + /// Set timestamp token sum probability threshold. + /// + /// Defaults to 0.01. + pub fn set_thold_ptsum(&mut self, thold_ptsum: f32) { + self.fp.thold_ptsum = thold_ptsum; + } + + /// # EXPERIMENTAL + /// + /// Set maximum segment length in characters. + /// + /// Defaults to 0. + pub fn set_max_len(&mut self, max_len: c_int) { + self.fp.max_len = max_len; + } + + /// # EXPERIMENTAL + /// + /// Should the timestamps be split on words instead of characters? + /// + /// Defaults to false. + pub fn set_split_on_word(&mut self, split_on_word: bool) { + self.fp.split_on_word = split_on_word; + } + + /// # EXPERIMENTAL + /// + /// Set maximum tokens per segment. 0 means no limit. + /// + /// Defaults to 0. + pub fn set_max_tokens(&mut self, max_tokens: c_int) { + self.fp.max_tokens = max_tokens; + } + + /// # EXPERIMENTAL + /// + /// Speed up audio ~2x by using phase vocoder. + /// Note that this can significantly reduce the accuracy of the transcription. + /// + /// Defaults to false. + pub fn set_speed_up(&mut self, speed_up: bool) { + self.fp.speed_up = speed_up; + } + + /// # EXPERIMENTAL + /// + /// Enables debug mode, such as dumping the log mel spectrogram. + /// + /// Defaults to false. + pub fn set_debug_mode(&mut self, debug: bool) { + self.fp.debug_mode = debug; + } + + /// # EXPERIMENTAL + /// + /// Overwrite the audio context size. 0 = default. + /// As with [set_speed_up](FullParams::set_speed_up), this can significantly reduce the accuracy of the transcription. + /// + /// Defaults to 0. + pub fn set_audio_ctx(&mut self, audio_ctx: c_int) { + self.fp.audio_ctx = audio_ctx; + } + + /// # EXPERIMENTAL + /// + /// Enable tinydiarize support. + /// Experimental speaker turn detection. + /// + /// Defaults to false. + pub fn set_tdrz_enable(&mut self, tdrz_enable: bool) { + self.fp.tdrz_enable = tdrz_enable; + } + + /// Set tokens to provide the model as initial input. + /// + /// These tokens are prepended to any existing text content from a previous call. + /// + /// Calling this more than once will overwrite the previous tokens. + /// + /// Defaults to an empty vector. + pub fn set_tokens(&mut self, tokens: &'b [c_int]) { + // turn into ptr and len + let tokens_ptr: *const whisper_token = tokens.as_ptr(); + let tokens_len: c_int = tokens.len() as c_int; + + // set the tokens + self.fp.prompt_tokens = tokens_ptr; + self.fp.prompt_n_tokens = tokens_len; + } + + /// Set the target language. + /// + /// For auto-detection, set this to either "auto" or None. + /// + /// Defaults to "en". + pub fn set_language(&mut self, language: Option<&'a str>) { + self.fp.language = match language { + Some(language) => CString::new(language) + .expect("Language contains null byte") + .into_raw() as *const _, + None => std::ptr::null(), + }; + } + + /// Set `detect_language`. + /// + /// Has the same effect as setting the language to "auto" or None. + /// + /// Defaults to false. + pub fn set_detect_language(&mut self, detect_language: bool) { + self.fp.detect_language = detect_language; + } + + /// Set suppress_blank. See https://github.com/openai/whisper/blob/f82bc59f5ea234d4b97fb2860842ed38519f7e65/whisper/decoding.py#L89 + /// for more information. + /// + /// Defaults to true. + pub fn set_suppress_blank(&mut self, suppress_blank: bool) { + self.fp.suppress_blank = suppress_blank; + } + + /// Set suppress_non_speech_tokens. See https://github.com/openai/whisper/blob/7858aa9c08d98f75575035ecd6481f462d66ca27/whisper/tokenizer.py#L224-L253 + /// for more information. + /// + /// Defaults to false. + pub fn set_suppress_non_speech_tokens(&mut self, suppress_non_speech_tokens: bool) { + self.fp.suppress_non_speech_tokens = suppress_non_speech_tokens; + } + + /// Set initial decoding temperature. See https://ai.stackexchange.com/a/32478 for more information. + /// + /// Defaults to 0.0. + pub fn set_temperature(&mut self, temperature: f32) { + self.fp.temperature = temperature; + } + + /// Set max_initial_ts. See https://github.com/openai/whisper/blob/f82bc59f5ea234d4b97fb2860842ed38519f7e65/whisper/decoding.py#L97 + /// for more information. + /// + /// Defaults to 1.0. + pub fn set_max_initial_ts(&mut self, max_initial_ts: f32) { + self.fp.max_initial_ts = max_initial_ts; + } + + /// Set length_penalty. See https://github.com/openai/whisper/blob/f82bc59f5ea234d4b97fb2860842ed38519f7e65/whisper/transcribe.py#L267 + /// for more information. + /// + /// Defaults to -1.0. + pub fn set_length_penalty(&mut self, length_penalty: f32) { + self.fp.length_penalty = length_penalty; + } + + /// Set temperature_inc. See https://github.com/openai/whisper/blob/f82bc59f5ea234d4b97fb2860842ed38519f7e65/whisper/transcribe.py#L274-L278 + /// for more information. + /// + /// Defaults to 0.2. + pub fn set_temperature_inc(&mut self, temperature_inc: f32) { + self.fp.temperature_inc = temperature_inc; + } + + /// Set entropy_thold. Similar to OpenAI's compression_ratio_threshold. + /// See https://github.com/openai/whisper/blob/f82bc59f5ea234d4b97fb2860842ed38519f7e65/whisper/transcribe.py#L274-L278 for more information. + /// + /// Defaults to 2.4. + pub fn set_entropy_thold(&mut self, entropy_thold: f32) { + self.fp.entropy_thold = entropy_thold; + } + + /// Set logprob_thold. See https://github.com/openai/whisper/blob/f82bc59f5ea234d4b97fb2860842ed38519f7e65/whisper/transcribe.py#L274-L278 + /// for more information. + /// + /// Defaults to -1.0. + pub fn set_logprob_thold(&mut self, logprob_thold: f32) { + self.fp.logprob_thold = logprob_thold; + } + + /// Set no_speech_thold. Currently (as of v1.3.0) not implemented. + /// + /// Defaults to 0.6. + pub fn set_no_speech_thold(&mut self, no_speech_thold: f32) { + self.fp.no_speech_thold = no_speech_thold; + } + + /// Set the callback for new segments. + /// + /// Note that this callback has not been Rustified yet (and likely never will be, unless someone else feels the need to do so). + /// It is still a C callback. + /// + /// # Safety + /// Do not use this function unless you know what you are doing. + /// * Be careful not to mutate the state of the whisper_context pointer returned in the callback. + /// This could cause undefined behavior, as this violates the thread-safety guarantees of the underlying C library. + /// + /// Defaults to None. + pub unsafe fn set_new_segment_callback( + &mut self, + new_segment_callback: crate::WhisperNewSegmentCallback, + ) { + self.fp.new_segment_callback = new_segment_callback; + } + + /// Set the user data to be passed to the new segment callback. + /// + /// # Safety + /// See the safety notes for `set_new_segment_callback`. + /// + /// Defaults to None. + pub unsafe fn set_new_segment_callback_user_data(&mut self, user_data: *mut std::ffi::c_void) { + self.fp.new_segment_callback_user_data = user_data; + } + + /// Set the callback for progress updates. + /// + /// Note that is still a C callback. + /// See `set_progress_callback_safe` for a limited yet safe version. + /// + /// # Safety + /// Do not use this function unless you know what you are doing. + /// * Be careful not to mutate the state of the whisper_context pointer returned in the callback. + /// This could cause undefined behavior, as this violates the thread-safety guarantees of the underlying C library. + /// + /// Defaults to None. + pub unsafe fn set_progress_callback( + &mut self, + progress_callback: crate::WhisperProgressCallback, + ) { + self.fp.progress_callback = progress_callback; + } + + /// Set the callback for progress updates, potentially using a closure. + /// + /// Note that, in order to ensure safety, the callback only accepts the progress in percent. + /// See `set_progress_callback` if you need to use `whisper_context` and `whisper_state` + /// (or extend this one to support their use). + /// + /// Defaults to None. + pub fn set_progress_callback_safe(&mut self, closure: O) + where + F: FnMut(i32) + 'static, + O: Into>, + { + use std::ffi::c_void; + use whisper_rs_sys::{whisper_context, whisper_state}; + + unsafe extern "C" fn trampoline( + _: *mut whisper_context, + _: *mut whisper_state, + progress: c_int, + user_data: *mut c_void, + ) where + F: FnMut(i32), + { + let user_data = &mut *(user_data as *mut F); + user_data(progress); + } + + match closure.into() { + Some(mut closure) => { + self.fp.progress_callback = Some(trampoline::); + self.fp.progress_callback_user_data = &mut closure as *mut F as *mut c_void; + // store the closure internally to make sure that the pointer above remains valid + self.progess_callback_safe = Some(Box::new(closure)); + } + None => { + self.fp.progress_callback = None; + self.fp.progress_callback_user_data = std::ptr::null_mut::(); + self.progess_callback_safe = None; + } + } + } + + /// Set the user data to be passed to the progress callback. + /// + /// # Safety + /// See the safety notes for `set_progress_callback`. + /// + /// Defaults to None. + pub unsafe fn set_progress_callback_user_data(&mut self, user_data: *mut std::ffi::c_void) { + self.fp.progress_callback_user_data = user_data; + } + + /// Set the callback that is called each time before the encoder begins. + /// + /// Note that this callback has not been Rustified yet (and likely never will be, unless someone else feels the need to do so). + /// It is still a C callback. + /// + /// # Safety + /// Do not use this function unless you know what you are doing. + /// * Be careful not to mutate the state of the whisper_context pointer returned in the callback. + /// This could cause undefined behavior, as this violates the thread-safety guarantees of the underlying C library. + /// + /// Defaults to None. + pub unsafe fn set_start_encoder_callback( + &mut self, + start_encoder_callback: crate::WhisperStartEncoderCallback, + ) { + self.fp.encoder_begin_callback = start_encoder_callback; + } + + /// Set the user data to be passed to the start encoder callback. + /// + /// # Safety + /// See the safety notes for `set_start_encoder_callback`. + /// + /// Defaults to None. + pub unsafe fn set_start_encoder_callback_user_data( + &mut self, + user_data: *mut std::ffi::c_void, + ) { + self.fp.encoder_begin_callback_user_data = user_data; + } + + /// Set the callback that is called by each decoder to filter obtained logits. + /// + /// Note that this callback has not been Rustified yet (and likely never will be, unless someone else feels the need to do so). + /// It is still a C callback. + /// + /// # Safety + /// Do not use this function unless you know what you are doing. + /// * Be careful not to mutate the state of the whisper_context pointer returned in the callback. + /// This could cause undefined behavior, as this violates the thread-safety guarantees of the underlying C library. + /// + /// Defaults to None. + pub unsafe fn set_filter_logits_callback( + &mut self, + logits_filter_callback: crate::WhisperLogitsFilterCallback, + ) { + self.fp.logits_filter_callback = logits_filter_callback; + } + + /// Set the user data to be passed to the logits filter callback. + /// + /// # Safety + /// See the safety notes for `set_filter_logits_callback`. + /// + /// Defaults to None. + pub unsafe fn set_filter_logits_callback_user_data( + &mut self, + user_data: *mut std::ffi::c_void, + ) { + self.fp.logits_filter_callback_user_data = user_data; + } + + /// Set the callback that is called each time before ggml computation starts. + /// + /// Note that this callback has not been Rustified yet (and likely never will be, unless someone else feels the need to do so). + /// It is still a C callback. + /// + /// # Safety + /// Do not use this function unless you know what you are doing. + /// * Be careful not to mutate the state of the whisper_context pointer returned in the callback. + /// This could cause undefined behavior, as this violates the thread-safety guarantees of the underlying C library. + /// + /// Defaults to None. + pub unsafe fn set_abort_callback(&mut self, abort_callback: crate::WhisperAbortCallback) { + self.fp.abort_callback = abort_callback; + } + + /// Set the user data to be passed to the abort callback. + /// + /// # Safety + /// See the safety notes for `set_abort_callback`. + /// + /// Defaults to None. + pub unsafe fn set_abort_callback_user_data(&mut self, user_data: *mut std::ffi::c_void) { + self.fp.abort_callback_user_data = user_data; + } +} + +// following implementations are safe +// see https://github.com/ggerganov/whisper.cpp/issues/32#issuecomment-1272790388 +// concurrent usage is prevented by &mut self on methods that modify the struct +unsafe impl<'a, 'b> Send for FullParams<'a, 'b> {} +unsafe impl<'a, 'b> Sync for FullParams<'a, 'b> {} diff --git a/src/whisper_state.rs b/src/whisper_state.rs new file mode 100644 index 0000000..c49e2b6 --- /dev/null +++ b/src/whisper_state.rs @@ -0,0 +1,542 @@ +use crate::{FullParams, WhisperContext, WhisperError, WhisperToken, WhisperTokenData}; +use std::ffi::{c_int, CStr}; +use std::marker::PhantomData; + +/// Rustified pointer to a Whisper state. +#[derive(Debug)] +pub struct WhisperState<'a> { + ctx: *mut whisper_rs_sys::whisper_context, + ptr: *mut whisper_rs_sys::whisper_state, + _phantom: PhantomData<&'a WhisperContext>, +} + +unsafe impl<'a> Send for WhisperState<'a> {} +unsafe impl<'a> Sync for WhisperState<'a> {} + +impl<'a> Drop for WhisperState<'a> { + fn drop(&mut self) { + unsafe { + whisper_rs_sys::whisper_free_state(self.ptr); + } + } +} + +impl<'a> WhisperState<'a> { + pub(crate) fn new( + ctx: *mut whisper_rs_sys::whisper_context, + ptr: *mut whisper_rs_sys::whisper_state, + ) -> Self { + Self { + ctx, + ptr, + _phantom: PhantomData, + } + } + + /// Convert raw PCM audio (floating point 32 bit) to log mel spectrogram. + /// The resulting spectrogram is stored in the context transparently. + /// + /// # Arguments + /// * pcm: The raw PCM audio. + /// * threads: How many threads to use. Defaults to 1. Must be at least 1, returns an error otherwise. + /// + /// # Returns + /// Ok(()) on success, Err(WhisperError) on failure. + /// + /// # C++ equivalent + /// `int whisper_pcm_to_mel(struct whisper_context * ctx, const float * samples, int n_samples, int n_threads)` + pub fn pcm_to_mel(&mut self, pcm: &[f32], threads: usize) -> Result<(), WhisperError> { + if threads < 1 { + return Err(WhisperError::InvalidThreadCount); + } + let ret = unsafe { + whisper_rs_sys::whisper_pcm_to_mel_with_state( + self.ctx, + self.ptr, + pcm.as_ptr(), + pcm.len() as c_int, + threads as c_int, + ) + }; + if ret == -1 { + Err(WhisperError::UnableToCalculateSpectrogram) + } else if ret == 0 { + Ok(()) + } else { + Err(WhisperError::GenericError(ret)) + } + } + + /// Convert raw PCM audio (floating point 32 bit) to log mel spectrogram. + /// Applies a Phase Vocoder to speed up the audio x2. + /// The resulting spectrogram is stored in the context transparently. + /// + /// # Arguments + /// * pcm: The raw PCM audio. + /// * threads: How many threads to use. Defaults to 1. Must be at least 1, returns an error otherwise. + /// + /// # Returns + /// Ok(()) on success, Err(WhisperError) on failure. + /// + /// # C++ equivalent + /// `int whisper_pcm_to_mel(struct whisper_context * ctx, const float * samples, int n_samples, int n_threads)` + pub fn pcm_to_mel_phase_vocoder( + &mut self, + pcm: &[f32], + threads: usize, + ) -> Result<(), WhisperError> { + if threads < 1 { + return Err(WhisperError::InvalidThreadCount); + } + let ret = unsafe { + whisper_rs_sys::whisper_pcm_to_mel_phase_vocoder_with_state( + self.ctx, + self.ptr, + pcm.as_ptr(), + pcm.len() as c_int, + threads as c_int, + ) + }; + if ret == -1 { + Err(WhisperError::UnableToCalculateSpectrogram) + } else if ret == 0 { + Ok(()) + } else { + Err(WhisperError::GenericError(ret)) + } + } + + /// This can be used to set a custom log mel spectrogram inside the provided whisper state. + /// Use this instead of whisper_pcm_to_mel() if you want to provide your own log mel spectrogram. + /// + /// # Note + /// This is a low-level function. + /// If you're a typical user, you probably don't want to use this function. + /// See instead [WhisperContext::pcm_to_mel]. + /// + /// # Arguments + /// * data: The log mel spectrogram. + /// + /// # Returns + /// Ok(()) on success, Err(WhisperError) on failure. + /// + /// # C++ equivalent + /// `int whisper_set_mel(struct whisper_context * ctx, const float * data, int n_len, int n_mel)` + pub fn set_mel(&mut self, data: &[f32]) -> Result<(), WhisperError> { + let hop_size = 160; + let n_len = (data.len() / hop_size) * 2; + let ret = unsafe { + whisper_rs_sys::whisper_set_mel_with_state( + self.ctx, + self.ptr, + data.as_ptr(), + n_len as c_int, + 80 as c_int, + ) + }; + if ret == -1 { + Err(WhisperError::InvalidMelBands) + } else if ret == 0 { + Ok(()) + } else { + Err(WhisperError::GenericError(ret)) + } + } + + /// Run the Whisper encoder on the log mel spectrogram stored inside the provided whisper state. + /// Make sure to call [WhisperContext::pcm_to_mel] or [WhisperContext::set_mel] first. + /// + /// # Arguments + /// * offset: Can be used to specify the offset of the first frame in the spectrogram. Usually 0. + /// * threads: How many threads to use. Defaults to 1. Must be at least 1, returns an error otherwise. + /// + /// # Returns + /// Ok(()) on success, Err(WhisperError) on failure. + /// + /// # C++ equivalent + /// `int whisper_encode(struct whisper_context * ctx, int offset, int n_threads)` + pub fn encode(&mut self, offset: usize, threads: usize) -> Result<(), WhisperError> { + if threads < 1 { + return Err(WhisperError::InvalidThreadCount); + } + let ret = unsafe { + whisper_rs_sys::whisper_encode_with_state( + self.ctx, + self.ptr, + offset as c_int, + threads as c_int, + ) + }; + if ret == -1 { + Err(WhisperError::UnableToCalculateEvaluation) + } else if ret == 0 { + Ok(()) + } else { + Err(WhisperError::GenericError(ret)) + } + } + + /// Run the Whisper decoder to obtain the logits and probabilities for the next token. + /// Make sure to call [WhisperContext::encode] first. + /// tokens + n_tokens is the provided context for the decoder. + /// + /// # Arguments + /// * tokens: The tokens to decode. + /// * n_tokens: The number of tokens to decode. + /// * n_past: The number of past tokens to use for the decoding. + /// * n_threads: How many threads to use. Defaults to 1. Must be at least 1, returns an error otherwise. + /// + /// # Returns + /// Ok(()) on success, Err(WhisperError) on failure. + /// + /// # C++ equivalent + /// `int whisper_decode(struct whisper_context * ctx, const whisper_token * tokens, int n_tokens, int n_past, int n_threads)` + pub fn decode( + &mut self, + tokens: &[WhisperToken], + n_past: usize, + threads: usize, + ) -> Result<(), WhisperError> { + if threads < 1 { + return Err(WhisperError::InvalidThreadCount); + } + let ret = unsafe { + whisper_rs_sys::whisper_decode_with_state( + self.ctx, + self.ptr, + tokens.as_ptr(), + tokens.len() as c_int, + n_past as c_int, + threads as c_int, + ) + }; + if ret == -1 { + Err(WhisperError::UnableToCalculateEvaluation) + } else if ret == 0 { + Ok(()) + } else { + Err(WhisperError::GenericError(ret)) + } + } + + // Language functions + /// Use mel data at offset_ms to try and auto-detect the spoken language + /// Make sure to call pcm_to_mel() or set_mel() first + /// + /// # Arguments + /// * offset_ms: The offset in milliseconds to use for the language detection. + /// * n_threads: How many threads to use. Defaults to 1. Must be at least 1, returns an error otherwise. + /// + /// # Returns + /// Ok(Vec) on success, Err(WhisperError) on failure. + /// + /// # C++ equivalent + /// `int whisper_lang_auto_detect(struct whisper_context * ctx, int offset_ms, int n_threads, float * lang_probs)` + pub fn lang_detect(&self, offset_ms: usize, threads: usize) -> Result, WhisperError> { + if threads < 1 { + return Err(WhisperError::InvalidThreadCount); + } + + let mut lang_probs: Vec = vec![0.0; crate::standalone::get_lang_max_id() as usize + 1]; + let ret = unsafe { + whisper_rs_sys::whisper_lang_auto_detect_with_state( + self.ctx, + self.ptr, + offset_ms as c_int, + threads as c_int, + lang_probs.as_mut_ptr(), + ) + }; + if ret == -1 { + Err(WhisperError::UnableToCalculateEvaluation) + } else { + assert_eq!( + ret as usize, + lang_probs.len(), + "lang_probs length mismatch: this is a bug in whisper.cpp" + ); + // if we're still running, double check that the length is correct, otherwise print to stderr + // and abort, as this will cause Undefined Behavior + // might get here due to the unwind being caught by a user-installed panic handler + if lang_probs.len() != ret as usize { + eprintln!( + "lang_probs length mismatch: this is a bug in whisper.cpp, \ + aborting to avoid Undefined Behavior" + ); + std::process::abort(); + } + Ok(lang_probs) + } + } + + // logit functions + /// Gets logits obtained from the last call to [WhisperContext::decode]. + /// As of whisper.cpp 1.4.1, only a single row of logits is available, corresponding to the last token in the input. + /// + /// # Returns + /// A slice of logits with length equal to n_vocab. + /// + /// # C++ equivalent + /// `float * whisper_get_logits(struct whisper_context * ctx)` + pub fn get_logits(&self) -> Result<&[f32], WhisperError> { + let ret = unsafe { whisper_rs_sys::whisper_get_logits_from_state(self.ptr) }; + if ret.is_null() { + return Err(WhisperError::NullPointer); + } + let n_vocab = self.n_vocab(); + Ok(unsafe { std::slice::from_raw_parts(ret, n_vocab as usize) }) + } + + // model attributes + /// Get the mel spectrogram length. + /// + /// # Returns + /// Ok(c_int) on success, Err(WhisperError) on failure. + /// + /// # C++ equivalent + /// `int whisper_n_len_from_state(struct whisper_context * ctx)` + #[inline] + pub fn n_len(&self) -> Result { + Ok(unsafe { whisper_rs_sys::whisper_n_len_from_state(self.ptr) }) + } + + /// Get n_vocab. + /// + /// # Returns + /// c_int + /// + /// # C++ equivalent + /// `int whisper_n_vocab (struct whisper_context * ctx)` + #[inline] + pub fn n_vocab(&self) -> c_int { + unsafe { whisper_rs_sys::whisper_n_vocab(self.ctx) } + } + + /// Run the entire model: PCM -> log mel spectrogram -> encoder -> decoder -> text + /// Uses the specified decoding strategy to obtain the text. + /// + /// This is usually the only function you need to call as an end user. + /// + /// # Arguments + /// * params: [crate::FullParams] struct. + /// * pcm: PCM audio data. + /// + /// # Returns + /// Ok(c_int) on success, Err(WhisperError) on failure. + /// + /// # C++ equivalent + /// `int whisper_full(struct whisper_context * ctx, struct whisper_full_params params, const float * samples, int n_samples)` + pub fn full(&mut self, params: FullParams, data: &[f32]) -> Result { + let ret = unsafe { + whisper_rs_sys::whisper_full_with_state( + self.ctx, + self.ptr, + params.fp, + data.as_ptr(), + data.len() as c_int, + ) + }; + if ret == -1 { + Err(WhisperError::UnableToCalculateSpectrogram) + } else if ret == 7 { + Err(WhisperError::FailedToEncode) + } else if ret == 8 { + Err(WhisperError::FailedToDecode) + } else if ret == 0 { + Ok(ret) + } else { + Err(WhisperError::GenericError(ret)) + } + } + + /// Number of generated text segments. + /// A segment can be a few words, a sentence, or even a paragraph. + /// + /// # C++ equivalent + /// `int whisper_full_n_segments(struct whisper_context * ctx)` + #[inline] + pub fn full_n_segments(&self) -> Result { + Ok(unsafe { whisper_rs_sys::whisper_full_n_segments_from_state(self.ptr) }) + } + + /// Language ID associated with the provided state. + /// + /// # C++ equivalent + /// `int whisper_full_lang_id_from_state(struct whisper_state * state);` + #[inline] + pub fn full_lang_id_from_state(&self) -> Result { + Ok(unsafe { whisper_rs_sys::whisper_full_lang_id_from_state(self.ptr) }) + } + + /// Get the start time of the specified segment. + /// + /// # Arguments + /// * segment: Segment index. + /// + /// # C++ equivalent + /// `int64_t whisper_full_get_segment_t0(struct whisper_context * ctx, int i_segment)` + #[inline] + pub fn full_get_segment_t0(&self, segment: c_int) -> Result { + Ok(unsafe { whisper_rs_sys::whisper_full_get_segment_t0_from_state(self.ptr, segment) }) + } + + /// Get the end time of the specified segment. + /// + /// # Arguments + /// * segment: Segment index. + /// + /// # C++ equivalent + /// `int64_t whisper_full_get_segment_t1(struct whisper_context * ctx, int i_segment)` + #[inline] + pub fn full_get_segment_t1(&self, segment: c_int) -> Result { + Ok(unsafe { whisper_rs_sys::whisper_full_get_segment_t1_from_state(self.ptr, segment) }) + } + + /// Get the text of the specified segment. + /// + /// # Arguments + /// * segment: Segment index. + /// + /// # Returns + /// Ok(String) on success, Err(WhisperError) on failure. + /// + /// # C++ equivalent + /// `const char * whisper_full_get_segment_text(struct whisper_context * ctx, int i_segment)` + pub fn full_get_segment_text(&self, segment: c_int) -> Result { + let ret = + unsafe { whisper_rs_sys::whisper_full_get_segment_text_from_state(self.ptr, segment) }; + if ret.is_null() { + return Err(WhisperError::NullPointer); + } + let c_str = unsafe { CStr::from_ptr(ret) }; + let r_str = c_str.to_str()?; + Ok(r_str.to_string()) + } + + /// Get the bytes of the specified segment. + /// + /// # Arguments + /// * segment: Segment index. + /// + /// # Returns + /// Ok(Vec) on success, Err(WhisperError) on failure. + /// + /// # C++ equivalent + /// `const char * whisper_full_get_segment_text(struct whisper_context * ctx, int i_segment)` + pub fn full_get_segment_bytes(&self, segment: c_int) -> Result, WhisperError> { + let ret = + unsafe { whisper_rs_sys::whisper_full_get_segment_text_from_state(self.ptr, segment) }; + if ret.is_null() { + return Err(WhisperError::NullPointer); + } + let c_str = unsafe { CStr::from_ptr(ret) }; + Ok(c_str.to_bytes().to_vec()) + } + + /// Get number of tokens in the specified segment. + /// + /// # Arguments + /// * segment: Segment index. + /// + /// # Returns + /// c_int + /// + /// # C++ equivalent + /// `int whisper_full_n_tokens(struct whisper_context * ctx, int i_segment)` + #[inline] + pub fn full_n_tokens(&self, segment: c_int) -> Result { + Ok(unsafe { whisper_rs_sys::whisper_full_n_tokens_from_state(self.ptr, segment) }) + } + + /// Get the token text of the specified token in the specified segment. + /// + /// # Arguments + /// * segment: Segment index. + /// * token: Token index. + /// + /// # Returns + /// Ok(String) on success, Err(WhisperError) on failure. + /// + /// # C++ equivalent + /// `const char * whisper_full_get_token_text(struct whisper_context * ctx, int i_segment, int i_token)` + pub fn full_get_token_text( + &self, + segment: c_int, + token: c_int, + ) -> Result { + let ret = unsafe { + whisper_rs_sys::whisper_full_get_token_text_from_state( + self.ctx, self.ptr, segment, token, + ) + }; + if ret.is_null() { + return Err(WhisperError::NullPointer); + } + let c_str = unsafe { CStr::from_ptr(ret) }; + let r_str = c_str.to_str()?; + Ok(r_str.to_string()) + } + + /// Get the token ID of the specified token in the specified segment. + /// + /// # Arguments + /// * segment: Segment index. + /// * token: Token index. + /// + /// # Returns + /// [crate::WhisperToken] + /// + /// # C++ equivalent + /// `whisper_token whisper_full_get_token_id (struct whisper_context * ctx, int i_segment, int i_token)` + pub fn full_get_token_id( + &self, + segment: c_int, + token: c_int, + ) -> Result { + Ok(unsafe { + whisper_rs_sys::whisper_full_get_token_id_from_state(self.ptr, segment, token) + }) + } + + /// Get token data for the specified token in the specified segment. + /// + /// # Arguments + /// * segment: Segment index. + /// * token: Token index. + /// + /// # Returns + /// [crate::WhisperTokenData] + /// + /// # C++ equivalent + /// `whisper_token_data whisper_full_get_token_data(struct whisper_context * ctx, int i_segment, int i_token)` + #[inline] + pub fn full_get_token_data( + &self, + segment: c_int, + token: c_int, + ) -> Result { + Ok(unsafe { + whisper_rs_sys::whisper_full_get_token_data_from_state(self.ptr, segment, token) + }) + } + + /// Get the probability of the specified token in the specified segment. + /// + /// # Arguments + /// * segment: Segment index. + /// * token: Token index. + /// + /// # Returns + /// f32 + /// + /// # C++ equivalent + /// `float whisper_full_get_token_p(struct whisper_context * ctx, int i_segment, int i_token)` + #[inline] + pub fn full_get_token_prob(&self, segment: c_int, token: c_int) -> Result { + Ok( + unsafe { + whisper_rs_sys::whisper_full_get_token_p_from_state(self.ptr, segment, token) + }, + ) + } +} diff --git a/sys/Cargo.toml b/sys/Cargo.toml new file mode 100644 index 0000000..91dc858 --- /dev/null +++ b/sys/Cargo.toml @@ -0,0 +1,48 @@ +[package] +name = "whisper-rs-sys" +version = "0.7.3" +edition = "2021" +description = "Rust bindings for whisper.cpp (FFI bindings)" +license = "Unlicense" +documentation = "https://docs.rs/whisper-rs-sys" +repository = "https://github.com/tazz4843/whisper-rs" +links = "whisper" +include = [ + "whisper.cpp/bindings/javascript/package-tmpl.json", + "whisper.cpp/bindings/CMakeLists.txt", + "whisper.cpp/cmake", + "whisper.cpp/coreml", + "whisper.cpp/CMakeLists.txt", + "whisper.cpp/ggml.c", + "whisper.cpp/ggml.h", + "whisper.cpp/ggml-opencl.c", + "whisper.cpp/ggml-opencl.h", + "whisper.cpp/ggml-cuda.cu", + "whisper.cpp/ggml-cuda.h", + "whisper.cpp/ggml-alloc.h", + "whisper.cpp/ggml-alloc.c", + "whisper.cpp/ggml-metal.metal", + "whisper.cpp/ggml-metal.m", + "whisper.cpp/ggml-metal.h", + "whisper.cpp/LICENSE", + "whisper.cpp/whisper.cpp", + "whisper.cpp/whisper.h", + "src/*.rs", + "build.rs", + "wrapper.h", +] + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[features] +coreml = [] +cuda = [] +opencl = [] +openblas = [] +metal = [] + +[build-dependencies] +cmake = "0.1" +bindgen = "0.68" +cfg-if = "1" +fs_extra = "1.3" diff --git a/sys/build.rs b/sys/build.rs new file mode 100644 index 0000000..e74ae3e --- /dev/null +++ b/sys/build.rs @@ -0,0 +1,169 @@ +#![allow(clippy::uninlined_format_args)] + +extern crate bindgen; + +use cmake::Config; +use std::env; +use std::path::PathBuf; + +fn main() { + let target = env::var("TARGET").unwrap(); + // Link C++ standard library + if let Some(cpp_stdlib) = get_cpp_link_stdlib(&target) { + println!("cargo:rustc-link-lib=dylib={}", cpp_stdlib); + } + // Link macOS Accelerate framework for matrix calculations + if target.contains("apple") { + println!("cargo:rustc-link-lib=framework=Accelerate"); + #[cfg(feature = "coreml")] + { + println!("cargo:rustc-link-lib=framework=Foundation"); + println!("cargo:rustc-link-lib=framework=CoreML"); + } + #[cfg(feature = "metal")] + { + println!("cargo:rustc-link-lib=framework=Foundation"); + println!("cargo:rustc-link-lib=framework=Metal"); + println!("cargo:rustc-link-lib=framework=MetalKit"); + } + } + + #[cfg(feature = "coreml")] + println!("cargo:rustc-link-lib=static=whisper.coreml"); + #[cfg(feature = "opencl")] + { + println!("cargo:rustc-link-lib=clblast"); + println!("cargo:rustc-link-lib=OpenCL"); + } + #[cfg(feature = "openblas")] + { + println!("cargo:rustc-link-lib=openblas"); + } + #[cfg(feature = "cuda")] + { + println!("cargo:rustc-link-lib=cublas"); + println!("cargo:rustc-link-lib=cudart"); + println!("cargo:rustc-link-lib=cublasLt"); + cfg_if::cfg_if! { + if #[cfg(target_os = "windows")] { + let cuda_path = PathBuf::from(env::var("CUDA_PATH").unwrap()).join("lib/x64"); + println!("cargo:rustc-link-search={}", cuda_path.display()); + } else { + println!("cargo:rustc-link-lib=culibos"); + println!("cargo:rustc-link-search=/usr/local/cuda/lib64"); + println!("cargo:rustc-link-search=/opt/cuda/lib64"); + } + } + } + println!("cargo:rerun-if-changed=wrapper.h"); + + let out = PathBuf::from(env::var("OUT_DIR").unwrap()); + let whisper_root = out.join("whisper.cpp/"); + + if !whisper_root.exists() { + std::fs::create_dir_all(&whisper_root).unwrap(); + fs_extra::dir::copy("./whisper.cpp", &out, &Default::default()).unwrap_or_else(|e| { + panic!( + "Failed to copy whisper sources into {}: {}", + whisper_root.display(), + e + ) + }); + } + + if env::var("WHISPER_DONT_GENERATE_BINDINGS").is_ok() { + let _: u64 = std::fs::copy("src/bindings.rs", out.join("bindings.rs")) + .expect("Failed to copy bindings.rs"); + } else { + let bindings = bindgen::Builder::default() + .header("wrapper.h") + .clang_arg("-I./whisper.cpp") + .parse_callbacks(Box::new(bindgen::CargoCallbacks)) + .generate(); + + match bindings { + Ok(b) => { + let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); + b.write_to_file(out_path.join("bindings.rs")) + .expect("Couldn't write bindings!"); + } + Err(e) => { + println!("cargo:warning=Unable to generate bindings: {}", e); + println!("cargo:warning=Using bundled bindings.rs, which may be out of date"); + // copy src/bindings.rs to OUT_DIR + std::fs::copy("src/bindings.rs", out.join("bindings.rs")) + .expect("Unable to copy bindings.rs"); + } + } + }; + + // stop if we're on docs.rs + if env::var("DOCS_RS").is_ok() { + return; + } + + let mut config = Config::new(&whisper_root); + + config + .profile("Release") + .define("BUILD_SHARED_LIBS", "OFF") + .define("WHISPER_ALL_WARNINGS", "OFF") + .define("WHISPER_ALL_WARNINGS_3RD_PARTY", "OFF") + .define("WHISPER_BUILD_TESTS", "OFF") + .define("WHISPER_BUILD_EXAMPLES", "OFF") + .very_verbose(true) + .pic(true); + + if cfg!(feature = "coreml") { + config.define("WHISPER_COREML", "ON"); + config.define("WHISPER_COREML_ALLOW_FALLBACK", "1"); + } + + if cfg!(feature = "cuda") { + config.define("WHISPER_CUBLAS", "ON"); + } + + if cfg!(feature = "openblas") { + config.define("WHISPER_OPENBLAS", "ON"); + } + + if cfg!(feature = "opencl") { + config.define("WHISPER_CLBLAST", "ON"); + } + + if cfg!(feature = "metal") { + config.define("WHISPER_METAL", "ON"); + } else { + // Metal is enabled by default, so we need to explicitly disable it + config.define("WHISPER_METAL", "OFF"); + } + + let destination = config.build(); + + if env::var("TARGET").unwrap().contains("window") { + println!( + "cargo:rustc-link-search={}", + out.join("build").join("Release").display() + ); + } else { + println!("cargo:rustc-link-search={}", out.join("build").display()); + } + println!("cargo:rustc-link-search=native={}", destination.display()); + println!("cargo:rustc-link-lib=static=whisper"); + + // for whatever reason this file is generated during build and triggers cargo complaining + _ = std::fs::remove_file("bindings/javascript/package.json"); +} + +// From https://github.com/alexcrichton/cc-rs/blob/fba7feded71ee4f63cfe885673ead6d7b4f2f454/src/lib.rs#L2462 +fn get_cpp_link_stdlib(target: &str) -> Option<&'static str> { + if target.contains("msvc") { + None + } else if target.contains("apple") || target.contains("freebsd") || target.contains("openbsd") { + Some("c++") + } else if target.contains("android") { + Some("c++_shared") + } else { + Some("stdc++") + } +} diff --git a/sys/src/bindings.rs b/sys/src/bindings.rs new file mode 100644 index 0000000..1e25f09 --- /dev/null +++ b/sys/src/bindings.rs @@ -0,0 +1,1507 @@ +/* automatically generated by rust-bindgen 0.65.1 */ + +pub const _STDINT_H: u32 = 1; +pub const _FEATURES_H: u32 = 1; +pub const _DEFAULT_SOURCE: u32 = 1; +pub const __GLIBC_USE_ISOC2X: u32 = 0; +pub const __USE_ISOC11: u32 = 1; +pub const __USE_ISOC99: u32 = 1; +pub const __USE_ISOC95: u32 = 1; +pub const __USE_POSIX_IMPLICITLY: u32 = 1; +pub const _POSIX_SOURCE: u32 = 1; +pub const _POSIX_C_SOURCE: u32 = 200809; +pub const __USE_POSIX: u32 = 1; +pub const __USE_POSIX2: u32 = 1; +pub const __USE_POSIX199309: u32 = 1; +pub const __USE_POSIX199506: u32 = 1; +pub const __USE_XOPEN2K: u32 = 1; +pub const __USE_XOPEN2K8: u32 = 1; +pub const _ATFILE_SOURCE: u32 = 1; +pub const __WORDSIZE: u32 = 64; +pub const __WORDSIZE_TIME64_COMPAT32: u32 = 1; +pub const __SYSCALL_WORDSIZE: u32 = 64; +pub const __TIMESIZE: u32 = 64; +pub const __USE_MISC: u32 = 1; +pub const __USE_ATFILE: u32 = 1; +pub const __USE_FORTIFY_LEVEL: u32 = 0; +pub const __GLIBC_USE_DEPRECATED_GETS: u32 = 0; +pub const __GLIBC_USE_DEPRECATED_SCANF: u32 = 0; +pub const _STDC_PREDEF_H: u32 = 1; +pub const __STDC_IEC_559__: u32 = 1; +pub const __STDC_IEC_60559_BFP__: u32 = 201404; +pub const __STDC_IEC_559_COMPLEX__: u32 = 1; +pub const __STDC_IEC_60559_COMPLEX__: u32 = 201404; +pub const __STDC_ISO_10646__: u32 = 201706; +pub const __GNU_LIBRARY__: u32 = 6; +pub const __GLIBC__: u32 = 2; +pub const __GLIBC_MINOR__: u32 = 37; +pub const _SYS_CDEFS_H: u32 = 1; +pub const __glibc_c99_flexarr_available: u32 = 1; +pub const __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI: u32 = 0; +pub const __HAVE_GENERIC_SELECTION: u32 = 1; +pub const __GLIBC_USE_LIB_EXT2: u32 = 0; +pub const __GLIBC_USE_IEC_60559_BFP_EXT: u32 = 0; +pub const __GLIBC_USE_IEC_60559_BFP_EXT_C2X: u32 = 0; +pub const __GLIBC_USE_IEC_60559_EXT: u32 = 0; +pub const __GLIBC_USE_IEC_60559_FUNCS_EXT: u32 = 0; +pub const __GLIBC_USE_IEC_60559_FUNCS_EXT_C2X: u32 = 0; +pub const __GLIBC_USE_IEC_60559_TYPES_EXT: u32 = 0; +pub const _BITS_TYPES_H: u32 = 1; +pub const _BITS_TYPESIZES_H: u32 = 1; +pub const __OFF_T_MATCHES_OFF64_T: u32 = 1; +pub const __INO_T_MATCHES_INO64_T: u32 = 1; +pub const __RLIM_T_MATCHES_RLIM64_T: u32 = 1; +pub const __STATFS_MATCHES_STATFS64: u32 = 1; +pub const __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64: u32 = 1; +pub const __FD_SETSIZE: u32 = 1024; +pub const _BITS_TIME64_H: u32 = 1; +pub const _BITS_WCHAR_H: u32 = 1; +pub const _BITS_STDINT_INTN_H: u32 = 1; +pub const _BITS_STDINT_UINTN_H: u32 = 1; +pub const INT8_MIN: i32 = -128; +pub const INT16_MIN: i32 = -32768; +pub const INT32_MIN: i32 = -2147483648; +pub const INT8_MAX: u32 = 127; +pub const INT16_MAX: u32 = 32767; +pub const INT32_MAX: u32 = 2147483647; +pub const UINT8_MAX: u32 = 255; +pub const UINT16_MAX: u32 = 65535; +pub const UINT32_MAX: u32 = 4294967295; +pub const INT_LEAST8_MIN: i32 = -128; +pub const INT_LEAST16_MIN: i32 = -32768; +pub const INT_LEAST32_MIN: i32 = -2147483648; +pub const INT_LEAST8_MAX: u32 = 127; +pub const INT_LEAST16_MAX: u32 = 32767; +pub const INT_LEAST32_MAX: u32 = 2147483647; +pub const UINT_LEAST8_MAX: u32 = 255; +pub const UINT_LEAST16_MAX: u32 = 65535; +pub const UINT_LEAST32_MAX: u32 = 4294967295; +pub const INT_FAST8_MIN: i32 = -128; +pub const INT_FAST16_MIN: i64 = -9223372036854775808; +pub const INT_FAST32_MIN: i64 = -9223372036854775808; +pub const INT_FAST8_MAX: u32 = 127; +pub const INT_FAST16_MAX: u64 = 9223372036854775807; +pub const INT_FAST32_MAX: u64 = 9223372036854775807; +pub const UINT_FAST8_MAX: u32 = 255; +pub const UINT_FAST16_MAX: i32 = -1; +pub const UINT_FAST32_MAX: i32 = -1; +pub const INTPTR_MIN: i64 = -9223372036854775808; +pub const INTPTR_MAX: u64 = 9223372036854775807; +pub const UINTPTR_MAX: i32 = -1; +pub const PTRDIFF_MIN: i64 = -9223372036854775808; +pub const PTRDIFF_MAX: u64 = 9223372036854775807; +pub const SIG_ATOMIC_MIN: i32 = -2147483648; +pub const SIG_ATOMIC_MAX: u32 = 2147483647; +pub const SIZE_MAX: i32 = -1; +pub const WINT_MIN: u32 = 0; +pub const WINT_MAX: u32 = 4294967295; +pub const __bool_true_false_are_defined: u32 = 1; +pub const true_: u32 = 1; +pub const false_: u32 = 0; +pub const WHISPER_SAMPLE_RATE: u32 = 16000; +pub const WHISPER_N_FFT: u32 = 400; +pub const WHISPER_N_MEL: u32 = 80; +pub const WHISPER_HOP_LENGTH: u32 = 160; +pub const WHISPER_CHUNK_SIZE: u32 = 30; +pub type wchar_t = ::std::os::raw::c_int; +#[repr(C)] +#[repr(align(16))] +#[derive(Debug, Copy, Clone)] +pub struct max_align_t { + pub __clang_max_align_nonce1: ::std::os::raw::c_longlong, + pub __bindgen_padding_0: u64, + pub __clang_max_align_nonce2: u128, +} +#[test] +fn bindgen_test_layout_max_align_t() { + const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 32usize, + concat!("Size of: ", stringify!(max_align_t)) + ); + assert_eq!( + ::std::mem::align_of::(), + 16usize, + concat!("Alignment of ", stringify!(max_align_t)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__clang_max_align_nonce1) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(max_align_t), + "::", + stringify!(__clang_max_align_nonce1) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__clang_max_align_nonce2) as usize - ptr as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(max_align_t), + "::", + stringify!(__clang_max_align_nonce2) + ) + ); +} +pub type __u_char = ::std::os::raw::c_uchar; +pub type __u_short = ::std::os::raw::c_ushort; +pub type __u_int = ::std::os::raw::c_uint; +pub type __u_long = ::std::os::raw::c_ulong; +pub type __int8_t = ::std::os::raw::c_schar; +pub type __uint8_t = ::std::os::raw::c_uchar; +pub type __int16_t = ::std::os::raw::c_short; +pub type __uint16_t = ::std::os::raw::c_ushort; +pub type __int32_t = ::std::os::raw::c_int; +pub type __uint32_t = ::std::os::raw::c_uint; +pub type __int64_t = ::std::os::raw::c_long; +pub type __uint64_t = ::std::os::raw::c_ulong; +pub type __int_least8_t = __int8_t; +pub type __uint_least8_t = __uint8_t; +pub type __int_least16_t = __int16_t; +pub type __uint_least16_t = __uint16_t; +pub type __int_least32_t = __int32_t; +pub type __uint_least32_t = __uint32_t; +pub type __int_least64_t = __int64_t; +pub type __uint_least64_t = __uint64_t; +pub type __quad_t = ::std::os::raw::c_long; +pub type __u_quad_t = ::std::os::raw::c_ulong; +pub type __intmax_t = ::std::os::raw::c_long; +pub type __uintmax_t = ::std::os::raw::c_ulong; +pub type __dev_t = ::std::os::raw::c_ulong; +pub type __uid_t = ::std::os::raw::c_uint; +pub type __gid_t = ::std::os::raw::c_uint; +pub type __ino_t = ::std::os::raw::c_ulong; +pub type __ino64_t = ::std::os::raw::c_ulong; +pub type __mode_t = ::std::os::raw::c_uint; +pub type __nlink_t = ::std::os::raw::c_ulong; +pub type __off_t = ::std::os::raw::c_long; +pub type __off64_t = ::std::os::raw::c_long; +pub type __pid_t = ::std::os::raw::c_int; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __fsid_t { + pub __val: [::std::os::raw::c_int; 2usize], +} +#[test] +fn bindgen_test_layout___fsid_t() { + const UNINIT: ::std::mem::MaybeUninit<__fsid_t> = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::<__fsid_t>(), + 8usize, + concat!("Size of: ", stringify!(__fsid_t)) + ); + assert_eq!( + ::std::mem::align_of::<__fsid_t>(), + 4usize, + concat!("Alignment of ", stringify!(__fsid_t)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__val) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(__fsid_t), + "::", + stringify!(__val) + ) + ); +} +pub type __clock_t = ::std::os::raw::c_long; +pub type __rlim_t = ::std::os::raw::c_ulong; +pub type __rlim64_t = ::std::os::raw::c_ulong; +pub type __id_t = ::std::os::raw::c_uint; +pub type __time_t = ::std::os::raw::c_long; +pub type __useconds_t = ::std::os::raw::c_uint; +pub type __suseconds_t = ::std::os::raw::c_long; +pub type __suseconds64_t = ::std::os::raw::c_long; +pub type __daddr_t = ::std::os::raw::c_int; +pub type __key_t = ::std::os::raw::c_int; +pub type __clockid_t = ::std::os::raw::c_int; +pub type __timer_t = *mut ::std::os::raw::c_void; +pub type __blksize_t = ::std::os::raw::c_long; +pub type __blkcnt_t = ::std::os::raw::c_long; +pub type __blkcnt64_t = ::std::os::raw::c_long; +pub type __fsblkcnt_t = ::std::os::raw::c_ulong; +pub type __fsblkcnt64_t = ::std::os::raw::c_ulong; +pub type __fsfilcnt_t = ::std::os::raw::c_ulong; +pub type __fsfilcnt64_t = ::std::os::raw::c_ulong; +pub type __fsword_t = ::std::os::raw::c_long; +pub type __ssize_t = ::std::os::raw::c_long; +pub type __syscall_slong_t = ::std::os::raw::c_long; +pub type __syscall_ulong_t = ::std::os::raw::c_ulong; +pub type __loff_t = __off64_t; +pub type __caddr_t = *mut ::std::os::raw::c_char; +pub type __intptr_t = ::std::os::raw::c_long; +pub type __socklen_t = ::std::os::raw::c_uint; +pub type __sig_atomic_t = ::std::os::raw::c_int; +pub type int_least8_t = __int_least8_t; +pub type int_least16_t = __int_least16_t; +pub type int_least32_t = __int_least32_t; +pub type int_least64_t = __int_least64_t; +pub type uint_least8_t = __uint_least8_t; +pub type uint_least16_t = __uint_least16_t; +pub type uint_least32_t = __uint_least32_t; +pub type uint_least64_t = __uint_least64_t; +pub type int_fast8_t = ::std::os::raw::c_schar; +pub type int_fast16_t = ::std::os::raw::c_long; +pub type int_fast32_t = ::std::os::raw::c_long; +pub type int_fast64_t = ::std::os::raw::c_long; +pub type uint_fast8_t = ::std::os::raw::c_uchar; +pub type uint_fast16_t = ::std::os::raw::c_ulong; +pub type uint_fast32_t = ::std::os::raw::c_ulong; +pub type uint_fast64_t = ::std::os::raw::c_ulong; +pub type intmax_t = __intmax_t; +pub type uintmax_t = __uintmax_t; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct whisper_context { + _unused: [u8; 0], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct whisper_state { + _unused: [u8; 0], +} +pub type whisper_token = ::std::os::raw::c_int; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct whisper_token_data { + pub id: whisper_token, + pub tid: whisper_token, + pub p: f32, + pub plog: f32, + pub pt: f32, + pub ptsum: f32, + pub t0: i64, + pub t1: i64, + pub vlen: f32, +} +#[test] +fn bindgen_test_layout_whisper_token_data() { + const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 48usize, + concat!("Size of: ", stringify!(whisper_token_data)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(whisper_token_data)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).id) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(whisper_token_data), + "::", + stringify!(id) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).tid) as usize - ptr as usize }, + 4usize, + concat!( + "Offset of field: ", + stringify!(whisper_token_data), + "::", + stringify!(tid) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).p) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(whisper_token_data), + "::", + stringify!(p) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).plog) as usize - ptr as usize }, + 12usize, + concat!( + "Offset of field: ", + stringify!(whisper_token_data), + "::", + stringify!(plog) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).pt) as usize - ptr as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(whisper_token_data), + "::", + stringify!(pt) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).ptsum) as usize - ptr as usize }, + 20usize, + concat!( + "Offset of field: ", + stringify!(whisper_token_data), + "::", + stringify!(ptsum) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).t0) as usize - ptr as usize }, + 24usize, + concat!( + "Offset of field: ", + stringify!(whisper_token_data), + "::", + stringify!(t0) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).t1) as usize - ptr as usize }, + 32usize, + concat!( + "Offset of field: ", + stringify!(whisper_token_data), + "::", + stringify!(t1) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).vlen) as usize - ptr as usize }, + 40usize, + concat!( + "Offset of field: ", + stringify!(whisper_token_data), + "::", + stringify!(vlen) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct whisper_model_loader { + pub context: *mut ::std::os::raw::c_void, + pub read: ::std::option::Option< + unsafe extern "C" fn( + ctx: *mut ::std::os::raw::c_void, + output: *mut ::std::os::raw::c_void, + read_size: usize, + ) -> usize, + >, + pub eof: ::std::option::Option bool>, + pub close: ::std::option::Option, +} +#[test] +fn bindgen_test_layout_whisper_model_loader() { + const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 32usize, + concat!("Size of: ", stringify!(whisper_model_loader)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(whisper_model_loader)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).context) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(whisper_model_loader), + "::", + stringify!(context) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).read) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(whisper_model_loader), + "::", + stringify!(read) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).eof) as usize - ptr as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(whisper_model_loader), + "::", + stringify!(eof) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).close) as usize - ptr as usize }, + 24usize, + concat!( + "Offset of field: ", + stringify!(whisper_model_loader), + "::", + stringify!(close) + ) + ); +} +extern "C" { + pub fn whisper_init_from_file( + path_model: *const ::std::os::raw::c_char, + ) -> *mut whisper_context; +} +extern "C" { + pub fn whisper_init_from_buffer( + buffer: *mut ::std::os::raw::c_void, + buffer_size: usize, + ) -> *mut whisper_context; +} +extern "C" { + pub fn whisper_init(loader: *mut whisper_model_loader) -> *mut whisper_context; +} +extern "C" { + pub fn whisper_init_from_file_no_state( + path_model: *const ::std::os::raw::c_char, + ) -> *mut whisper_context; +} +extern "C" { + pub fn whisper_init_from_buffer_no_state( + buffer: *mut ::std::os::raw::c_void, + buffer_size: usize, + ) -> *mut whisper_context; +} +extern "C" { + pub fn whisper_init_no_state(loader: *mut whisper_model_loader) -> *mut whisper_context; +} +extern "C" { + pub fn whisper_init_state(ctx: *mut whisper_context) -> *mut whisper_state; +} +extern "C" { + pub fn whisper_free(ctx: *mut whisper_context); +} +extern "C" { + pub fn whisper_free_state(state: *mut whisper_state); +} +extern "C" { + pub fn whisper_pcm_to_mel( + ctx: *mut whisper_context, + samples: *const f32, + n_samples: ::std::os::raw::c_int, + n_threads: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn whisper_pcm_to_mel_with_state( + ctx: *mut whisper_context, + state: *mut whisper_state, + samples: *const f32, + n_samples: ::std::os::raw::c_int, + n_threads: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn whisper_pcm_to_mel_phase_vocoder( + ctx: *mut whisper_context, + samples: *const f32, + n_samples: ::std::os::raw::c_int, + n_threads: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn whisper_pcm_to_mel_phase_vocoder_with_state( + ctx: *mut whisper_context, + state: *mut whisper_state, + samples: *const f32, + n_samples: ::std::os::raw::c_int, + n_threads: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn whisper_set_mel( + ctx: *mut whisper_context, + data: *const f32, + n_len: ::std::os::raw::c_int, + n_mel: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn whisper_set_mel_with_state( + ctx: *mut whisper_context, + state: *mut whisper_state, + data: *const f32, + n_len: ::std::os::raw::c_int, + n_mel: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn whisper_encode( + ctx: *mut whisper_context, + offset: ::std::os::raw::c_int, + n_threads: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn whisper_encode_with_state( + ctx: *mut whisper_context, + state: *mut whisper_state, + offset: ::std::os::raw::c_int, + n_threads: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn whisper_decode( + ctx: *mut whisper_context, + tokens: *const whisper_token, + n_tokens: ::std::os::raw::c_int, + n_past: ::std::os::raw::c_int, + n_threads: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn whisper_decode_with_state( + ctx: *mut whisper_context, + state: *mut whisper_state, + tokens: *const whisper_token, + n_tokens: ::std::os::raw::c_int, + n_past: ::std::os::raw::c_int, + n_threads: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn whisper_tokenize( + ctx: *mut whisper_context, + text: *const ::std::os::raw::c_char, + tokens: *mut whisper_token, + n_max_tokens: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn whisper_lang_max_id() -> ::std::os::raw::c_int; +} +extern "C" { + pub fn whisper_lang_id(lang: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn whisper_lang_str(id: ::std::os::raw::c_int) -> *const ::std::os::raw::c_char; +} +extern "C" { + pub fn whisper_lang_auto_detect( + ctx: *mut whisper_context, + offset_ms: ::std::os::raw::c_int, + n_threads: ::std::os::raw::c_int, + lang_probs: *mut f32, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn whisper_lang_auto_detect_with_state( + ctx: *mut whisper_context, + state: *mut whisper_state, + offset_ms: ::std::os::raw::c_int, + n_threads: ::std::os::raw::c_int, + lang_probs: *mut f32, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn whisper_n_len(ctx: *mut whisper_context) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn whisper_n_len_from_state(state: *mut whisper_state) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn whisper_n_vocab(ctx: *mut whisper_context) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn whisper_n_text_ctx(ctx: *mut whisper_context) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn whisper_n_audio_ctx(ctx: *mut whisper_context) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn whisper_is_multilingual(ctx: *mut whisper_context) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn whisper_model_n_vocab(ctx: *mut whisper_context) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn whisper_model_n_audio_ctx(ctx: *mut whisper_context) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn whisper_model_n_audio_state(ctx: *mut whisper_context) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn whisper_model_n_audio_head(ctx: *mut whisper_context) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn whisper_model_n_audio_layer(ctx: *mut whisper_context) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn whisper_model_n_text_ctx(ctx: *mut whisper_context) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn whisper_model_n_text_state(ctx: *mut whisper_context) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn whisper_model_n_text_head(ctx: *mut whisper_context) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn whisper_model_n_text_layer(ctx: *mut whisper_context) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn whisper_model_n_mels(ctx: *mut whisper_context) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn whisper_model_ftype(ctx: *mut whisper_context) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn whisper_model_type(ctx: *mut whisper_context) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn whisper_get_logits(ctx: *mut whisper_context) -> *mut f32; +} +extern "C" { + pub fn whisper_get_logits_from_state(state: *mut whisper_state) -> *mut f32; +} +extern "C" { + pub fn whisper_token_to_str( + ctx: *mut whisper_context, + token: whisper_token, + ) -> *const ::std::os::raw::c_char; +} +extern "C" { + pub fn whisper_model_type_readable(ctx: *mut whisper_context) -> *const ::std::os::raw::c_char; +} +extern "C" { + pub fn whisper_token_eot(ctx: *mut whisper_context) -> whisper_token; +} +extern "C" { + pub fn whisper_token_sot(ctx: *mut whisper_context) -> whisper_token; +} +extern "C" { + pub fn whisper_token_prev(ctx: *mut whisper_context) -> whisper_token; +} +extern "C" { + pub fn whisper_token_solm(ctx: *mut whisper_context) -> whisper_token; +} +extern "C" { + pub fn whisper_token_not(ctx: *mut whisper_context) -> whisper_token; +} +extern "C" { + pub fn whisper_token_beg(ctx: *mut whisper_context) -> whisper_token; +} +extern "C" { + pub fn whisper_token_lang( + ctx: *mut whisper_context, + lang_id: ::std::os::raw::c_int, + ) -> whisper_token; +} +extern "C" { + pub fn whisper_token_translate() -> whisper_token; +} +extern "C" { + pub fn whisper_token_transcribe() -> whisper_token; +} +extern "C" { + pub fn whisper_print_timings(ctx: *mut whisper_context); +} +extern "C" { + pub fn whisper_reset_timings(ctx: *mut whisper_context); +} +extern "C" { + pub fn whisper_print_system_info() -> *const ::std::os::raw::c_char; +} +pub const whisper_sampling_strategy_WHISPER_SAMPLING_GREEDY: whisper_sampling_strategy = 0; +pub const whisper_sampling_strategy_WHISPER_SAMPLING_BEAM_SEARCH: whisper_sampling_strategy = 1; +pub type whisper_sampling_strategy = ::std::os::raw::c_uint; +pub type whisper_new_segment_callback = ::std::option::Option< + unsafe extern "C" fn( + ctx: *mut whisper_context, + state: *mut whisper_state, + n_new: ::std::os::raw::c_int, + user_data: *mut ::std::os::raw::c_void, + ), +>; +pub type whisper_progress_callback = ::std::option::Option< + unsafe extern "C" fn( + ctx: *mut whisper_context, + state: *mut whisper_state, + progress: ::std::os::raw::c_int, + user_data: *mut ::std::os::raw::c_void, + ), +>; +pub type whisper_encoder_begin_callback = ::std::option::Option< + unsafe extern "C" fn( + ctx: *mut whisper_context, + state: *mut whisper_state, + user_data: *mut ::std::os::raw::c_void, + ) -> bool, +>; +pub type whisper_logits_filter_callback = ::std::option::Option< + unsafe extern "C" fn( + ctx: *mut whisper_context, + state: *mut whisper_state, + tokens: *const whisper_token_data, + n_tokens: ::std::os::raw::c_int, + logits: *mut f32, + user_data: *mut ::std::os::raw::c_void, + ), +>; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct whisper_full_params { + pub strategy: whisper_sampling_strategy, + pub n_threads: ::std::os::raw::c_int, + pub n_max_text_ctx: ::std::os::raw::c_int, + pub offset_ms: ::std::os::raw::c_int, + pub duration_ms: ::std::os::raw::c_int, + pub translate: bool, + pub no_context: bool, + pub single_segment: bool, + pub print_special: bool, + pub print_progress: bool, + pub print_realtime: bool, + pub print_timestamps: bool, + pub token_timestamps: bool, + pub thold_pt: f32, + pub thold_ptsum: f32, + pub max_len: ::std::os::raw::c_int, + pub split_on_word: bool, + pub max_tokens: ::std::os::raw::c_int, + pub speed_up: bool, + pub audio_ctx: ::std::os::raw::c_int, + pub initial_prompt: *const ::std::os::raw::c_char, + pub prompt_tokens: *const whisper_token, + pub prompt_n_tokens: ::std::os::raw::c_int, + pub language: *const ::std::os::raw::c_char, + pub detect_language: bool, + pub suppress_blank: bool, + pub suppress_non_speech_tokens: bool, + pub temperature: f32, + pub max_initial_ts: f32, + pub length_penalty: f32, + pub temperature_inc: f32, + pub entropy_thold: f32, + pub logprob_thold: f32, + pub no_speech_thold: f32, + pub greedy: whisper_full_params__bindgen_ty_1, + pub beam_search: whisper_full_params__bindgen_ty_2, + pub new_segment_callback: whisper_new_segment_callback, + pub new_segment_callback_user_data: *mut ::std::os::raw::c_void, + pub progress_callback: whisper_progress_callback, + pub progress_callback_user_data: *mut ::std::os::raw::c_void, + pub encoder_begin_callback: whisper_encoder_begin_callback, + pub encoder_begin_callback_user_data: *mut ::std::os::raw::c_void, + pub logits_filter_callback: whisper_logits_filter_callback, + pub logits_filter_callback_user_data: *mut ::std::os::raw::c_void, +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct whisper_full_params__bindgen_ty_1 { + pub best_of: ::std::os::raw::c_int, +} +#[test] +fn bindgen_test_layout_whisper_full_params__bindgen_ty_1() { + const UNINIT: ::std::mem::MaybeUninit = + ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 4usize, + concat!("Size of: ", stringify!(whisper_full_params__bindgen_ty_1)) + ); + assert_eq!( + ::std::mem::align_of::(), + 4usize, + concat!( + "Alignment of ", + stringify!(whisper_full_params__bindgen_ty_1) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).best_of) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(whisper_full_params__bindgen_ty_1), + "::", + stringify!(best_of) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct whisper_full_params__bindgen_ty_2 { + pub beam_size: ::std::os::raw::c_int, + pub patience: f32, +} +#[test] +fn bindgen_test_layout_whisper_full_params__bindgen_ty_2() { + const UNINIT: ::std::mem::MaybeUninit = + ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 8usize, + concat!("Size of: ", stringify!(whisper_full_params__bindgen_ty_2)) + ); + assert_eq!( + ::std::mem::align_of::(), + 4usize, + concat!( + "Alignment of ", + stringify!(whisper_full_params__bindgen_ty_2) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).beam_size) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(whisper_full_params__bindgen_ty_2), + "::", + stringify!(beam_size) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).patience) as usize - ptr as usize }, + 4usize, + concat!( + "Offset of field: ", + stringify!(whisper_full_params__bindgen_ty_2), + "::", + stringify!(patience) + ) + ); +} +#[test] +fn bindgen_test_layout_whisper_full_params() { + const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 200usize, + concat!("Size of: ", stringify!(whisper_full_params)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(whisper_full_params)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).strategy) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(whisper_full_params), + "::", + stringify!(strategy) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).n_threads) as usize - ptr as usize }, + 4usize, + concat!( + "Offset of field: ", + stringify!(whisper_full_params), + "::", + stringify!(n_threads) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).n_max_text_ctx) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(whisper_full_params), + "::", + stringify!(n_max_text_ctx) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).offset_ms) as usize - ptr as usize }, + 12usize, + concat!( + "Offset of field: ", + stringify!(whisper_full_params), + "::", + stringify!(offset_ms) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).duration_ms) as usize - ptr as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(whisper_full_params), + "::", + stringify!(duration_ms) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).translate) as usize - ptr as usize }, + 20usize, + concat!( + "Offset of field: ", + stringify!(whisper_full_params), + "::", + stringify!(translate) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).no_context) as usize - ptr as usize }, + 21usize, + concat!( + "Offset of field: ", + stringify!(whisper_full_params), + "::", + stringify!(no_context) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).single_segment) as usize - ptr as usize }, + 22usize, + concat!( + "Offset of field: ", + stringify!(whisper_full_params), + "::", + stringify!(single_segment) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).print_special) as usize - ptr as usize }, + 23usize, + concat!( + "Offset of field: ", + stringify!(whisper_full_params), + "::", + stringify!(print_special) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).print_progress) as usize - ptr as usize }, + 24usize, + concat!( + "Offset of field: ", + stringify!(whisper_full_params), + "::", + stringify!(print_progress) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).print_realtime) as usize - ptr as usize }, + 25usize, + concat!( + "Offset of field: ", + stringify!(whisper_full_params), + "::", + stringify!(print_realtime) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).print_timestamps) as usize - ptr as usize }, + 26usize, + concat!( + "Offset of field: ", + stringify!(whisper_full_params), + "::", + stringify!(print_timestamps) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).token_timestamps) as usize - ptr as usize }, + 27usize, + concat!( + "Offset of field: ", + stringify!(whisper_full_params), + "::", + stringify!(token_timestamps) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).thold_pt) as usize - ptr as usize }, + 28usize, + concat!( + "Offset of field: ", + stringify!(whisper_full_params), + "::", + stringify!(thold_pt) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).thold_ptsum) as usize - ptr as usize }, + 32usize, + concat!( + "Offset of field: ", + stringify!(whisper_full_params), + "::", + stringify!(thold_ptsum) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).max_len) as usize - ptr as usize }, + 36usize, + concat!( + "Offset of field: ", + stringify!(whisper_full_params), + "::", + stringify!(max_len) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).split_on_word) as usize - ptr as usize }, + 40usize, + concat!( + "Offset of field: ", + stringify!(whisper_full_params), + "::", + stringify!(split_on_word) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).max_tokens) as usize - ptr as usize }, + 44usize, + concat!( + "Offset of field: ", + stringify!(whisper_full_params), + "::", + stringify!(max_tokens) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).speed_up) as usize - ptr as usize }, + 48usize, + concat!( + "Offset of field: ", + stringify!(whisper_full_params), + "::", + stringify!(speed_up) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).audio_ctx) as usize - ptr as usize }, + 52usize, + concat!( + "Offset of field: ", + stringify!(whisper_full_params), + "::", + stringify!(audio_ctx) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).initial_prompt) as usize - ptr as usize }, + 56usize, + concat!( + "Offset of field: ", + stringify!(whisper_full_params), + "::", + stringify!(initial_prompt) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).prompt_tokens) as usize - ptr as usize }, + 64usize, + concat!( + "Offset of field: ", + stringify!(whisper_full_params), + "::", + stringify!(prompt_tokens) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).prompt_n_tokens) as usize - ptr as usize }, + 72usize, + concat!( + "Offset of field: ", + stringify!(whisper_full_params), + "::", + stringify!(prompt_n_tokens) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).language) as usize - ptr as usize }, + 80usize, + concat!( + "Offset of field: ", + stringify!(whisper_full_params), + "::", + stringify!(language) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).detect_language) as usize - ptr as usize }, + 88usize, + concat!( + "Offset of field: ", + stringify!(whisper_full_params), + "::", + stringify!(detect_language) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).suppress_blank) as usize - ptr as usize }, + 89usize, + concat!( + "Offset of field: ", + stringify!(whisper_full_params), + "::", + stringify!(suppress_blank) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).suppress_non_speech_tokens) as usize - ptr as usize }, + 90usize, + concat!( + "Offset of field: ", + stringify!(whisper_full_params), + "::", + stringify!(suppress_non_speech_tokens) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).temperature) as usize - ptr as usize }, + 92usize, + concat!( + "Offset of field: ", + stringify!(whisper_full_params), + "::", + stringify!(temperature) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).max_initial_ts) as usize - ptr as usize }, + 96usize, + concat!( + "Offset of field: ", + stringify!(whisper_full_params), + "::", + stringify!(max_initial_ts) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).length_penalty) as usize - ptr as usize }, + 100usize, + concat!( + "Offset of field: ", + stringify!(whisper_full_params), + "::", + stringify!(length_penalty) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).temperature_inc) as usize - ptr as usize }, + 104usize, + concat!( + "Offset of field: ", + stringify!(whisper_full_params), + "::", + stringify!(temperature_inc) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).entropy_thold) as usize - ptr as usize }, + 108usize, + concat!( + "Offset of field: ", + stringify!(whisper_full_params), + "::", + stringify!(entropy_thold) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).logprob_thold) as usize - ptr as usize }, + 112usize, + concat!( + "Offset of field: ", + stringify!(whisper_full_params), + "::", + stringify!(logprob_thold) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).no_speech_thold) as usize - ptr as usize }, + 116usize, + concat!( + "Offset of field: ", + stringify!(whisper_full_params), + "::", + stringify!(no_speech_thold) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).greedy) as usize - ptr as usize }, + 120usize, + concat!( + "Offset of field: ", + stringify!(whisper_full_params), + "::", + stringify!(greedy) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).beam_search) as usize - ptr as usize }, + 124usize, + concat!( + "Offset of field: ", + stringify!(whisper_full_params), + "::", + stringify!(beam_search) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).new_segment_callback) as usize - ptr as usize }, + 136usize, + concat!( + "Offset of field: ", + stringify!(whisper_full_params), + "::", + stringify!(new_segment_callback) + ) + ); + assert_eq!( + unsafe { + ::std::ptr::addr_of!((*ptr).new_segment_callback_user_data) as usize - ptr as usize + }, + 144usize, + concat!( + "Offset of field: ", + stringify!(whisper_full_params), + "::", + stringify!(new_segment_callback_user_data) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).progress_callback) as usize - ptr as usize }, + 152usize, + concat!( + "Offset of field: ", + stringify!(whisper_full_params), + "::", + stringify!(progress_callback) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).progress_callback_user_data) as usize - ptr as usize }, + 160usize, + concat!( + "Offset of field: ", + stringify!(whisper_full_params), + "::", + stringify!(progress_callback_user_data) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).encoder_begin_callback) as usize - ptr as usize }, + 168usize, + concat!( + "Offset of field: ", + stringify!(whisper_full_params), + "::", + stringify!(encoder_begin_callback) + ) + ); + assert_eq!( + unsafe { + ::std::ptr::addr_of!((*ptr).encoder_begin_callback_user_data) as usize - ptr as usize + }, + 176usize, + concat!( + "Offset of field: ", + stringify!(whisper_full_params), + "::", + stringify!(encoder_begin_callback_user_data) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).logits_filter_callback) as usize - ptr as usize }, + 184usize, + concat!( + "Offset of field: ", + stringify!(whisper_full_params), + "::", + stringify!(logits_filter_callback) + ) + ); + assert_eq!( + unsafe { + ::std::ptr::addr_of!((*ptr).logits_filter_callback_user_data) as usize - ptr as usize + }, + 192usize, + concat!( + "Offset of field: ", + stringify!(whisper_full_params), + "::", + stringify!(logits_filter_callback_user_data) + ) + ); +} +extern "C" { + pub fn whisper_full_default_params(strategy: whisper_sampling_strategy) -> whisper_full_params; +} +extern "C" { + pub fn whisper_full( + ctx: *mut whisper_context, + params: whisper_full_params, + samples: *const f32, + n_samples: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn whisper_full_with_state( + ctx: *mut whisper_context, + state: *mut whisper_state, + params: whisper_full_params, + samples: *const f32, + n_samples: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn whisper_full_parallel( + ctx: *mut whisper_context, + params: whisper_full_params, + samples: *const f32, + n_samples: ::std::os::raw::c_int, + n_processors: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn whisper_full_n_segments(ctx: *mut whisper_context) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn whisper_full_n_segments_from_state(state: *mut whisper_state) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn whisper_full_lang_id(ctx: *mut whisper_context) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn whisper_full_lang_id_from_state(state: *mut whisper_state) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn whisper_full_get_segment_t0( + ctx: *mut whisper_context, + i_segment: ::std::os::raw::c_int, + ) -> i64; +} +extern "C" { + pub fn whisper_full_get_segment_t0_from_state( + state: *mut whisper_state, + i_segment: ::std::os::raw::c_int, + ) -> i64; +} +extern "C" { + pub fn whisper_full_get_segment_t1( + ctx: *mut whisper_context, + i_segment: ::std::os::raw::c_int, + ) -> i64; +} +extern "C" { + pub fn whisper_full_get_segment_t1_from_state( + state: *mut whisper_state, + i_segment: ::std::os::raw::c_int, + ) -> i64; +} +extern "C" { + pub fn whisper_full_get_segment_text( + ctx: *mut whisper_context, + i_segment: ::std::os::raw::c_int, + ) -> *const ::std::os::raw::c_char; +} +extern "C" { + pub fn whisper_full_get_segment_text_from_state( + state: *mut whisper_state, + i_segment: ::std::os::raw::c_int, + ) -> *const ::std::os::raw::c_char; +} +extern "C" { + pub fn whisper_full_n_tokens( + ctx: *mut whisper_context, + i_segment: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn whisper_full_n_tokens_from_state( + state: *mut whisper_state, + i_segment: ::std::os::raw::c_int, + ) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn whisper_full_get_token_text( + ctx: *mut whisper_context, + i_segment: ::std::os::raw::c_int, + i_token: ::std::os::raw::c_int, + ) -> *const ::std::os::raw::c_char; +} +extern "C" { + pub fn whisper_full_get_token_text_from_state( + ctx: *mut whisper_context, + state: *mut whisper_state, + i_segment: ::std::os::raw::c_int, + i_token: ::std::os::raw::c_int, + ) -> *const ::std::os::raw::c_char; +} +extern "C" { + pub fn whisper_full_get_token_id( + ctx: *mut whisper_context, + i_segment: ::std::os::raw::c_int, + i_token: ::std::os::raw::c_int, + ) -> whisper_token; +} +extern "C" { + pub fn whisper_full_get_token_id_from_state( + state: *mut whisper_state, + i_segment: ::std::os::raw::c_int, + i_token: ::std::os::raw::c_int, + ) -> whisper_token; +} +extern "C" { + pub fn whisper_full_get_token_data( + ctx: *mut whisper_context, + i_segment: ::std::os::raw::c_int, + i_token: ::std::os::raw::c_int, + ) -> whisper_token_data; +} +extern "C" { + pub fn whisper_full_get_token_data_from_state( + state: *mut whisper_state, + i_segment: ::std::os::raw::c_int, + i_token: ::std::os::raw::c_int, + ) -> whisper_token_data; +} +extern "C" { + pub fn whisper_full_get_token_p( + ctx: *mut whisper_context, + i_segment: ::std::os::raw::c_int, + i_token: ::std::os::raw::c_int, + ) -> f32; +} +extern "C" { + pub fn whisper_full_get_token_p_from_state( + state: *mut whisper_state, + i_segment: ::std::os::raw::c_int, + i_token: ::std::os::raw::c_int, + ) -> f32; +} +extern "C" { + pub fn whisper_bench_memcpy(n_threads: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn whisper_bench_memcpy_str( + n_threads: ::std::os::raw::c_int, + ) -> *const ::std::os::raw::c_char; +} +extern "C" { + pub fn whisper_bench_ggml_mul_mat(n_threads: ::std::os::raw::c_int) -> ::std::os::raw::c_int; +} +extern "C" { + pub fn whisper_bench_ggml_mul_mat_str( + n_threads: ::std::os::raw::c_int, + ) -> *const ::std::os::raw::c_char; +} diff --git a/sys/src/lib.rs b/sys/src/lib.rs new file mode 100644 index 0000000..a38a13a --- /dev/null +++ b/sys/src/lib.rs @@ -0,0 +1,5 @@ +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] + +include!(concat!(env!("OUT_DIR"), "/bindings.rs")); diff --git a/sys/whisper.cpp/.gitignore b/sys/whisper.cpp/.gitignore new file mode 100644 index 0000000..30fca39 --- /dev/null +++ b/sys/whisper.cpp/.gitignore @@ -0,0 +1,61 @@ +*.o +*.a +.cache/ +.coreml/ +.test/ +.vs/ +.vscode/ +.DS_Store + +build/ +build-coreml/ +build-em/ +build-debug/ +build-release/ +build-rwdi/ +build-static/ +build-cublas/ +build-no-accel/ +build-sanitize-addr/ +build-sanitize-thread/ + +# SPM +.build/ +.swiftpm +*.metallib + +/main +/stream +/command +/talk +/talk-llama +/bench +/quantize +/server +/lsp + +arm_neon.h +sync.sh +libwhisper.a +libwhisper.so +compile_commands.json + +examples/arm_neon.h +examples/whisper.objc/whisper.objc.xcodeproj/xcshareddata +examples/whisper.objc/whisper.objc.xcodeproj/xcuserdata/ +examples/whisper.objc/whisper.objc.xcodeproj/project.xcworkspace/xcuserdata + +extra/bench-gg.txt + +models/*.mlmodel +models/*.mlmodelc +models/*.mlpackage +bindings/java/.gradle/ +bindings/java/.idea/ +.idea/ + +benchmark_results.csv +cmake-build-debug/ +.cxx/ +.gradle/ +local.properties \ No newline at end of file diff --git a/sys/whisper.cpp/.gitmodules b/sys/whisper.cpp/.gitmodules new file mode 100644 index 0000000..94d7ce1 --- /dev/null +++ b/sys/whisper.cpp/.gitmodules @@ -0,0 +1,3 @@ +[submodule "bindings/ios"] + path = bindings/ios + url = https://github.com/ggerganov/whisper.spm diff --git a/sys/whisper.cpp/CMakeLists.txt b/sys/whisper.cpp/CMakeLists.txt new file mode 100644 index 0000000..0ac1103 --- /dev/null +++ b/sys/whisper.cpp/CMakeLists.txt @@ -0,0 +1,565 @@ +cmake_minimum_required (VERSION 3.5) + +project(whisper.cpp VERSION 1.5.1) + +# Add path to modules +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/") + +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) + +if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) + set(WHISPER_STANDALONE ON) + include(GitVars) + include(BuildTypes) + + # configure project version + if (EXISTS "${CMAKE_SOURCE_DIR}/bindings/ios/Makefile-tmpl") + configure_file(${CMAKE_SOURCE_DIR}/bindings/ios/Makefile-tmpl ${CMAKE_SOURCE_DIR}/bindings/ios/Makefile @ONLY) + endif() + configure_file(${CMAKE_SOURCE_DIR}/bindings/javascript/package-tmpl.json ${CMAKE_SOURCE_DIR}/bindings/javascript/package.json @ONLY) +else() + set(WHISPER_STANDALONE OFF) +endif() + +if (EMSCRIPTEN) + set(BUILD_SHARED_LIBS_DEFAULT OFF) + + option(WHISPER_WASM_SINGLE_FILE "whisper: embed WASM inside the generated whisper.js" ON) +else() + if (MINGW) + set(BUILD_SHARED_LIBS_DEFAULT OFF) + else() + set(BUILD_SHARED_LIBS_DEFAULT ON) + endif() +endif() + +# options + +if (APPLE) + set(WHISPER_METAL_DEFAULT ON) +else() + set(WHISPER_METAL_DEFAULT OFF) +endif() + +option(BUILD_SHARED_LIBS "whisper: build shared libs" ${BUILD_SHARED_LIBS_DEFAULT}) + +option(WHISPER_ALL_WARNINGS "whisper: enable all compiler warnings" ON) +option(WHISPER_ALL_WARNINGS_3RD_PARTY "whisper: enable all compiler warnings in 3rd party libs" OFF) + +option(WHISPER_SANITIZE_THREAD "whisper: enable thread sanitizer" OFF) +option(WHISPER_SANITIZE_ADDRESS "whisper: enable address sanitizer" OFF) +option(WHISPER_SANITIZE_UNDEFINED "whisper: enable undefined sanitizer" OFF) + +option(WHISPER_BUILD_TESTS "whisper: build tests" ${WHISPER_STANDALONE}) +option(WHISPER_BUILD_EXAMPLES "whisper: build examples" ${WHISPER_STANDALONE}) + +option(WHISPER_SDL2 "whisper: support for libSDL2" OFF) + +option(WHISPER_NO_AVX "whisper: disable AVX" OFF) +option(WHISPER_NO_AVX2 "whisper: disable AVX2" OFF) +option(WHISPER_NO_FMA "whisper: disable FMA" OFF) +option(WHISPER_NO_F16C "whisper: disable F16c" OFF) + +option(WHISPER_OPENVINO "whisper: support for OpenVINO" OFF) + +if (APPLE) + option(WHISPER_NO_ACCELERATE "whisper: disable Accelerate framework" OFF) + option(WHISPER_METAL "whisper: use Metal" ${WHISPER_METAL_DEFAULT}) + option(WHISPER_METAL_NDEBUG "whisper: disable Metal debugging" OFF) + option(WHISPER_COREML "whisper: enable Core ML framework" OFF) + option(WHISPER_COREML_ALLOW_FALLBACK "whisper: allow non-CoreML fallback" OFF) +else() + option(WHISPER_BLAS "whisper: use BLAS libraries" OFF) + option(WHISPER_BLAS_VENDOR "whisper: BLAS library vendor" Generic) + option(WHISPER_OPENBLAS "whisper: prefer OpenBLAS" OFF) + option(WHISPER_CUBLAS "whisper: support for cuBLAS" OFF) + option(WHISPER_HIPBLAS "whisper: support for hipBLAS" OFF) + option(WHISPER_CLBLAST "whisper: use CLBlast" OFF) +endif() + +option(WHISPER_PERF "whisper: enable perf timings" OFF) + +# sanitizers + +if (NOT MSVC) + if (WHISPER_SANITIZE_THREAD) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=thread") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread") + endif() + + if (WHISPER_SANITIZE_ADDRESS) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fno-omit-frame-pointer") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer") + endif() + + if (WHISPER_SANITIZE_UNDEFINED) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=undefined") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined") + endif() +endif() + +#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffast-math") +#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=native") + +# dependencies + +find_package(Threads REQUIRED) + +# on APPLE +if (APPLE) + # include Accelerate framework + if (NOT WHISPER_NO_ACCELERATE) + find_library(ACCELERATE_FRAMEWORK Accelerate) + + if (ACCELERATE_FRAMEWORK) + message(STATUS "Accelerate framework found") + + set(WHISPER_EXTRA_LIBS ${WHISPER_EXTRA_LIBS} ${ACCELERATE_FRAMEWORK}) + set(WHISPER_EXTRA_FLAGS ${WHISPER_EXTRA_FLAGS} -DGGML_USE_ACCELERATE) + else() + message(FATAL_ERROR "Accelerate framework not found") + endif() + endif() + + if (WHISPER_METAL) + find_library(FOUNDATION_LIBRARY Foundation REQUIRED) + find_library(METAL_FRAMEWORK Metal REQUIRED) + find_library(METALKIT_FRAMEWORK MetalKit REQUIRED) + + if (METAL_FRAMEWORK) + message(STATUS "Metal framework found") + + set(WHISPER_EXTRA_LIBS ${WHISPER_EXTRA_LIBS} + ${FOUNDATION_LIBRARY} + ${METAL_FRAMEWORK} + ${METALKIT_FRAMEWORK} + ) + set(WHISPER_EXTRA_FLAGS ${WHISPER_EXTRA_FLAGS} -DGGML_USE_METAL) + + if (WHISPER_METAL_NDEBUG) + set(WHISPER_EXTRA_FLAGS ${WHISPER_EXTRA_FLAGS} -DGGML_METAL_NDEBUG) + endif() + else() + message(FATAL_ERROR "Metal framework not found") + endif() + + set(GGML_SOURCES_METAL ggml-metal.m ggml-metal.h) + + # copy ggml-metal.metal to bin directory + configure_file(ggml-metal.metal bin/ggml-metal.metal COPYONLY) + endif() + + if (WHISPER_COREML) + find_library(FOUNDATION_FRAMEWORK Foundation) + find_library(COREML_FRAMEWORK CoreML) + + if (COREML_FRAMEWORK) + message(STATUS "CoreML framework found") + + set(WHISPER_EXTRA_FLAGS ${WHISPER_EXTRA_FLAGS} -DWHISPER_USE_COREML) + else() + message(FATAL_ERROR "CoreML framework not found") + endif() + + if (WHISPER_COREML_ALLOW_FALLBACK) + set(WHISPER_EXTRA_FLAGS ${WHISPER_EXTRA_FLAGS} -DWHISPER_COREML_ALLOW_FALLBACK) + endif() + endif() +endif() + +if (WHISPER_OPENBLAS) + set(WHISPER_BLAS_VENDOR "OpenBLAS") + set(WHISPER_BLAS ON) +endif() + +if (WHISPER_BLAS) + if (WIN32) + if(DEFINED ENV{OPENBLAS_PATH}) + set(BLAS_LIBRARIES $ENV{OPENBLAS_PATH}/lib/libopenblas.dll.a) + message(STATUS "Libraries ${BLAS_LIBRARIES}") + set(WHISPER_EXTRA_FLAGS ${WHISPER_EXTRA_FLAGS} -DGGML_USE_OPENBLAS) + include_directories($ENV{OPENBLAS_PATH}/include) + set(WHISPER_EXTRA_LIBS ${WHISPER_EXTRA_LIBS} ${BLAS_LIBRARIES}) + else () + message(FATAL_ERROR "BLAS library was not found. Environment variable OPENBLAS_PATH not defined.") + endif () + else () + set(BLA_STATIC 1) + set(BLA_VENDOR ${WHISPER_BLAS_VENDOR}) + set(BLA_SIZEOF_INTEGER 8) + set(BLA_PREFER_PKGCONFIG 1) + find_package(BLAS) + + if(BLAS_FOUND) + message(STATUS "BLAS compatible library found") + message(STATUS "Libraries ${BLAS_LIBRARIES}") + find_path(BLAS_INCLUDE_DIRS cblas.h /usr/include/openblas /usr/local/include/openblas $ENV{BLAS_HOME}/include) + set(WHISPER_EXTRA_FLAGS ${WHISPER_EXTRA_FLAGS} -DGGML_USE_OPENBLAS) + include_directories(${BLAS_INCLUDE_DIRS}) + set(WHISPER_EXTRA_LIBS ${WHISPER_EXTRA_LIBS} ${BLAS_LIBRARIES}) + else() + message(FATAL_ERROR "BLAS library was not found") + endif() + endif () +endif () + +if (WHISPER_CUBLAS) + cmake_minimum_required(VERSION 3.17) + + find_package(CUDAToolkit) + + if (CUDAToolkit_FOUND) + message(STATUS "cuBLAS found") + + enable_language(CUDA) + + set(GGML_SOURCES_CUDA ggml-cuda.cu ggml-cuda.h) + + add_compile_definitions(GGML_USE_CUBLAS) + + if (WHISPER_STATIC) + set(WHISPER_EXTRA_LIBS ${WHISPER_EXTRA_LIBS} CUDA::cudart_static CUDA::cublas_static CUDA::cublasLt_static) + else() + set(WHISPER_EXTRA_LIBS ${WHISPER_EXTRA_LIBS} CUDA::cudart CUDA::cublas CUDA::cublasLt) + endif() + + else() + message(FATAL_ERROR "cuBLAS not found") + endif() +endif() + + +if (WHISPER_HIPBLAS) + list(APPEND CMAKE_PREFIX_PATH /opt/rocm) + if (NOT ${CMAKE_C_COMPILER_ID} MATCHES "Clang") + message(WARNING "Only LLVM is supported for HIP, hint: CC=/opt/rocm/llvm/bin/clang") + endif() + if (NOT ${CMAKE_CXX_COMPILER_ID} MATCHES "Clang") + message(WARNING "Only LLVM is supported for HIP, hint: CXX=/opt/rocm/llvm/bin/clang++") + endif() + + find_package(hip) + find_package(hipblas) + find_package(rocblas) + + if (${hipblas_FOUND} AND ${hip_FOUND}) + message(STATUS "HIP and hipBLAS found") + add_compile_definitions(GGML_USE_HIPBLAS GGML_USE_CUBLAS) + add_library(ggml-rocm OBJECT ggml-cuda.cu ggml-cuda.h) + set_property(TARGET ggml-rocm PROPERTY POSITION_INDEPENDENT_CODE ON) + set_source_files_properties(ggml-cuda.cu PROPERTIES LANGUAGE CXX) + target_link_libraries(ggml-rocm PRIVATE hip::device PUBLIC hip::host roc::rocblas roc::hipblas) + + if (WHISPER_STATIC) + message(FATAL_ERROR "Static linking not supported for HIP/ROCm") + endif() + set(WHISPER_EXTRA_LIBS ${WHISPER_EXTRA_LIBS} ggml-rocm) + else() + message(FATAL_ERROR "hipBLAS or HIP not found. Try setting CMAKE_PREFIX_PATH=/opt/rocm") + endif() +endif() + +if (WHISPER_CLBLAST) + find_package(CLBlast) + if (CLBlast_FOUND) + message(STATUS "CLBlast found") + + set(GGML_SOURCES_OPENCL ggml-opencl.cpp ggml-opencl.h) + + add_compile_definitions(GGML_USE_CLBLAST) + + set(WHISPER_EXTRA_LIBS ${WHISPER_EXTRA_LIBS} clblast) + else() + message(FATAL_ERROR "CLBlast not found") + endif() +endif() + +if( WHISPER_OPENVINO ) + find_package(OpenVINO REQUIRED COMPONENTS Runtime) +endif() + +# compiler flags + +if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE) + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "RelWithDebInfo") +endif () + +if (WHISPER_ALL_WARNINGS) + if (NOT MSVC) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} \ + -Wall \ + -Wextra \ + -Wpedantic \ + -Wshadow \ + -Wcast-qual \ + -Wstrict-prototypes \ + -Wpointer-arith \ + -Wno-unused-function \ + ") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} \ + -Wall \ + -Wextra \ + -Wpedantic \ + -Wcast-qual \ + ") + else() + # todo : msvc + endif() +endif() + +if (NOT MSVC) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror=vla") + #set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-math-errno -ffinite-math-only -funsafe-math-optimizations") +endif() + +message(STATUS "CMAKE_SYSTEM_PROCESSOR: ${CMAKE_SYSTEM_PROCESSOR}") + +if (${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm" OR ${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64") + message(STATUS "ARM detected") +elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "ppc64le") + message(STATUS "PowerPC detected") +else() + message(STATUS "x86 detected") + if (MSVC) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /utf-8") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /utf-8") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /utf-8") + if(NOT WHISPER_NO_AVX2) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /arch:AVX2") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /arch:AVX2") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /arch:AVX2") + else() + if(NOT WHISPER_NO_AVX) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /arch:AVX") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /arch:AVX") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /arch:AVX") + endif() + endif() + else() + if (EMSCRIPTEN) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthread") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread") + else() + if(NOT WHISPER_NO_AVX) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mavx") + endif() + if(NOT WHISPER_NO_AVX2) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mavx2") + endif() + if(NOT WHISPER_NO_FMA) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mfma") + endif() + if(NOT WHISPER_NO_F16C) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mf16c") + endif() + endif() + endif() +endif() + +# +# POSIX conformance +# + +# clock_gettime came in POSIX.1b (1993) +# CLOCK_MONOTONIC came in POSIX.1-2001 / SUSv3 as optional +# posix_memalign came in POSIX.1-2001 / SUSv3 +# M_PI is an XSI extension since POSIX.1-2001 / SUSv3, came in XPG1 (1985) +add_compile_definitions(_XOPEN_SOURCE=600) + +# Somehow in OpenBSD whenever POSIX conformance is specified +# some string functions rely on locale_t availability, +# which was introduced in POSIX.1-2008, forcing us to go higher +if (CMAKE_SYSTEM_NAME MATCHES "OpenBSD") + remove_definitions(-D_XOPEN_SOURCE=600) + add_compile_definitions(_XOPEN_SOURCE=700) +endif() + +# Data types, macros and functions related to controlling CPU affinity +# are available on Linux through GNU extensions in libc +if (CMAKE_SYSTEM_NAME MATCHES "Linux") + add_compile_definitions(_GNU_SOURCE) +endif() + +# RLIMIT_MEMLOCK came in BSD, is not specified in POSIX.1, +# and on macOS its availability depends on enabling Darwin extensions +# similarly on DragonFly, enabling BSD extensions is necessary +if (CMAKE_SYSTEM_NAME MATCHES "Darwin") + add_compile_definitions(_DARWIN_C_SOURCE) +endif() +if (CMAKE_SYSTEM_NAME MATCHES "DragonFly") + add_compile_definitions(_DARWIN_C_SOURCE) +endif() + +# alloca is a non-standard interface that is not visible on BSDs when +# POSIX conformance is specified, but not all of them provide a clean way +# to enable it in such cases +if (CMAKE_SYSTEM_NAME MATCHES "FreeBSD") + add_compile_definitions(__BSD_VISIBLE) +endif() +if (CMAKE_SYSTEM_NAME MATCHES "NetBSD") + add_compile_definitions(_NETBSD_SOURCE) +endif() +if (CMAKE_SYSTEM_NAME MATCHES "OpenBSD") + add_compile_definitions(_BSD_SOURCE) +endif() + +if (WHISPER_PERF) + set(WHISPER_EXTRA_FLAGS ${WHISPER_EXTRA_FLAGS} -DGGML_PERF) +endif() + +# +# whisper.coreml - Core ML support +# + +if (WHISPER_COREML) + set(TARGET whisper.coreml) + + add_library(${TARGET} + coreml/whisper-encoder.h + coreml/whisper-encoder.mm + coreml/whisper-encoder-impl.h + coreml/whisper-encoder-impl.m + ) + + include(DefaultTargetOptions) + + target_include_directories(${TARGET} PUBLIC + . + ) + + target_link_libraries(${TARGET} PRIVATE ${FOUNDATION_FRAMEWORK} ${COREML_FRAMEWORK}) + + set_target_properties(${TARGET} PROPERTIES + COMPILE_FLAGS "-fobjc-arc" + ) +endif() + +if (WHISPER_OPENVINO) + set(TARGET whisper.openvino) + + add_library(${TARGET} OBJECT + openvino/whisper-openvino-encoder.h + openvino/whisper-openvino-encoder.cpp + ) + + target_include_directories(${TARGET} PUBLIC + . + ) + + set_property(TARGET ${TARGET} PROPERTY POSITION_INDEPENDENT_CODE ON) + set(WHISPER_EXTRA_FLAGS ${WHISPER_EXTRA_FLAGS} -DWHISPER_USE_OPENVINO) + + target_link_libraries(${TARGET} PRIVATE openvino::runtime) +endif() + +# +# whisper - this is the main library of the project +# + +set(TARGET whisper) + +add_library(${TARGET} + ggml.h + ggml.c + ggml-alloc.h + ggml-alloc.c + ggml-backend.h + ggml-backend.c + ggml-quants.h + ggml-quants.c + ${GGML_SOURCES_METAL} + ${GGML_SOURCES_CUDA} + ${GGML_SOURCES_OPENCL} + whisper.h + whisper.cpp + ) + +include(DefaultTargetOptions) + +target_include_directories(${TARGET} PUBLIC + . + ) + +if (WHISPER_COREML) + target_link_libraries(${TARGET} PRIVATE whisper.coreml) +endif() + +if (WHISPER_OPENVINO) + target_link_libraries(${TARGET} PRIVATE whisper.openvino) +endif() + +if (MSVC) + target_link_libraries(${TARGET} PRIVATE ${WHISPER_EXTRA_LIBS} ${CMAKE_THREAD_LIBS_INIT}) + + set(WHISPER_EXTRA_FLAGS ${WHISPER_EXTRA_FLAGS} -D_CRT_SECURE_NO_WARNINGS) +else() + target_link_libraries(${TARGET} PRIVATE m ${WHISPER_EXTRA_LIBS} ${CMAKE_THREAD_LIBS_INIT}) +endif() + +if (BUILD_SHARED_LIBS) + target_link_libraries(${TARGET} PUBLIC + ${CMAKE_DL_LIBS} + ) + + target_compile_definitions(${TARGET} PUBLIC + WHISPER_SHARED + GGML_SHARED + ) + + target_compile_definitions(${TARGET} PRIVATE + WHISPER_BUILD + GGML_BUILD + ) + + if (WHISPER_METAL) + # TODO: I think this should make ggml-metal.m "see" the ggml-metal.metal file from the "bin" directory + # but for some reason it does not work here like it does in llama.cpp + set_target_properties(${TARGET} PROPERTIES RESOURCE "${CMAKE_CURRENT_SOURCE_DIR}/ggml-metal.metal") + endif() +endif() + +if (GGML_SOURCES_CUDA) + message(STATUS "GGML CUDA sources found, configuring CUDA architecture") + set_property(TARGET whisper PROPERTY CUDA_ARCHITECTURES OFF) + set_property(TARGET whisper PROPERTY CUDA_SELECT_NVCC_ARCH_FLAGS "Auto") +endif() + +if (EMSCRIPTEN) + set_target_properties(${TARGET} PROPERTIES COMPILE_FLAGS "-msimd128") +endif() + +target_compile_definitions(${TARGET} PUBLIC + ${WHISPER_EXTRA_FLAGS} + ) + +set_target_properties(${TARGET} PROPERTIES PUBLIC_HEADER "whisper.h") + +include(GNUInstallDirs) + +install(TARGETS ${TARGET} + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib/static + RUNTIME DESTINATION bin + RESOURCE DESTINATION bin + PUBLIC_HEADER DESTINATION include + ) + +# +# bindings +# + +add_subdirectory(bindings) + +# +# programs, examples and tests +# + +if (WHISPER_BUILD_TESTS AND NOT CMAKE_JS_VERSION) + enable_testing() + add_subdirectory(tests) +endif () + +if (WHISPER_BUILD_EXAMPLES) + add_subdirectory(examples) +endif() diff --git a/sys/whisper.cpp/LICENSE b/sys/whisper.cpp/LICENSE new file mode 100644 index 0000000..76f67ef --- /dev/null +++ b/sys/whisper.cpp/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Georgi Gerganov + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/sys/whisper.cpp/Makefile b/sys/whisper.cpp/Makefile new file mode 100644 index 0000000..b1f5b7c --- /dev/null +++ b/sys/whisper.cpp/Makefile @@ -0,0 +1,448 @@ +default: main bench quantize server + +ifndef UNAME_S +UNAME_S := $(shell uname -s) +endif + +ifndef UNAME_P +UNAME_P := $(shell uname -p) +endif + +ifndef UNAME_M +UNAME_M := $(shell uname -m) +endif + +ifndef NVCC_VERSION + ifeq ($(call,$(shell which nvcc))$(.SHELLSTATUS),0) + NVCC_VERSION := $(shell nvcc --version | egrep -o "V[0-9]+.[0-9]+.[0-9]+" | cut -c2-) + endif +endif + +CCV := $(shell $(CC) --version | head -n 1) +CXXV := $(shell $(CXX) --version | head -n 1) + +# Mac OS + Arm can report x86_64 +# ref: https://github.com/ggerganov/whisper.cpp/issues/66#issuecomment-1282546789 +ifeq ($(UNAME_S),Darwin) + ifneq ($(UNAME_P),arm) + SYSCTL_M := $(shell sysctl -n hw.optional.arm64) + ifeq ($(SYSCTL_M),1) + # UNAME_P := arm + # UNAME_M := arm64 + warn := $(warning Your arch is announced as x86_64, but it seems to actually be ARM64. Not fixing that can lead to bad performance. For more info see: https://github.com/ggerganov/whisper.cpp/issues/66\#issuecomment-1282546789) + endif + endif +endif + +# +# Compile flags +# + +CFLAGS = -I. -O3 -DNDEBUG -std=c11 -fPIC +CXXFLAGS = -I. -I./examples -O3 -DNDEBUG -std=c++11 -fPIC +LDFLAGS = + +# clock_gettime came in POSIX.1b (1993) +# CLOCK_MONOTONIC came in POSIX.1-2001 / SUSv3 as optional +# posix_memalign came in POSIX.1-2001 / SUSv3 +# M_PI is an XSI extension since POSIX.1-2001 / SUSv3, came in XPG1 (1985) +CFLAGS += -D_XOPEN_SOURCE=600 +CXXFLAGS += -D_XOPEN_SOURCE=600 + +# Somehow in OpenBSD whenever POSIX conformance is specified +# some string functions rely on locale_t availability, +# which was introduced in POSIX.1-2008, forcing us to go higher +ifeq ($(UNAME_S),OpenBSD) + CFLAGS += -U_XOPEN_SOURCE -D_XOPEN_SOURCE=700 + CXXFLAGS += -U_XOPEN_SOURCE -D_XOPEN_SOURCE=700 +endif + +# Data types, macros and functions related to controlling CPU affinity +# are available on Linux through GNU extensions in libc +ifeq ($(UNAME_S),Linux) + CFLAGS += -D_GNU_SOURCE + CXXFLAGS += -D_GNU_SOURCE +endif + +# RLIMIT_MEMLOCK came in BSD, is not specified in POSIX.1, +# and on macOS its availability depends on enabling Darwin extensions +# similarly on DragonFly, enabling BSD extensions is necessary +ifeq ($(UNAME_S),Darwin) + CFLAGS += -D_DARWIN_C_SOURCE + CXXFLAGS += -D_DARWIN_C_SOURCE +endif +ifeq ($(UNAME_S),DragonFly) + CFLAGS += -D__BSD_VISIBLE + CXXFLAGS += -D__BSD_VISIBLE +endif + +# alloca is a non-standard interface that is not visible on BSDs when +# POSIX conformance is specified, but not all of them provide a clean way +# to enable it in such cases +ifeq ($(UNAME_S),FreeBSD) + CFLAGS += -D__BSD_VISIBLE + CXXFLAGS += -D__BSD_VISIBLE +endif +ifeq ($(UNAME_S),NetBSD) + CFLAGS += -D_NETBSD_SOURCE + CXXFLAGS += -D_NETBSD_SOURCE +endif +ifeq ($(UNAME_S),OpenBSD) + CFLAGS += -D_BSD_SOURCE + CXXFLAGS += -D_BSD_SOURCE +endif + +# OS specific +# TODO: support Windows +ifeq ($(filter $(UNAME_S),Linux Darwin DragonFly FreeBSD NetBSD OpenBSD Haiku),$(UNAME_S)) + CFLAGS += -pthread + CXXFLAGS += -pthread +endif + +# Architecture specific +# TODO: probably these flags need to be tweaked on some architectures +# feel free to update the Makefile for your architecture and send a pull request or issue +ifeq ($(UNAME_M),$(filter $(UNAME_M),x86_64 i686 amd64)) + ifeq ($(UNAME_S),Darwin) + CPUINFO_CMD := sysctl machdep.cpu.features machdep.cpu.leaf7_features + else ifeq ($(UNAME_S),Linux) + CPUINFO_CMD := cat /proc/cpuinfo + else ifneq (,$(filter MINGW32_NT% MINGW64_NT%,$(UNAME_S))) + CPUINFO_CMD := cat /proc/cpuinfo + else ifneq (,$(filter DragonFly FreeBSD,$(UNAME_S))) + CPUINFO_CMD := grep Features /var/run/dmesg.boot + else ifeq ($(UNAME_S),Haiku) + CPUINFO_CMD := sysinfo -cpu + endif + + ifdef CPUINFO_CMD + AVX_M := $(shell $(CPUINFO_CMD) | grep -iwE 'AVX|AVX1.0') + ifneq (,$(AVX_M)) + CFLAGS += -mavx + CXXFLAGS += -mavx + endif + + AVX2_M := $(shell $(CPUINFO_CMD) | grep -iw 'AVX2') + ifneq (,$(AVX2_M)) + CFLAGS += -mavx2 + CXXFLAGS += -mavx2 + endif + + FMA_M := $(shell $(CPUINFO_CMD) | grep -iw 'FMA') + ifneq (,$(FMA_M)) + CFLAGS += -mfma + CXXFLAGS += -mfma + endif + + F16C_M := $(shell $(CPUINFO_CMD) | grep -iw 'F16C') + ifneq (,$(F16C_M)) + CFLAGS += -mf16c + CXXFLAGS += -mf16c + endif + + SSE3_M := $(shell $(CPUINFO_CMD) | grep -iwE 'PNI|SSE3') + ifneq (,$(SSE3_M)) + CFLAGS += -msse3 + CXXFLAGS += -msse3 + endif + + SSSE3_M := $(shell $(CPUINFO_CMD) | grep -iw 'SSSE3') + ifneq (,$(SSSE3_M)) + CFLAGS += -mssse3 + CXXFLAGS += -mssse3 + endif + endif +endif + +ifneq ($(filter ppc64%,$(UNAME_M)),) + POWER9_M := $(shell grep "POWER9" /proc/cpuinfo) + ifneq (,$(findstring POWER9,$(POWER9_M))) + CFLAGS += -mpower9-vector + endif + # Require c++23's std::byteswap for big-endian support. + ifeq ($(UNAME_M),ppc64) + CXXFLAGS += -std=c++23 -DGGML_BIG_ENDIAN + endif +endif + +ifndef WHISPER_NO_ACCELERATE + # Mac M1 - include Accelerate framework + ifeq ($(UNAME_S),Darwin) + CFLAGS += -DGGML_USE_ACCELERATE + LDFLAGS += -framework Accelerate + endif +endif + +ifdef WHISPER_COREML + CXXFLAGS += -DWHISPER_USE_COREML + LDFLAGS += -framework Foundation -framework CoreML + +ifdef WHISPER_COREML_ALLOW_FALLBACK + CXXFLAGS += -DWHISPER_COREML_ALLOW_FALLBACK +endif +endif + +ifndef WHISPER_NO_METAL + ifeq ($(UNAME_S),Darwin) + WHISPER_METAL := 1 + + CFLAGS += -DGGML_USE_METAL + CXXFLAGS += -DGGML_USE_METAL + LDFLAGS += -framework Foundation -framework Metal -framework MetalKit + endif +endif + +ifdef WHISPER_OPENBLAS + CFLAGS += -DGGML_USE_OPENBLAS -I/usr/local/include/openblas -I/usr/include/openblas + LDFLAGS += -lopenblas +endif + +ifdef WHISPER_CUBLAS + ifeq ($(shell expr $(NVCC_VERSION) \>= 11.6), 1) + CUDA_ARCH_FLAG=native + else + CUDA_ARCH_FLAG=all + endif + + CFLAGS += -DGGML_USE_CUBLAS -I/usr/local/cuda/include -I/opt/cuda/include -I$(CUDA_PATH)/targets/$(UNAME_M)-linux/include + CXXFLAGS += -DGGML_USE_CUBLAS -I/usr/local/cuda/include -I/opt/cuda/include -I$(CUDA_PATH)/targets/$(UNAME_M)-linux/include + LDFLAGS += -lcublas -lculibos -lcudart -lcublasLt -lpthread -ldl -lrt -L/usr/local/cuda/lib64 -L/opt/cuda/lib64 -L$(CUDA_PATH)/targets/$(UNAME_M)-linux/lib + WHISPER_OBJ += ggml-cuda.o + NVCC = nvcc + NVCCFLAGS = --forward-unknown-to-host-compiler -arch=$(CUDA_ARCH_FLAG) + +ggml-cuda.o: ggml-cuda.cu ggml-cuda.h + $(NVCC) $(NVCCFLAGS) $(CXXFLAGS) -Wno-pedantic -c $< -o $@ +endif + +ifdef WHISPER_HIPBLAS + ROCM_PATH ?= /opt/rocm + HIPCC ?= $(ROCM_PATH)/bin/hipcc + GPU_TARGETS ?= $(shell $(ROCM_PATH)/llvm/bin/amdgpu-arch) + CFLAGS += -DGGML_USE_HIPBLAS -DGGML_USE_CUBLAS + CXXFLAGS += -DGGML_USE_HIPBLAS -DGGML_USE_CUBLAS + LDFLAGS += -L$(ROCM_PATH)/lib -Wl,-rpath=$(ROCM_PATH)/lib + LDFLAGS += -lhipblas -lamdhip64 -lrocblas + HIPFLAGS += $(addprefix --offload-arch=,$(GPU_TARGETS)) + WHISPER_OBJ += ggml-cuda.o + +ggml-cuda.o: ggml-cuda.cu ggml-cuda.h + $(HIPCC) $(CXXFLAGS) $(HIPFLAGS) -x hip -c -o $@ $< +endif + +ifdef WHISPER_CLBLAST + CFLAGS += -DGGML_USE_CLBLAST + CXXFLAGS += -DGGML_USE_CLBLAST + LDFLAGS += -lclblast + ifeq ($(UNAME_S),Darwin) + LDFLAGS += -framework OpenCL + else + LDFLAGS += -lOpenCL + endif + WHISPER_OBJ += ggml-opencl.o + +ggml-opencl.o: ggml-opencl.cpp ggml-opencl.h + $(CXX) $(CXXFLAGS) -c $< -o $@ +endif + +ifdef WHISPER_GPROF + CFLAGS += -pg + CXXFLAGS += -pg +endif + +ifneq ($(filter aarch64%,$(UNAME_M)),) + CFLAGS += -mcpu=native + CXXFLAGS += -mcpu=native +endif + +ifneq ($(filter armv6%,$(UNAME_M)),) + # 32-bit Raspberry Pi 1, 2, 3 + CFLAGS += -mfpu=neon -mfp16-format=ieee -mno-unaligned-access +endif + +ifneq ($(filter armv7%,$(UNAME_M)),) + # 32-bit ARM, for example on Armbian or possibly raspbian + #CFLAGS += -mfpu=neon -mfp16-format=ieee -funsafe-math-optimizations -mno-unaligned-access + #CXXFLAGS += -mfpu=neon -mfp16-format=ieee -funsafe-math-optimizations -mno-unaligned-access + + # 64-bit ARM on 32-bit OS, use these (TODO: auto-detect 64-bit) + CFLAGS += -mfpu=neon-fp-armv8 -mfp16-format=ieee -funsafe-math-optimizations -mno-unaligned-access + CXXFLAGS += -mfpu=neon-fp-armv8 -mfp16-format=ieee -funsafe-math-optimizations -mno-unaligned-access +endif + +ifneq ($(filter armv8%,$(UNAME_M)),) + # Raspberry Pi 4 + CFLAGS += -mfpu=neon-fp-armv8 -mfp16-format=ieee -funsafe-math-optimizations -mno-unaligned-access + CXXFLAGS += -mfpu=neon-fp-armv8 -mfp16-format=ieee -funsafe-math-optimizations -mno-unaligned-access +endif + +# +# Print build information +# + +$(info I whisper.cpp build info: ) +$(info I UNAME_S: $(UNAME_S)) +$(info I UNAME_P: $(UNAME_P)) +$(info I UNAME_M: $(UNAME_M)) +$(info I CFLAGS: $(CFLAGS)) +$(info I CXXFLAGS: $(CXXFLAGS)) +$(info I LDFLAGS: $(LDFLAGS)) +$(info I CC: $(CCV)) +$(info I CXX: $(CXXV)) +$(info ) + +# +# Build library +# + +ggml.o: ggml.c ggml.h ggml-cuda.h + $(CC) $(CFLAGS) -c $< -o $@ + +ggml-alloc.o: ggml-alloc.c ggml.h ggml-alloc.h + $(CC) $(CFLAGS) -c $< -o $@ + +ggml-backend.o: ggml-backend.c ggml.h ggml-backend.h + $(CC) $(CFLAGS) -c $< -o $@ + +ggml-quants.o: ggml-quants.c ggml.h ggml-quants.h + $(CC) $(CFLAGS) -c $< -o $@ + +WHISPER_OBJ += ggml.o ggml-alloc.o ggml-backend.o ggml-quants.o + +whisper.o: whisper.cpp whisper.h ggml.h ggml-cuda.h + $(CXX) $(CXXFLAGS) -c $< -o $@ + +ifndef WHISPER_COREML +WHISPER_OBJ += whisper.o +else +whisper-encoder.o: coreml/whisper-encoder.mm coreml/whisper-encoder.h + $(CXX) -O3 -I . -fobjc-arc -c coreml/whisper-encoder.mm -o whisper-encoder.o + +whisper-encoder-impl.o: coreml/whisper-encoder-impl.m coreml/whisper-encoder-impl.h + $(CXX) -O3 -I . -fobjc-arc -c coreml/whisper-encoder-impl.m -o whisper-encoder-impl.o + +WHISPER_OBJ += whisper.o whisper-encoder.o whisper-encoder-impl.o +endif + +ifdef WHISPER_METAL +ggml-metal.o: ggml-metal.m ggml-metal.h + $(CC) $(CFLAGS) -c $< -o $@ + +WHISPER_OBJ += ggml-metal.o +endif + +libwhisper.a: $(WHISPER_OBJ) + $(AR) rcs libwhisper.a $(WHISPER_OBJ) + +libwhisper.so: $(WHISPER_OBJ) + $(CXX) $(CXXFLAGS) -shared -o libwhisper.so $(WHISPER_OBJ) $(LDFLAGS) + +clean: + rm -f *.o main stream command talk talk-llama bench quantize server lsp libwhisper.a libwhisper.so + +# +# Examples +# + +CC_SDL=`sdl2-config --cflags --libs` + +SRC_COMMON = examples/common.cpp examples/common-ggml.cpp +SRC_COMMON_SDL = examples/common-sdl.cpp + +main: examples/main/main.cpp $(SRC_COMMON) $(WHISPER_OBJ) + $(CXX) $(CXXFLAGS) examples/main/main.cpp $(SRC_COMMON) $(WHISPER_OBJ) -o main $(LDFLAGS) + ./main -h + +bench: examples/bench/bench.cpp $(WHISPER_OBJ) + $(CXX) $(CXXFLAGS) examples/bench/bench.cpp $(WHISPER_OBJ) -o bench $(LDFLAGS) + +quantize: examples/quantize/quantize.cpp $(WHISPER_OBJ) $(SRC_COMMON) + $(CXX) $(CXXFLAGS) examples/quantize/quantize.cpp $(SRC_COMMON) $(WHISPER_OBJ) -o quantize $(LDFLAGS) + +server: examples/server/server.cpp $(SRC_COMMON) $(WHISPER_OBJ) + $(CXX) $(CXXFLAGS) examples/server/server.cpp $(SRC_COMMON) $(WHISPER_OBJ) -o server $(LDFLAGS) + +stream: examples/stream/stream.cpp $(SRC_COMMON) $(SRC_COMMON_SDL) $(WHISPER_OBJ) + $(CXX) $(CXXFLAGS) examples/stream/stream.cpp $(SRC_COMMON) $(SRC_COMMON_SDL) $(WHISPER_OBJ) -o stream $(CC_SDL) $(LDFLAGS) + +command: examples/command/command.cpp examples/grammar-parser.cpp $(SRC_COMMON) $(SRC_COMMON_SDL) $(WHISPER_OBJ) + $(CXX) $(CXXFLAGS) examples/command/command.cpp examples/grammar-parser.cpp $(SRC_COMMON) $(SRC_COMMON_SDL) $(WHISPER_OBJ) -o command $(CC_SDL) $(LDFLAGS) + +lsp: examples/lsp/lsp.cpp $(SRC_COMMON) $(SRC_COMMON_SDL) $(WHISPER_OBJ) + $(CXX) $(CXXFLAGS) examples/lsp/lsp.cpp $(SRC_COMMON) $(SRC_COMMON_SDL) $(WHISPER_OBJ) -o lsp $(CC_SDL) $(LDFLAGS) + +talk: examples/talk/talk.cpp examples/talk/gpt-2.cpp $(SRC_COMMON) $(SRC_COMMON_SDL) $(WHISPER_OBJ) + $(CXX) $(CXXFLAGS) examples/talk/talk.cpp examples/talk/gpt-2.cpp $(SRC_COMMON) $(SRC_COMMON_SDL) $(WHISPER_OBJ) -o talk $(CC_SDL) $(LDFLAGS) + +talk-llama: examples/talk-llama/talk-llama.cpp examples/talk-llama/llama.cpp $(SRC_COMMON) $(SRC_COMMON_SDL) $(WHISPER_OBJ) + $(CXX) $(CXXFLAGS) examples/talk-llama/talk-llama.cpp examples/talk-llama/llama.cpp $(SRC_COMMON) $(SRC_COMMON_SDL) $(WHISPER_OBJ) -o talk-llama $(CC_SDL) $(LDFLAGS) + +# +# Audio samples +# + +# download a few audio samples into folder "./samples": +.PHONY: samples +samples: + @echo "Downloading samples..." + @mkdir -p samples + @wget --quiet --show-progress -O samples/gb0.ogg https://upload.wikimedia.org/wikipedia/commons/2/22/George_W._Bush%27s_weekly_radio_address_%28November_1%2C_2008%29.oga + @wget --quiet --show-progress -O samples/gb1.ogg https://upload.wikimedia.org/wikipedia/commons/1/1f/George_W_Bush_Columbia_FINAL.ogg + @wget --quiet --show-progress -O samples/hp0.ogg https://upload.wikimedia.org/wikipedia/en/d/d4/En.henryfphillips.ogg + @wget --quiet --show-progress -O samples/mm1.wav https://cdn.openai.com/whisper/draft-20220913a/micro-machines.wav + @wget --quiet --show-progress -O samples/a13.mp3 https://upload.wikimedia.org/wikipedia/commons/transcoded/6/6f/Apollo13-wehaveaproblem.ogg/Apollo13-wehaveaproblem.ogg.mp3 + @wget --quiet --show-progress -O samples/diffusion2023-07-03.flac https://archive.org/download/diffusion2023-07-03/diffusion2023-07-03.flac + @echo "Converting to 16-bit WAV ..." + @ffmpeg -loglevel -0 -y -i samples/gb0.ogg -ar 16000 -ac 1 -c:a pcm_s16le samples/gb0.wav + @ffmpeg -loglevel -0 -y -i samples/gb1.ogg -ar 16000 -ac 1 -c:a pcm_s16le samples/gb1.wav + @ffmpeg -loglevel -0 -y -i samples/hp0.ogg -ar 16000 -ac 1 -c:a pcm_s16le samples/hp0.wav + @rm samples/*.ogg + @ffmpeg -loglevel -0 -y -i samples/mm1.wav -ar 16000 -ac 1 -c:a pcm_s16le samples/mm0.wav + @rm samples/mm1.wav + @ffmpeg -loglevel -0 -y -i samples/a13.mp3 -ar 16000 -ac 1 -c:a pcm_s16le -ss 00:00:00 -to 00:00:30 samples/a13.wav + @rm samples/a13.mp3 + @ffmpeg -loglevel -0 -y -i samples/diffusion2023-07-03.flac -ar 16000 -ac 1 -c:a pcm_s16le samples/diffusion2023-07-03.wav + @rm samples/diffusion2023-07-03.flac + +# +# Models +# + +# if not already downloaded, the following targets download the specified model and +# runs it on all samples in the folder "./samples": + +.PHONY: tiny.en +.PHONY: tiny +.PHONY: base.en +.PHONY: base +.PHONY: small.en +.PHONY: small +.PHONY: medium.en +.PHONY: medium +.PHONY: large-v1 +.PHONY: large-v2 +.PHONY: large-v3 + +tiny.en tiny base.en base small.en small medium.en medium large-v1 large-v2 large-v3: main + bash ./models/download-ggml-model.sh $@ + @echo "" + @echo "===============================================" + @echo "Running $@ on all samples in ./samples ..." + @echo "===============================================" + @echo "" + @for f in samples/*.wav; do \ + echo "----------------------------------------------" ; \ + echo "[+] Running $@ on $$f ... (run 'ffplay $$f' to listen)" ; \ + echo "----------------------------------------------" ; \ + echo "" ; \ + ./main -m models/ggml-$@.bin -f $$f ; \ + echo "" ; \ + done + +# +# Tests +# + +.PHONY: tests +tests: + bash ./tests/run-tests.sh $(word 2, $(MAKECMDGOALS)) diff --git a/sys/whisper.cpp/README.md b/sys/whisper.cpp/README.md new file mode 100644 index 0000000..c790af3 --- /dev/null +++ b/sys/whisper.cpp/README.md @@ -0,0 +1,787 @@ +# whisper.cpp + +![whisper.cpp](https://user-images.githubusercontent.com/1991296/235238348-05d0f6a4-da44-4900-a1de-d0707e75b763.jpeg) + +[![Actions Status](https://github.com/ggerganov/whisper.cpp/workflows/CI/badge.svg)](https://github.com/ggerganov/whisper.cpp/actions) +[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT) +[![npm](https://img.shields.io/npm/v/whisper.cpp.svg)](https://www.npmjs.com/package/whisper.cpp/) + +Stable: [v1.5.1](https://github.com/ggerganov/whisper.cpp/releases/tag/v1.5.1) / [Roadmap | F.A.Q.](https://github.com/ggerganov/whisper.cpp/discussions/126) + +High-performance inference of [OpenAI's Whisper](https://github.com/openai/whisper) automatic speech recognition (ASR) model: + +- Plain C/C++ implementation without dependencies +- Apple Silicon first-class citizen - optimized via ARM NEON, Accelerate framework, Metal and [Core ML](https://github.com/ggerganov/whisper.cpp#core-ml-support) +- AVX intrinsics support for x86 architectures +- VSX intrinsics support for POWER architectures +- Mixed F16 / F32 precision +- [4-bit and 5-bit integer quantization support](https://github.com/ggerganov/whisper.cpp#quantization) +- Zero memory allocations at runtime +- Support for CPU-only inference +- [Efficient GPU support for NVIDIA](https://github.com/ggerganov/whisper.cpp#nvidia-gpu-support-via-cublas) +- [Partial OpenCL GPU support via CLBlast](https://github.com/ggerganov/whisper.cpp#opencl-gpu-support-via-clblast) +- [OpenVINO Support](https://github.com/ggerganov/whisper.cpp#openvino-support) +- [C-style API](https://github.com/ggerganov/whisper.cpp/blob/master/whisper.h) + +Supported platforms: + +- [x] Mac OS (Intel and Arm) +- [x] [iOS](examples/whisper.objc) +- [x] [Android](examples/whisper.android) +- [x] [Java](bindings/java/README.md) +- [x] Linux / [FreeBSD](https://github.com/ggerganov/whisper.cpp/issues/56#issuecomment-1350920264) +- [x] [WebAssembly](examples/whisper.wasm) +- [x] Windows ([MSVC](https://github.com/ggerganov/whisper.cpp/blob/master/.github/workflows/build.yml#L117-L144) and [MinGW](https://github.com/ggerganov/whisper.cpp/issues/168)] +- [x] [Raspberry Pi](https://github.com/ggerganov/whisper.cpp/discussions/166) + +The entire high-level implementation of the model is contained in [whisper.h](whisper.h) and [whisper.cpp](whisper.cpp). +The rest of the code is part of the [ggml](https://github.com/ggerganov/ggml) machine learning library. + +Having such a lightweight implementation of the model allows to easily integrate it in different platforms and applications. +As an example, here is a video of running the model on an iPhone 13 device - fully offline, on-device: [whisper.objc](examples/whisper.objc) + +https://user-images.githubusercontent.com/1991296/197385372-962a6dea-bca1-4d50-bf96-1d8c27b98c81.mp4 + +You can also easily make your own offline voice assistant application: [command](examples/command) + +https://user-images.githubusercontent.com/1991296/204038393-2f846eae-c255-4099-a76d-5735c25c49da.mp4 + +On Apple Silicon, the inference runs fully on the GPU via Metal: + +https://github.com/ggerganov/whisper.cpp/assets/1991296/c82e8f86-60dc-49f2-b048-d2fdbd6b5225 + +Or you can even run it straight in the browser: [talk.wasm](examples/talk.wasm) + +## Implementation details + +- The core tensor operations are implemented in C ([ggml.h](ggml.h) / [ggml.c](ggml.c)) +- The transformer model and the high-level C-style API are implemented in C++ ([whisper.h](whisper.h) / [whisper.cpp](whisper.cpp)) +- Sample usage is demonstrated in [main.cpp](examples/main) +- Sample real-time audio transcription from the microphone is demonstrated in [stream.cpp](examples/stream) +- Various other examples are available in the [examples](examples) folder + +The tensor operators are optimized heavily for Apple silicon CPUs. Depending on the computation size, Arm Neon SIMD +intrinsics or CBLAS Accelerate framework routines are used. The latter are especially effective for bigger sizes since +the Accelerate framework utilizes the special-purpose AMX coprocessor available in modern Apple products. + +## Quick start + +First clone the repository. + +Then, download one of the Whisper models converted in [ggml format](models). For example: + +```bash +bash ./models/download-ggml-model.sh base.en +``` + +If you wish to convert the Whisper models to ggml format yourself, instructions are in [models/README.md](models/README.md). + +Now build the [main](examples/main) example and transcribe an audio file like this: + +```bash +# build the main example +make + +# transcribe an audio file +./main -f samples/jfk.wav +``` + +--- + +For a quick demo, simply run `make base.en`: + +```java +$ make base.en + +cc -I. -O3 -std=c11 -pthread -DGGML_USE_ACCELERATE -c ggml.c -o ggml.o +c++ -I. -I./examples -O3 -std=c++11 -pthread -c whisper.cpp -o whisper.o +c++ -I. -I./examples -O3 -std=c++11 -pthread examples/main/main.cpp whisper.o ggml.o -o main -framework Accelerate +./main -h + +usage: ./main [options] file0.wav file1.wav ... + +options: + -h, --help [default] show this help message and exit + -t N, --threads N [4 ] number of threads to use during computation + -p N, --processors N [1 ] number of processors to use during computation + -ot N, --offset-t N [0 ] time offset in milliseconds + -on N, --offset-n N [0 ] segment index offset + -d N, --duration N [0 ] duration of audio to process in milliseconds + -mc N, --max-context N [-1 ] maximum number of text context tokens to store + -ml N, --max-len N [0 ] maximum segment length in characters + -sow, --split-on-word [false ] split on word rather than on token + -bo N, --best-of N [2 ] number of best candidates to keep + -bs N, --beam-size N [-1 ] beam size for beam search + -wt N, --word-thold N [0.01 ] word timestamp probability threshold + -et N, --entropy-thold N [2.40 ] entropy threshold for decoder fail + -lpt N, --logprob-thold N [-1.00 ] log probability threshold for decoder fail + -debug, --debug-mode [false ] enable debug mode (eg. dump log_mel) + -tr, --translate [false ] translate from source language to english + -di, --diarize [false ] stereo audio diarization + -tdrz, --tinydiarize [false ] enable tinydiarize (requires a tdrz model) + -nf, --no-fallback [false ] do not use temperature fallback while decoding + -otxt, --output-txt [false ] output result in a text file + -ovtt, --output-vtt [false ] output result in a vtt file + -osrt, --output-srt [false ] output result in a srt file + -olrc, --output-lrc [false ] output result in a lrc file + -owts, --output-words [false ] output script for generating karaoke video + -fp, --font-path [/System/Library/Fonts/Supplemental/Courier New Bold.ttf] path to a monospace font for karaoke video + -ocsv, --output-csv [false ] output result in a CSV file + -oj, --output-json [false ] output result in a JSON file + -of FNAME, --output-file FNAME [ ] output file path (without file extension) + -ps, --print-special [false ] print special tokens + -pc, --print-colors [false ] print colors + -pp, --print-progress [false ] print progress + -nt, --no-timestamps [false ] do not print timestamps + -l LANG, --language LANG [en ] spoken language ('auto' for auto-detect) + -dl, --detect-language [false ] exit after automatically detecting language + --prompt PROMPT [ ] initial prompt + -m FNAME, --model FNAME [models/ggml-base.en.bin] model path + -f FNAME, --file FNAME [ ] input WAV file path + -oved D, --ov-e-device DNAME [CPU ] the OpenVINO device used for encode inference + -ls, --log-score [false ] log best decoder scores of token + + +bash ./models/download-ggml-model.sh base.en +Downloading ggml model base.en ... +ggml-base.en.bin 100%[========================>] 141.11M 6.34MB/s in 24s +Done! Model 'base.en' saved in 'models/ggml-base.en.bin' +You can now use it like this: + + $ ./main -m models/ggml-base.en.bin -f samples/jfk.wav + + +=============================================== +Running base.en on all samples in ./samples ... +=============================================== + +---------------------------------------------- +[+] Running base.en on samples/jfk.wav ... (run 'ffplay samples/jfk.wav' to listen) +---------------------------------------------- + +whisper_init_from_file: loading model from 'models/ggml-base.en.bin' +whisper_model_load: loading model +whisper_model_load: n_vocab = 51864 +whisper_model_load: n_audio_ctx = 1500 +whisper_model_load: n_audio_state = 512 +whisper_model_load: n_audio_head = 8 +whisper_model_load: n_audio_layer = 6 +whisper_model_load: n_text_ctx = 448 +whisper_model_load: n_text_state = 512 +whisper_model_load: n_text_head = 8 +whisper_model_load: n_text_layer = 6 +whisper_model_load: n_mels = 80 +whisper_model_load: f16 = 1 +whisper_model_load: type = 2 +whisper_model_load: mem required = 215.00 MB (+ 6.00 MB per decoder) +whisper_model_load: kv self size = 5.25 MB +whisper_model_load: kv cross size = 17.58 MB +whisper_model_load: adding 1607 extra tokens +whisper_model_load: model ctx = 140.60 MB +whisper_model_load: model size = 140.54 MB + +system_info: n_threads = 4 / 10 | AVX = 0 | AVX2 = 0 | AVX512 = 0 | FMA = 0 | NEON = 1 | ARM_FMA = 1 | F16C = 0 | FP16_VA = 1 | WASM_SIMD = 0 | BLAS = 1 | SSE3 = 0 | VSX = 0 | + +main: processing 'samples/jfk.wav' (176000 samples, 11.0 sec), 4 threads, 1 processors, lang = en, task = transcribe, timestamps = 1 ... + + +[00:00:00.000 --> 00:00:11.000] And so my fellow Americans, ask not what your country can do for you, ask what you can do for your country. + + +whisper_print_timings: fallbacks = 0 p / 0 h +whisper_print_timings: load time = 113.81 ms +whisper_print_timings: mel time = 15.40 ms +whisper_print_timings: sample time = 11.58 ms / 27 runs ( 0.43 ms per run) +whisper_print_timings: encode time = 266.60 ms / 1 runs ( 266.60 ms per run) +whisper_print_timings: decode time = 66.11 ms / 27 runs ( 2.45 ms per run) +whisper_print_timings: total time = 476.31 ms +``` + +The command downloads the `base.en` model converted to custom `ggml` format and runs the inference on all `.wav` samples in the folder `samples`. + +For detailed usage instructions, run: `./main -h` + +Note that the [main](examples/main) example currently runs only with 16-bit WAV files, so make sure to convert your input before running the tool. +For example, you can use `ffmpeg` like this: + +```java +ffmpeg -i input.mp3 -ar 16000 -ac 1 -c:a pcm_s16le output.wav +``` + +## More audio samples + +If you want some extra audio samples to play with, simply run: + +``` +make samples +``` + +This will download a few more audio files from Wikipedia and convert them to 16-bit WAV format via `ffmpeg`. + +You can download and run the other models as follows: + +``` +make tiny.en +make tiny +make base.en +make base +make small.en +make small +make medium.en +make medium +make large-v1 +make large-v2 +make large-v3 +``` + +## Memory usage + +| Model | Disk | Mem | +| --- | --- | --- | +| tiny | 75 MiB | ~273 MB | +| base | 142 MiB | ~388 MB | +| small | 466 MiB | ~852 MB | +| medium | 1.5 GiB | ~2.1 GB | +| large | 2.9 GiB | ~3.9 GB | + +## Quantization + +`whisper.cpp` supports integer quantization of the Whisper `ggml` models. +Quantized models require less memory and disk space and depending on the hardware can be processed more efficiently. + +Here are the steps for creating and using a quantized model: + +```bash +# quantize a model with Q5_0 method +make quantize +./quantize models/ggml-base.en.bin models/ggml-base.en-q5_0.bin q5_0 + +# run the examples as usual, specifying the quantized model file +./main -m models/ggml-base.en-q5_0.bin ./samples/gb0.wav +``` + +## Core ML support + +On Apple Silicon devices, the Encoder inference can be executed on the Apple Neural Engine (ANE) via Core ML. This can result in significant +speed-up - more than x3 faster compared with CPU-only execution. Here are the instructions for generating a Core ML model and using it with `whisper.cpp`: + +- Install Python dependencies needed for the creation of the Core ML model: + + ```bash + pip install ane_transformers + pip install openai-whisper + pip install coremltools + ``` + + - To ensure `coremltools` operates correctly, please confirm that [Xcode](https://developer.apple.com/xcode/) is installed and execute `xcode-select --install` to install the command-line tools. + - Python 3.10 is recommended. + - [OPTIONAL] It is recommended to utilize a Python version management system, such as [Miniconda](https://docs.conda.io/en/latest/miniconda.html) for this step: + - To create an environment, use: `conda create -n py310-whisper python=3.10 -y` + - To activate the environment, use: `conda activate py310-whisper` + +- Generate a Core ML model. For example, to generate a `base.en` model, use: + + ```bash + ./models/generate-coreml-model.sh base.en + ``` + + This will generate the folder `models/ggml-base.en-encoder.mlmodelc` + +- Build `whisper.cpp` with Core ML support: + + ```bash + # using Makefile + make clean + WHISPER_COREML=1 make -j + + # using CMake + cmake -B build -DWHISPER_COREML=1 + cmake --build build -j --config Release + ``` + +- Run the examples as usual. For example: + + ```bash + ./main -m models/ggml-base.en.bin -f samples/jfk.wav + + ... + + whisper_init_state: loading Core ML model from 'models/ggml-base.en-encoder.mlmodelc' + whisper_init_state: first run on a device may take a while ... + whisper_init_state: Core ML model loaded + + system_info: n_threads = 4 / 10 | AVX = 0 | AVX2 = 0 | AVX512 = 0 | FMA = 0 | NEON = 1 | ARM_FMA = 1 | F16C = 0 | FP16_VA = 1 | WASM_SIMD = 0 | BLAS = 1 | SSE3 = 0 | VSX = 0 | COREML = 1 | + + ... + ``` + + The first run on a device is slow, since the ANE service compiles the Core ML model to some device-specific format. + Next runs are faster. + +For more information about the Core ML implementation please refer to PR [#566](https://github.com/ggerganov/whisper.cpp/pull/566). + +## OpenVINO support + +On platforms that support [OpenVINO](https://github.com/openvinotoolkit/openvino), the Encoder inference can be executed +on OpenVINO-supported devices including x86 CPUs and Intel GPUs (integrated & discrete). + +This can result in significant speedup in encoder performance. Here are the instructions for generating the OpenVINO model and using it with `whisper.cpp`: + +- First, setup python virtual env. and install python dependencies. Python 3.10 is recommended. + + Windows: + ``` + cd models + python -m venv openvino_conv_env + openvino_conv_env\Scripts\activate + python -m pip install --upgrade pip + pip install -r openvino-conversion-requirements.txt + ``` + + Linux and macOS: + ``` + cd models + python3 -m venv openvino_conv_env + source openvino_conv_env/bin/activate + python -m pip install --upgrade pip + pip install -r openvino-conversion-requirements.txt + ``` + +- Generate an OpenVINO encoder model. For example, to generate a `base.en` model, use: + + ``` + python convert-whisper-to-openvino.py --model base.en + ``` + + This will produce ggml-base.en-encoder-openvino.xml/.bin IR model files. It's recommended to relocate these to the same folder as ggml models, as that + is the default location that the OpenVINO extension will search at runtime. + +- Build `whisper.cpp` with OpenVINO support: + + Download OpenVINO package from [release page](https://github.com/openvinotoolkit/openvino/releases). The recommended version to use is [2023.0.0](https://github.com/openvinotoolkit/openvino/releases/tag/2023.0.0). + + After downloading & extracting package onto your development system, set up required environment by sourcing setupvars script. For example: + + Linux: + ```bash + source /path/to/l_openvino_toolkit_ubuntu22_2023.0.0.10926.b4452d56304_x86_64/setupvars.sh + ``` + + Windows (cmd): + ``` + C:\Path\To\w_openvino_toolkit_windows_2023.0.0.10926.b4452d56304_x86_64\setupvars.bat + ``` + + And then build the project using cmake: + ```bash + cmake -B build -DWHISPER_OPENVINO=1 + cmake --build build -j --config Release + ``` + +- Run the examples as usual. For example: + ```bash + ./main -m models/ggml-base.en.bin -f samples/jfk.wav + + ... + + whisper_ctx_init_openvino_encoder: loading OpenVINO model from 'models/ggml-base.en-encoder-openvino.xml' + whisper_ctx_init_openvino_encoder: first run on a device may take a while ... + whisper_openvino_init: path_model = models/ggml-base.en-encoder-openvino.xml, device = GPU, cache_dir = models/ggml-base.en-encoder-openvino-cache + whisper_ctx_init_openvino_encoder: OpenVINO model loaded + + system_info: n_threads = 4 / 8 | AVX = 1 | AVX2 = 1 | AVX512 = 0 | FMA = 1 | NEON = 0 | ARM_FMA = 0 | F16C = 1 | FP16_VA = 0 | WASM_SIMD = 0 | BLAS = 0 | SSE3 = 1 | VSX = 0 | COREML = 0 | OPENVINO = 1 | + + ... + ``` + + The first time run on an OpenVINO device is slow, since the OpenVINO framework will compile the IR (Intermediate Representation) model to a device-specific 'blob'. This device-specific blob will get + cached for the next run. + +For more information about the Core ML implementation please refer to PR [#1037](https://github.com/ggerganov/whisper.cpp/pull/1037). + +## NVIDIA GPU support + +With NVIDIA cards the processing of the models is done efficiently on the GPU via cuBLAS and custom CUDA kernels. +First, make sure you have installed `cuda`: https://developer.nvidia.com/cuda-downloads + +Now build `whisper.cpp` with cuBLAS support: + +``` +make clean +WHISPER_CUBLAS=1 make -j +``` + +## OpenCL GPU support via CLBlast + +For cards and integrated GPUs that support OpenCL, the Encoder processing can be largely offloaded to the GPU through CLBlast. This is especially useful for users with AMD APUs or low end devices for up to ~2x speedup. + +First, make sure you have installed `CLBlast` for your OS or Distribution: https://github.com/CNugteren/CLBlast + +Now build `whisper.cpp` with CLBlast support: + +``` +Makefile: +cd whisper.cpp +make clean +WHISPER_CLBLAST=1 make -j + +CMake: +cd whisper.cpp +cmake -B build -DWHISPER_CLBLAST=ON +cmake --build build -j --config Release +``` + + +Run all the examples as usual. + +## BLAS CPU support via OpenBLAS + +Encoder processing can be accelerated on the CPU via OpenBLAS. +First, make sure you have installed `openblas`: https://www.openblas.net/ + +Now build `whisper.cpp` with OpenBLAS support: + +``` +make clean +WHISPER_OPENBLAS=1 make -j +``` + +## Limitations + +- Inference only + +## Another example + +Here is another example of transcribing a [3:24 min speech](https://upload.wikimedia.org/wikipedia/commons/1/1f/George_W_Bush_Columbia_FINAL.ogg) +in about half a minute on a MacBook M1 Pro, using `medium.en` model: + +
+ Expand to see the result + +```java +$ ./main -m models/ggml-medium.en.bin -f samples/gb1.wav -t 8 + +whisper_init_from_file: loading model from 'models/ggml-medium.en.bin' +whisper_model_load: loading model +whisper_model_load: n_vocab = 51864 +whisper_model_load: n_audio_ctx = 1500 +whisper_model_load: n_audio_state = 1024 +whisper_model_load: n_audio_head = 16 +whisper_model_load: n_audio_layer = 24 +whisper_model_load: n_text_ctx = 448 +whisper_model_load: n_text_state = 1024 +whisper_model_load: n_text_head = 16 +whisper_model_load: n_text_layer = 24 +whisper_model_load: n_mels = 80 +whisper_model_load: f16 = 1 +whisper_model_load: type = 4 +whisper_model_load: mem required = 1720.00 MB (+ 43.00 MB per decoder) +whisper_model_load: kv self size = 42.00 MB +whisper_model_load: kv cross size = 140.62 MB +whisper_model_load: adding 1607 extra tokens +whisper_model_load: model ctx = 1462.35 MB +whisper_model_load: model size = 1462.12 MB + +system_info: n_threads = 8 / 10 | AVX = 0 | AVX2 = 0 | AVX512 = 0 | FMA = 0 | NEON = 1 | ARM_FMA = 1 | F16C = 0 | FP16_VA = 1 | WASM_SIMD = 0 | BLAS = 1 | SSE3 = 0 | VSX = 0 | + +main: processing 'samples/gb1.wav' (3179750 samples, 198.7 sec), 8 threads, 1 processors, lang = en, task = transcribe, timestamps = 1 ... + + +[00:00:00.000 --> 00:00:08.000] My fellow Americans, this day has brought terrible news and great sadness to our country. +[00:00:08.000 --> 00:00:17.000] At nine o'clock this morning, Mission Control in Houston lost contact with our Space Shuttle Columbia. +[00:00:17.000 --> 00:00:23.000] A short time later, debris was seen falling from the skies above Texas. +[00:00:23.000 --> 00:00:29.000] The Columbia's lost. There are no survivors. +[00:00:29.000 --> 00:00:32.000] On board was a crew of seven. +[00:00:32.000 --> 00:00:39.000] Colonel Rick Husband, Lieutenant Colonel Michael Anderson, Commander Laurel Clark, +[00:00:39.000 --> 00:00:48.000] Captain David Brown, Commander William McCool, Dr. Kultna Shavla, and Ilan Ramon, +[00:00:48.000 --> 00:00:52.000] a colonel in the Israeli Air Force. +[00:00:52.000 --> 00:00:58.000] These men and women assumed great risk in the service to all humanity. +[00:00:58.000 --> 00:01:03.000] In an age when space flight has come to seem almost routine, +[00:01:03.000 --> 00:01:07.000] it is easy to overlook the dangers of travel by rocket +[00:01:07.000 --> 00:01:12.000] and the difficulties of navigating the fierce outer atmosphere of the Earth. +[00:01:12.000 --> 00:01:18.000] These astronauts knew the dangers, and they faced them willingly, +[00:01:18.000 --> 00:01:23.000] knowing they had a high and noble purpose in life. +[00:01:23.000 --> 00:01:31.000] Because of their courage and daring and idealism, we will miss them all the more. +[00:01:31.000 --> 00:01:36.000] All Americans today are thinking as well of the families of these men and women +[00:01:36.000 --> 00:01:40.000] who have been given this sudden shock and grief. +[00:01:40.000 --> 00:01:45.000] You're not alone. Our entire nation grieves with you, +[00:01:45.000 --> 00:01:52.000] and those you love will always have the respect and gratitude of this country. +[00:01:52.000 --> 00:01:56.000] The cause in which they died will continue. +[00:01:56.000 --> 00:02:04.000] Mankind is led into the darkness beyond our world by the inspiration of discovery +[00:02:04.000 --> 00:02:11.000] and the longing to understand. Our journey into space will go on. +[00:02:11.000 --> 00:02:16.000] In the skies today, we saw destruction and tragedy. +[00:02:16.000 --> 00:02:22.000] Yet farther than we can see, there is comfort and hope. +[00:02:22.000 --> 00:02:29.000] In the words of the prophet Isaiah, "Lift your eyes and look to the heavens +[00:02:29.000 --> 00:02:35.000] who created all these. He who brings out the starry hosts one by one +[00:02:35.000 --> 00:02:39.000] and calls them each by name." +[00:02:39.000 --> 00:02:46.000] Because of His great power and mighty strength, not one of them is missing. +[00:02:46.000 --> 00:02:55.000] The same Creator who names the stars also knows the names of the seven souls we mourn today. +[00:02:55.000 --> 00:03:01.000] The crew of the shuttle Columbia did not return safely to earth, +[00:03:01.000 --> 00:03:05.000] yet we can pray that all are safely home. +[00:03:05.000 --> 00:03:13.000] May God bless the grieving families, and may God continue to bless America. +[00:03:13.000 --> 00:03:19.000] [Silence] + + +whisper_print_timings: fallbacks = 1 p / 0 h +whisper_print_timings: load time = 569.03 ms +whisper_print_timings: mel time = 146.85 ms +whisper_print_timings: sample time = 238.66 ms / 553 runs ( 0.43 ms per run) +whisper_print_timings: encode time = 18665.10 ms / 9 runs ( 2073.90 ms per run) +whisper_print_timings: decode time = 13090.93 ms / 549 runs ( 23.85 ms per run) +whisper_print_timings: total time = 32733.52 ms +``` +
+ +## Real-time audio input example + +This is a naive example of performing real-time inference on audio from your microphone. +The [stream](examples/stream) tool samples the audio every half a second and runs the transcription continuously. +More info is available in [issue #10](https://github.com/ggerganov/whisper.cpp/issues/10). + +```java +make stream +./stream -m ./models/ggml-base.en.bin -t 8 --step 500 --length 5000 +``` + +https://user-images.githubusercontent.com/1991296/194935793-76afede7-cfa8-48d8-a80f-28ba83be7d09.mp4 + +## Confidence color-coding + +Adding the `--print-colors` argument will print the transcribed text using an experimental color coding strategy +to highlight words with high or low confidence: + +```java +./main -m models/ggml-base.en.bin -f samples/gb0.wav --print-colors +``` + +image + +## Controlling the length of the generated text segments (experimental) + +For example, to limit the line length to a maximum of 16 characters, simply add `-ml 16`: + +```java +./main -m ./models/ggml-base.en.bin -f ./samples/jfk.wav -ml 16 + +whisper_model_load: loading model from './models/ggml-base.en.bin' +... +system_info: n_threads = 4 / 10 | AVX2 = 0 | AVX512 = 0 | NEON = 1 | FP16_VA = 1 | WASM_SIMD = 0 | BLAS = 1 | + +main: processing './samples/jfk.wav' (176000 samples, 11.0 sec), 4 threads, 1 processors, lang = en, task = transcribe, timestamps = 1 ... + +[00:00:00.000 --> 00:00:00.850] And so my +[00:00:00.850 --> 00:00:01.590] fellow +[00:00:01.590 --> 00:00:04.140] Americans, ask +[00:00:04.140 --> 00:00:05.660] not what your +[00:00:05.660 --> 00:00:06.840] country can do +[00:00:06.840 --> 00:00:08.430] for you, ask +[00:00:08.430 --> 00:00:09.440] what you can do +[00:00:09.440 --> 00:00:10.020] for your +[00:00:10.020 --> 00:00:11.000] country. +``` + +## Word-level timestamp (experimental) + +The `--max-len` argument can be used to obtain word-level timestamps. Simply use `-ml 1`: + +```java +./main -m ./models/ggml-base.en.bin -f ./samples/jfk.wav -ml 1 + +whisper_model_load: loading model from './models/ggml-base.en.bin' +... +system_info: n_threads = 4 / 10 | AVX2 = 0 | AVX512 = 0 | NEON = 1 | FP16_VA = 1 | WASM_SIMD = 0 | BLAS = 1 | + +main: processing './samples/jfk.wav' (176000 samples, 11.0 sec), 4 threads, 1 processors, lang = en, task = transcribe, timestamps = 1 ... + +[00:00:00.000 --> 00:00:00.320] +[00:00:00.320 --> 00:00:00.370] And +[00:00:00.370 --> 00:00:00.690] so +[00:00:00.690 --> 00:00:00.850] my +[00:00:00.850 --> 00:00:01.590] fellow +[00:00:01.590 --> 00:00:02.850] Americans +[00:00:02.850 --> 00:00:03.300] , +[00:00:03.300 --> 00:00:04.140] ask +[00:00:04.140 --> 00:00:04.990] not +[00:00:04.990 --> 00:00:05.410] what +[00:00:05.410 --> 00:00:05.660] your +[00:00:05.660 --> 00:00:06.260] country +[00:00:06.260 --> 00:00:06.600] can +[00:00:06.600 --> 00:00:06.840] do +[00:00:06.840 --> 00:00:07.010] for +[00:00:07.010 --> 00:00:08.170] you +[00:00:08.170 --> 00:00:08.190] , +[00:00:08.190 --> 00:00:08.430] ask +[00:00:08.430 --> 00:00:08.910] what +[00:00:08.910 --> 00:00:09.040] you +[00:00:09.040 --> 00:00:09.320] can +[00:00:09.320 --> 00:00:09.440] do +[00:00:09.440 --> 00:00:09.760] for +[00:00:09.760 --> 00:00:10.020] your +[00:00:10.020 --> 00:00:10.510] country +[00:00:10.510 --> 00:00:11.000] . +``` + +## Speaker segmentation via tinydiarize (experimental) + +More information about this approach is available here: https://github.com/ggerganov/whisper.cpp/pull/1058 + +Sample usage: + +```py +# download a tinydiarize compatible model +./models/download-ggml-model.sh small.en-tdrz + +# run as usual, adding the "-tdrz" command-line argument +./main -f ./samples/a13.wav -m ./models/ggml-small.en-tdrz.bin -tdrz +... +main: processing './samples/a13.wav' (480000 samples, 30.0 sec), 4 threads, 1 processors, lang = en, task = transcribe, tdrz = 1, timestamps = 1 ... +... +[00:00:00.000 --> 00:00:03.800] Okay Houston, we've had a problem here. [SPEAKER_TURN] +[00:00:03.800 --> 00:00:06.200] This is Houston. Say again please. [SPEAKER_TURN] +[00:00:06.200 --> 00:00:08.260] Uh Houston we've had a problem. +[00:00:08.260 --> 00:00:11.320] We've had a main beam up on a volt. [SPEAKER_TURN] +[00:00:11.320 --> 00:00:13.820] Roger main beam interval. [SPEAKER_TURN] +[00:00:13.820 --> 00:00:15.100] Uh uh [SPEAKER_TURN] +[00:00:15.100 --> 00:00:18.020] So okay stand, by thirteen we're looking at it. [SPEAKER_TURN] +[00:00:18.020 --> 00:00:25.740] Okay uh right now uh Houston the uh voltage is uh is looking good um. +[00:00:27.620 --> 00:00:29.940] And we had a a pretty large bank or so. +``` + +## Karaoke-style movie generation (experimental) + +The [main](examples/main) example provides support for output of karaoke-style movies, where the +currently pronounced word is highlighted. Use the `-wts` argument and run the generated bash script. +This requires to have `ffmpeg` installed. + +Here are a few *"typical"* examples: + +```java +./main -m ./models/ggml-base.en.bin -f ./samples/jfk.wav -owts +source ./samples/jfk.wav.wts +ffplay ./samples/jfk.wav.mp4 +``` + +https://user-images.githubusercontent.com/1991296/199337465-dbee4b5e-9aeb-48a3-b1c6-323ac4db5b2c.mp4 + +--- + +```java +./main -m ./models/ggml-base.en.bin -f ./samples/mm0.wav -owts +source ./samples/mm0.wav.wts +ffplay ./samples/mm0.wav.mp4 +``` + +https://user-images.githubusercontent.com/1991296/199337504-cc8fd233-0cb7-4920-95f9-4227de3570aa.mp4 + +--- + +```java +./main -m ./models/ggml-base.en.bin -f ./samples/gb0.wav -owts +source ./samples/gb0.wav.wts +ffplay ./samples/gb0.wav.mp4 +``` + +https://user-images.githubusercontent.com/1991296/199337538-b7b0c7a3-2753-4a88-a0cd-f28a317987ba.mp4 + +--- + +## Video comparison of different models + +Use the [extra/bench-wts.sh](https://github.com/ggerganov/whisper.cpp/blob/master/extra/bench-wts.sh) script to generate a video in the following format: + +```java +./extra/bench-wts.sh samples/jfk.wav +ffplay ./samples/jfk.wav.all.mp4 +``` + +https://user-images.githubusercontent.com/1991296/223206245-2d36d903-cf8e-4f09-8c3b-eb9f9c39d6fc.mp4 + +--- + +## Benchmarks + +In order to have an objective comparison of the performance of the inference across different system configurations, +use the [bench](examples/bench) tool. The tool simply runs the Encoder part of the model and prints how much time it +took to execute it. The results are summarized in the following Github issue: + +[Benchmark results](https://github.com/ggerganov/whisper.cpp/issues/89) + +Additionally a script to run whisper.cpp with different models and audio files is provided [bench.py](bench.py). + +You can run it with the following command, by default it will run against any standard model in the models folder. + +```bash +python3 extra/bench.py -f samples/jfk.wav -t 2,4,8 -p 1,2 +``` + +It is written in python with the intention of being easy to modify and extend for your benchmarking use case. + +It outputs a csv file with the results of the benchmarking. + + +## ggml format + +The original models are converted to a custom binary format. This allows to pack everything needed into a single file: + +- model parameters +- mel filters +- vocabulary +- weights + +You can download the converted models using the [models/download-ggml-model.sh](models/download-ggml-model.sh) script +or manually from here: + +- https://huggingface.co/ggerganov/whisper.cpp +- https://ggml.ggerganov.com + +For more details, see the conversion script [models/convert-pt-to-ggml.py](models/convert-pt-to-ggml.py) or the README +in [models](models). + +## [Bindings](https://github.com/ggerganov/whisper.cpp/discussions/categories/bindings) + +- [X] Rust: [tazz4843/whisper-rs](https://github.com/tazz4843/whisper-rs) | [#310](https://github.com/ggerganov/whisper.cpp/discussions/310) +- [X] JavaScript: [bindings/javascript](bindings/javascript) | [#309](https://github.com/ggerganov/whisper.cpp/discussions/309) + - React Native (iOS / Android): [whisper.rn](https://github.com/mybigday/whisper.rn) +- [X] Go: [bindings/go](bindings/go) | [#312](https://github.com/ggerganov/whisper.cpp/discussions/312) +- [X] Java: + - [GiviMAD/whisper-jni](https://github.com/GiviMAD/whisper-jni) +- [X] Ruby: [bindings/ruby](bindings/ruby) | [#507](https://github.com/ggerganov/whisper.cpp/discussions/507) +- [X] Objective-C / Swift: [ggerganov/whisper.spm](https://github.com/ggerganov/whisper.spm) | [#313](https://github.com/ggerganov/whisper.cpp/discussions/313) + - [exPHAT/SwiftWhisper](https://github.com/exPHAT/SwiftWhisper) +- [X] .NET: | [#422](https://github.com/ggerganov/whisper.cpp/discussions/422) + - [sandrohanea/whisper.net](https://github.com/sandrohanea/whisper.net) + - [NickDarvey/whisper](https://github.com/NickDarvey/whisper) +- [X] Python: | [#9](https://github.com/ggerganov/whisper.cpp/issues/9) + - [stlukey/whispercpp.py](https://github.com/stlukey/whispercpp.py) (Cython) + - [aarnphm/whispercpp](https://github.com/aarnphm/whispercpp) (Pybind11) +- [X] R: [bnosac/audio.whisper](https://github.com/bnosac/audio.whisper) +- [X] Unity: [macoron/whisper.unity](https://github.com/Macoron/whisper.unity) + +## Examples + +There are various examples of using the library for different projects in the [examples](examples) folder. +Some of the examples are even ported to run in the browser using WebAssembly. Check them out! + +| Example | Web | Description | +| --- | --- | --- | +| [main](examples/main) | [whisper.wasm](examples/whisper.wasm) | Tool for translating and transcribing audio using Whisper | +| [bench](examples/bench) | [bench.wasm](examples/bench.wasm) | Benchmark the performance of Whisper on your machine | +| [stream](examples/stream) | [stream.wasm](examples/stream.wasm) | Real-time transcription of raw microphone capture | +| [command](examples/command) | [command.wasm](examples/command.wasm) | Basic voice assistant example for receiving voice commands from the mic | +| [talk](examples/talk) | [talk.wasm](examples/talk.wasm) | Talk with a GPT-2 bot | +| [talk-llama](examples/talk-llama) | | Talk with a LLaMA bot | +| [whisper.objc](examples/whisper.objc) | | iOS mobile application using whisper.cpp | +| [whisper.swiftui](examples/whisper.swiftui) | | SwiftUI iOS / macOS application using whisper.cpp | +| [whisper.android](examples/whisper.android) | | Android mobile application using whisper.cpp | +| [whisper.nvim](examples/whisper.nvim) | | Speech-to-text plugin for Neovim | +| [generate-karaoke.sh](examples/generate-karaoke.sh) | | Helper script to easily [generate a karaoke video](https://youtu.be/uj7hVta4blM) of raw audio capture | +| [livestream.sh](examples/livestream.sh) | | [Livestream audio transcription](https://github.com/ggerganov/whisper.cpp/issues/185) | +| [yt-wsp.sh](examples/yt-wsp.sh) | | Download + transcribe and/or translate any VOD [(original)](https://gist.github.com/DaniruKun/96f763ec1a037cc92fe1a059b643b818) | +| [server](examples/server) | | HTTP transcription server with OAI-like API | + +## [Discussions](https://github.com/ggerganov/whisper.cpp/discussions) + +If you have any kind of feedback about this project feel free to use the Discussions section and open a new topic. +You can use the [Show and tell](https://github.com/ggerganov/whisper.cpp/discussions/categories/show-and-tell) category +to share your own projects that use `whisper.cpp`. If you have a question, make sure to check the +[Frequently asked questions (#126)](https://github.com/ggerganov/whisper.cpp/discussions/126) discussion. diff --git a/sys/whisper.cpp/bindings/CMakeLists.txt b/sys/whisper.cpp/bindings/CMakeLists.txt new file mode 100644 index 0000000..af79c51 --- /dev/null +++ b/sys/whisper.cpp/bindings/CMakeLists.txt @@ -0,0 +1,19 @@ +if (EMSCRIPTEN) + add_subdirectory(javascript) + + add_custom_command( + OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/javascript/publish.log + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/javascript/whisper.js + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/javascript/libwhisper.worker.js + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/javascript/package.json + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/javascript + COMMAND npm publish + COMMAND touch publish.log + COMMENT "Publishing npm module v${PROJECT_VERSION}" + VERBATIM + ) + + add_custom_target(publish-npm + DEPENDS javascript/publish.log + ) +endif() diff --git a/sys/whisper.cpp/bindings/go/.gitignore b/sys/whisper.cpp/bindings/go/.gitignore new file mode 100644 index 0000000..036df1d --- /dev/null +++ b/sys/whisper.cpp/bindings/go/.gitignore @@ -0,0 +1,2 @@ +build +models diff --git a/sys/whisper.cpp/bindings/go/LICENSE b/sys/whisper.cpp/bindings/go/LICENSE new file mode 100644 index 0000000..a8f0d7b --- /dev/null +++ b/sys/whisper.cpp/bindings/go/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 David Thorpe + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/sys/whisper.cpp/bindings/go/Makefile b/sys/whisper.cpp/bindings/go/Makefile new file mode 100644 index 0000000..4f3a416 --- /dev/null +++ b/sys/whisper.cpp/bindings/go/Makefile @@ -0,0 +1,64 @@ +ifndef UNAME_S +UNAME_S := $(shell uname -s) +endif + +ifndef UNAME_P +UNAME_P := $(shell uname -p) +endif + +ifndef UNAME_M +UNAME_M := $(shell uname -m) +endif + +GGML_METAL_PATH_RESOURCES := $(abspath ../..) +BUILD_DIR := build +MODELS_DIR := models +EXAMPLES_DIR := $(wildcard examples/*) +INCLUDE_PATH := $(abspath ../..) +LIBRARY_PATH := $(abspath ../..) + +ifeq ($(UNAME_S),Darwin) + EXT_LDFLAGS := -framework Foundation -framework Metal -framework MetalKit +endif + +all: clean whisper examples + +whisper: mkdir + @echo Build whisper + @${MAKE} -C ../.. libwhisper.a + +test: model-small whisper modtidy +ifeq ($(UNAME_S),Darwin) + @C_INCLUDE_PATH=${INCLUDE_PATH} LIBRARY_PATH=${LIBRARY_PATH} GGML_METAL_PATH_RESOURCES=${GGML_METAL_PATH_RESOURCES} go test -ldflags "-extldflags '$(EXT_LDFLAGS)'" -v . + @C_INCLUDE_PATH=${INCLUDE_PATH} LIBRARY_PATH=${LIBRARY_PATH} GGML_METAL_PATH_RESOURCES=${GGML_METAL_PATH_RESOURCES} go test -ldflags "-extldflags '$(EXT_LDFLAGS)'" -v ./pkg/whisper/... +else + @C_INCLUDE_PATH=${INCLUDE_PATH} LIBRARY_PATH=${LIBRARY_PATH} go test -v . + @C_INCLUDE_PATH=${INCLUDE_PATH} LIBRARY_PATH=${LIBRARY_PATH} go test -v ./pkg/whisper/... +endif + +examples: $(EXAMPLES_DIR) + +model-small: mkdir examples/go-model-download + @${BUILD_DIR}/go-model-download -out models ggml-small.en.bin + +$(EXAMPLES_DIR): mkdir whisper modtidy + @echo Build example $(notdir $@) +ifeq ($(UNAME_S),Darwin) + @C_INCLUDE_PATH=${INCLUDE_PATH} LIBRARY_PATH=${LIBRARY_PATH} GGML_METAL_PATH_RESOURCES=${GGML_METAL_PATH_RESOURCES} go build ${BUILD_FLAGS} -ldflags "-extldflags '$(EXT_LDFLAGS)'" -o ${BUILD_DIR}/$(notdir $@) ./$@ +else + @C_INCLUDE_PATH=${INCLUDE_PATH} LIBRARY_PATH=${LIBRARY_PATH} go build ${BUILD_FLAGS} -o ${BUILD_DIR}/$(notdir $@) ./$@ +endif + +mkdir: + @echo Mkdir ${BUILD_DIR} + @install -d ${BUILD_DIR} + @echo Mkdir ${MODELS_DIR} + @install -d ${MODELS_DIR} + +modtidy: + @go mod tidy + +clean: + @echo Clean + @rm -fr $(BUILD_DIR) + @go clean diff --git a/sys/whisper.cpp/bindings/go/README.md b/sys/whisper.cpp/bindings/go/README.md new file mode 100644 index 0000000..1968cfd --- /dev/null +++ b/sys/whisper.cpp/bindings/go/README.md @@ -0,0 +1,100 @@ +# Go bindings for Whisper + +This package provides Go bindings for whisper.cpp. They have been tested on: + + * Darwin (OS X) 12.6 on x64_64 + * Debian Linux on arm64 + * Fedora Linux on x86_64 + +The "low level" bindings are in the `bindings/go` directory and there is a more +Go-style package in the `bindings/go/pkg/whisper` directory. The most simple usage +is as follows: + +```go +import ( + "github.com/ggerganov/whisper.cpp/bindings/go/pkg/whisper" +) + +func main() { + var modelpath string // Path to the model + var samples []float32 // Samples to process + + // Load the model + model, err := whisper.New(modelpath) + if err != nil { + panic(err) + } + defer model.Close() + + // Process samples + context, err := model.NewContext() + if err != nil { + panic(err) + } + if err := context.Process(samples, nil, nil); err != nil { + return err + } + + // Print out the results + for { + segment, err := context.NextSegment() + if err != nil { + break + } + fmt.Printf("[%6s->%6s] %s\n", segment.Start, segment.End, segment.Text) + } +} +``` + +## Building & Testing + +In order to build, you need to have the Go compiler installed. You can get it from [here](https://golang.org/dl/). Run the tests with: + +```bash +git clone https://github.com/ggerganov/whisper.cpp.git +cd whisper.cpp/bindings/go +make test +``` + +This will compile a static `libwhisper.a` in a `build` folder, download a model file, then run the tests. To build the examples: + +```bash +make examples +``` + +The examples are placed in the `build` directory. Once built, you can download all the models with the following command: + +```bash +./build/go-model-download -out models +``` + +And you can then test a model against samples with the following command: + +```bash +./build/go-whisper -model models/ggml-tiny.en.bin samples/jfk.wav +``` + +## Using the bindings + +To use the bindings in your own software, + + 1. Import `github.com/ggerganov/whisper.cpp/bindings/go/pkg/whisper` (or `github.com/ggerganov/whisper.cpp/bindings/go` into your package; + 2. Compile `libwhisper.a` (you can use `make whisper` in the `bindings/go` directory); + 3. Link your go binary against whisper by setting the environment variables `C_INCLUDE_PATH` and `LIBRARY_PATH` + to point to the `whisper.h` file directory and `libwhisper.a` file directory respectively. + +Look at the `Makefile` in the `bindings/go` directory for an example. + +The API Documentation: + + * https://pkg.go.dev/github.com/ggerganov/whisper.cpp/bindings/go + * https://pkg.go.dev/github.com/ggerganov/whisper.cpp/bindings/go/pkg/whisper + +Getting help: + + * Follow the discussion for the go bindings [here](https://github.com/ggerganov/whisper.cpp/discussions/312) + +## License + +The license for the Go bindings is the same as the license for the rest of the whisper.cpp project, which is the MIT License. See the `LICENSE` file for more details. + diff --git a/sys/whisper.cpp/bindings/go/doc.go b/sys/whisper.cpp/bindings/go/doc.go new file mode 100644 index 0000000..dcc351f --- /dev/null +++ b/sys/whisper.cpp/bindings/go/doc.go @@ -0,0 +1,5 @@ +/* +github.com/ggerganov/whisper.cpp/bindings/go +provides a speech-to-text service bindings for the Go programming language. +*/ +package whisper diff --git a/sys/whisper.cpp/bindings/go/examples/go-model-download/context.go b/sys/whisper.cpp/bindings/go/examples/go-model-download/context.go new file mode 100644 index 0000000..639d8f5 --- /dev/null +++ b/sys/whisper.cpp/bindings/go/examples/go-model-download/context.go @@ -0,0 +1,30 @@ +package main + +import ( + "context" + "os" + "os/signal" +) + +// ContextForSignal returns a context object which is cancelled when a signal +// is received. It returns nil if no signal parameter is provided +func ContextForSignal(signals ...os.Signal) context.Context { + if len(signals) == 0 { + return nil + } + + ch := make(chan os.Signal) + ctx, cancel := context.WithCancel(context.Background()) + + // Send message on channel when signal received + signal.Notify(ch, signals...) + + // When any signal received, call cancel + go func() { + <-ch + cancel() + }() + + // Return success + return ctx +} diff --git a/sys/whisper.cpp/bindings/go/examples/go-model-download/main.go b/sys/whisper.cpp/bindings/go/examples/go-model-download/main.go new file mode 100644 index 0000000..3522d88 --- /dev/null +++ b/sys/whisper.cpp/bindings/go/examples/go-model-download/main.go @@ -0,0 +1,208 @@ +package main + +import ( + "context" + "flag" + "fmt" + "io" + "net/http" + "net/url" + "os" + "path/filepath" + "syscall" + "time" +) + +/////////////////////////////////////////////////////////////////////////////// +// CONSTANTS + +const ( + srcUrl = "https://huggingface.co/ggerganov/whisper.cpp/resolve/main" // The location of the models + srcExt = ".bin" // Filename extension + bufSize = 1024 * 64 // Size of the buffer used for downloading the model +) + +var ( + // The models which will be downloaded, if no model is specified as an argument + modelNames = []string{"ggml-tiny.en", "ggml-tiny", "ggml-base.en", "ggml-base", "ggml-small.en", "ggml-small", "ggml-medium.en", "ggml-medium", "ggml-large-v1", "ggml-large-v2", "ggml-large-v3"} +) + +var ( + // The output folder. When not set, use current working directory. + flagOut = flag.String("out", "", "Output folder") + + // HTTP timeout parameter - will timeout if takes longer than this to download a model + flagTimeout = flag.Duration("timeout", 30*time.Minute, "HTTP timeout") + + // Quiet parameter - will not print progress if set + flagQuiet = flag.Bool("quiet", false, "Quiet mode") +) + +/////////////////////////////////////////////////////////////////////////////// +// MAIN + +func main() { + flag.Usage = func() { + name := filepath.Base(flag.CommandLine.Name()) + fmt.Fprintf(flag.CommandLine.Output(), "Usage: %s [options] \n\n", name) + flag.PrintDefaults() + } + flag.Parse() + + // Get output path + out, err := GetOut() + if err != nil { + fmt.Fprintln(os.Stderr, "Error:", err) + os.Exit(-1) + } + + // Create context which quits on SIGINT or SIGQUIT + ctx := ContextForSignal(os.Interrupt, syscall.SIGQUIT) + + // Progress filehandle + progress := os.Stdout + if *flagQuiet { + progress, err = os.Open(os.DevNull) + if err != nil { + fmt.Fprintln(os.Stderr, "Error:", err) + os.Exit(-1) + } + defer progress.Close() + } + + // Download models - exit on error or interrupt + for _, model := range GetModels() { + url, err := URLForModel(model) + if err != nil { + fmt.Fprintln(os.Stderr, "Error:", err) + continue + } else if path, err := Download(ctx, progress, url, out); err == nil || err == io.EOF { + continue + } else if err == context.Canceled { + os.Remove(path) + fmt.Fprintln(progress, "\nInterrupted") + break + } else if err == context.DeadlineExceeded { + os.Remove(path) + fmt.Fprintln(progress, "Timeout downloading model") + continue + } else { + os.Remove(path) + fmt.Fprintln(os.Stderr, "Error:", err) + break + } + } +} + +/////////////////////////////////////////////////////////////////////////////// +// PUBLIC METHODS + +// GetOut returns the path to the output directory +func GetOut() (string, error) { + if *flagOut == "" { + return os.Getwd() + } + if info, err := os.Stat(*flagOut); err != nil { + return "", err + } else if !info.IsDir() { + return "", fmt.Errorf("not a directory: %s", info.Name()) + } else { + return *flagOut, nil + } +} + +// GetModels returns the list of models to download +func GetModels() []string { + if flag.NArg() == 0 { + return modelNames + } else { + return flag.Args() + } +} + +// URLForModel returns the URL for the given model on huggingface.co +func URLForModel(model string) (string, error) { + if filepath.Ext(model) != srcExt { + model += srcExt + } + url, err := url.Parse(srcUrl) + if err != nil { + return "", err + } else { + url.Path = filepath.Join(url.Path, model) + } + return url.String(), nil +} + +// Download downloads the model from the given URL to the given output directory +func Download(ctx context.Context, p io.Writer, model, out string) (string, error) { + // Create HTTP client + client := http.Client{ + Timeout: *flagTimeout, + } + + // Initiate the download + req, err := http.NewRequest("GET", model, nil) + if err != nil { + return "", err + } + resp, err := client.Do(req) + if err != nil { + return "", err + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + return "", fmt.Errorf("%s: %s", model, resp.Status) + } + + // If output file exists and is the same size as the model, skip + path := filepath.Join(out, filepath.Base(model)) + if info, err := os.Stat(path); err == nil && info.Size() == resp.ContentLength { + fmt.Fprintln(p, "Skipping", model, "as it already exists") + return "", nil + } + + // Create file + w, err := os.Create(path) + if err != nil { + return "", err + } + defer w.Close() + + // Report + fmt.Fprintln(p, "Downloading", model, "to", out) + + // Progressively download the model + data := make([]byte, bufSize) + count, pct := int64(0), int64(0) + ticker := time.NewTicker(5 * time.Second) + for { + select { + case <-ctx.Done(): + // Cancelled, return error + return path, ctx.Err() + case <-ticker.C: + pct = DownloadReport(p, pct, count, resp.ContentLength) + default: + // Read body + n, err := resp.Body.Read(data) + if err != nil { + DownloadReport(p, pct, count, resp.ContentLength) + return path, err + } else if m, err := w.Write(data[:n]); err != nil { + return path, err + } else { + count += int64(m) + } + } + } +} + +// Report periodically reports the download progress when percentage changes +func DownloadReport(w io.Writer, pct, count, total int64) int64 { + pct_ := count * 100 / total + if pct_ > pct { + fmt.Fprintf(w, " ...%d MB written (%d%%)\n", count/1e6, pct_) + } + return pct_ +} diff --git a/sys/whisper.cpp/bindings/go/examples/go-whisper/color.go b/sys/whisper.cpp/bindings/go/examples/go-whisper/color.go new file mode 100644 index 0000000..fa5ac2f --- /dev/null +++ b/sys/whisper.cpp/bindings/go/examples/go-whisper/color.go @@ -0,0 +1,22 @@ +package main + +import "fmt" + +/////////////////////////////////////////////////////////////////////////////// +// CONSTANTS + +const ( + Reset = "\033[0m" + RGBPrefix = "\033[38;5;" // followed by RGB values in decimal format separated by colons + RGBSuffix = "m" +) + +/////////////////////////////////////////////////////////////////////////////// +// PUBLIC METHODS + +// Colorize text with RGB values, from 0 to 23 +func Colorize(text string, v int) string { + // https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit + // Grayscale colors are in the range 232-255 + return RGBPrefix + fmt.Sprint(v%24+232) + RGBSuffix + text + Reset +} diff --git a/sys/whisper.cpp/bindings/go/examples/go-whisper/flags.go b/sys/whisper.cpp/bindings/go/examples/go-whisper/flags.go new file mode 100644 index 0000000..ea20445 --- /dev/null +++ b/sys/whisper.cpp/bindings/go/examples/go-whisper/flags.go @@ -0,0 +1,156 @@ +package main + +import ( + "flag" + "fmt" + "strings" + "time" + + // Packages + whisper "github.com/ggerganov/whisper.cpp/bindings/go/pkg/whisper" +) + +/////////////////////////////////////////////////////////////////////////////// +// TYPES + +type Flags struct { + *flag.FlagSet +} + +/////////////////////////////////////////////////////////////////////////////// +// LIFECYCLE + +func NewFlags(name string, args []string) (*Flags, error) { + flags := &Flags{ + FlagSet: flag.NewFlagSet(name, flag.ContinueOnError), + } + + // Register the command line arguments + registerFlags(flags) + + // Parse command line + if err := flags.Parse(args); err != nil { + return nil, err + } + + // Return success + return flags, nil +} + +/////////////////////////////////////////////////////////////////////////////// +// PUBLIC METHODS + +func (flags *Flags) GetModel() string { + return flags.Lookup("model").Value.String() +} + +func (flags *Flags) GetLanguage() string { + return flags.Lookup("language").Value.String() +} + +func (flags *Flags) IsTranslate() bool { + return flags.Lookup("translate").Value.(flag.Getter).Get().(bool) +} + +func (flags *Flags) GetOffset() time.Duration { + return flags.Lookup("offset").Value.(flag.Getter).Get().(time.Duration) +} + +func (flags *Flags) GetDuration() time.Duration { + return flags.Lookup("duration").Value.(flag.Getter).Get().(time.Duration) +} + +func (flags *Flags) GetThreads() uint { + return flags.Lookup("threads").Value.(flag.Getter).Get().(uint) +} + +func (flags *Flags) GetOut() string { + return strings.ToLower(flags.Lookup("out").Value.String()) +} + +func (flags *Flags) IsSpeedup() bool { + return flags.Lookup("speedup").Value.String() == "true" +} + +func (flags *Flags) IsTokens() bool { + return flags.Lookup("tokens").Value.String() == "true" +} + +func (flags *Flags) IsColorize() bool { + return flags.Lookup("colorize").Value.String() == "true" +} + +func (flags *Flags) GetMaxLen() uint { + return flags.Lookup("max-len").Value.(flag.Getter).Get().(uint) +} + +func (flags *Flags) GetMaxTokens() uint { + return flags.Lookup("max-tokens").Value.(flag.Getter).Get().(uint) +} + +func (flags *Flags) GetWordThreshold() float32 { + return float32(flags.Lookup("word-thold").Value.(flag.Getter).Get().(float64)) +} + +func (flags *Flags) SetParams(context whisper.Context) error { + if lang := flags.GetLanguage(); lang != "" && lang != "auto" { + fmt.Fprintf(flags.Output(), "Setting language to %q\n", lang) + if err := context.SetLanguage(lang); err != nil { + return err + } + } + if flags.IsTranslate() && context.IsMultilingual() { + fmt.Fprintf(flags.Output(), "Setting translate to true\n") + context.SetTranslate(true) + } + if offset := flags.GetOffset(); offset != 0 { + fmt.Fprintf(flags.Output(), "Setting offset to %v\n", offset) + context.SetOffset(offset) + } + if duration := flags.GetDuration(); duration != 0 { + fmt.Fprintf(flags.Output(), "Setting duration to %v\n", duration) + context.SetDuration(duration) + } + if flags.IsSpeedup() { + fmt.Fprintf(flags.Output(), "Setting speedup to true\n") + context.SetSpeedup(true) + } + if threads := flags.GetThreads(); threads != 0 { + fmt.Fprintf(flags.Output(), "Setting threads to %d\n", threads) + context.SetThreads(threads) + } + if max_len := flags.GetMaxLen(); max_len != 0 { + fmt.Fprintf(flags.Output(), "Setting max_segment_length to %d\n", max_len) + context.SetMaxSegmentLength(max_len) + } + if max_tokens := flags.GetMaxTokens(); max_tokens != 0 { + fmt.Fprintf(flags.Output(), "Setting max_tokens to %d\n", max_tokens) + context.SetMaxTokensPerSegment(max_tokens) + } + if word_threshold := flags.GetWordThreshold(); word_threshold != 0 { + fmt.Fprintf(flags.Output(), "Setting word_threshold to %f\n", word_threshold) + context.SetTokenThreshold(word_threshold) + } + + // Return success + return nil +} + +/////////////////////////////////////////////////////////////////////////////// +// PRIVATE METHODS + +func registerFlags(flag *Flags) { + flag.String("model", "", "Path to the model file") + flag.String("language", "", "Spoken language") + flag.Bool("translate", false, "Translate from source language to english") + flag.Duration("offset", 0, "Time offset") + flag.Duration("duration", 0, "Duration of audio to process") + flag.Uint("threads", 0, "Number of threads to use") + flag.Bool("speedup", false, "Enable speedup") + flag.Uint("max-len", 0, "Maximum segment length in characters") + flag.Uint("max-tokens", 0, "Maximum tokens per segment") + flag.Float64("word-thold", 0, "Maximum segment score") + flag.Bool("tokens", false, "Display tokens") + flag.Bool("colorize", false, "Colorize tokens") + flag.String("out", "", "Output format (srt, none or leave as empty string)") +} diff --git a/sys/whisper.cpp/bindings/go/examples/go-whisper/main.go b/sys/whisper.cpp/bindings/go/examples/go-whisper/main.go new file mode 100644 index 0000000..1bff7f5 --- /dev/null +++ b/sys/whisper.cpp/bindings/go/examples/go-whisper/main.go @@ -0,0 +1,43 @@ +package main + +import ( + "flag" + "fmt" + "os" + "path/filepath" + + // Packages + whisper "github.com/ggerganov/whisper.cpp/bindings/go/pkg/whisper" +) + +func main() { + flags, err := NewFlags(filepath.Base(os.Args[0]), os.Args[1:]) + if err == flag.ErrHelp { + os.Exit(0) + } else if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } else if flags.GetModel() == "" { + fmt.Fprintln(os.Stderr, "Use -model flag to specify which model file to use") + os.Exit(1) + } else if flags.NArg() == 0 { + fmt.Fprintln(os.Stderr, "No input files specified") + os.Exit(1) + } + + // Load model + model, err := whisper.New(flags.GetModel()) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + defer model.Close() + + // Process files + for _, filename := range flags.Args() { + if err := Process(model, filename, flags); err != nil { + fmt.Fprintln(os.Stderr, err) + continue + } + } +} diff --git a/sys/whisper.cpp/bindings/go/examples/go-whisper/process.go b/sys/whisper.cpp/bindings/go/examples/go-whisper/process.go new file mode 100644 index 0000000..71e52f0 --- /dev/null +++ b/sys/whisper.cpp/bindings/go/examples/go-whisper/process.go @@ -0,0 +1,132 @@ +package main + +import ( + "fmt" + "io" + "os" + "time" + + // Package imports + whisper "github.com/ggerganov/whisper.cpp/bindings/go/pkg/whisper" + wav "github.com/go-audio/wav" +) + +func Process(model whisper.Model, path string, flags *Flags) error { + var data []float32 + + // Create processing context + context, err := model.NewContext() + if err != nil { + return err + } + + // Set the parameters + if err := flags.SetParams(context); err != nil { + return err + } + + fmt.Printf("\n%s\n", context.SystemInfo()) + + // Open the file + fmt.Fprintf(flags.Output(), "Loading %q\n", path) + fh, err := os.Open(path) + if err != nil { + return err + } + defer fh.Close() + + // Decode the WAV file - load the full buffer + dec := wav.NewDecoder(fh) + if buf, err := dec.FullPCMBuffer(); err != nil { + return err + } else if dec.SampleRate != whisper.SampleRate { + return fmt.Errorf("unsupported sample rate: %d", dec.SampleRate) + } else if dec.NumChans != 1 { + return fmt.Errorf("unsupported number of channels: %d", dec.NumChans) + } else { + data = buf.AsFloat32Buffer().Data + } + + // Segment callback when -tokens is specified + var cb whisper.SegmentCallback + if flags.IsTokens() { + cb = func(segment whisper.Segment) { + fmt.Fprintf(flags.Output(), "%02d [%6s->%6s] ", segment.Num, segment.Start.Truncate(time.Millisecond), segment.End.Truncate(time.Millisecond)) + for _, token := range segment.Tokens { + if flags.IsColorize() && context.IsText(token) { + fmt.Fprint(flags.Output(), Colorize(token.Text, int(token.P*24.0)), " ") + } else { + fmt.Fprint(flags.Output(), token.Text, " ") + } + } + fmt.Fprintln(flags.Output(), "") + fmt.Fprintln(flags.Output(), "") + } + } + + // Process the data + fmt.Fprintf(flags.Output(), " ...processing %q\n", path) + context.ResetTimings() + if err := context.Process(data, cb, nil); err != nil { + return err + } + + context.PrintTimings() + + // Print out the results + switch { + case flags.GetOut() == "srt": + return OutputSRT(os.Stdout, context) + case flags.GetOut() == "none": + return nil + default: + return Output(os.Stdout, context, flags.IsColorize()) + } +} + +// Output text as SRT file +func OutputSRT(w io.Writer, context whisper.Context) error { + n := 1 + for { + segment, err := context.NextSegment() + if err == io.EOF { + return nil + } else if err != nil { + return err + } + fmt.Fprintln(w, n) + fmt.Fprintln(w, srtTimestamp(segment.Start), " --> ", srtTimestamp(segment.End)) + fmt.Fprintln(w, segment.Text) + fmt.Fprintln(w, "") + n++ + } +} + +// Output text to terminal +func Output(w io.Writer, context whisper.Context, colorize bool) error { + for { + segment, err := context.NextSegment() + if err == io.EOF { + return nil + } else if err != nil { + return err + } + fmt.Fprintf(w, "[%6s->%6s]", segment.Start.Truncate(time.Millisecond), segment.End.Truncate(time.Millisecond)) + if colorize { + for _, token := range segment.Tokens { + if !context.IsText(token) { + continue + } + fmt.Fprint(w, " ", Colorize(token.Text, int(token.P*24.0))) + } + fmt.Fprint(w, "\n") + } else { + fmt.Fprintln(w, " ", segment.Text) + } + } +} + +// Return srtTimestamp +func srtTimestamp(t time.Duration) string { + return fmt.Sprintf("%02d:%02d:%02d,%03d", t/time.Hour, (t%time.Hour)/time.Minute, (t%time.Minute)/time.Second, (t%time.Second)/time.Millisecond) +} diff --git a/sys/whisper.cpp/bindings/go/go.mod b/sys/whisper.cpp/bindings/go/go.mod new file mode 100644 index 0000000..594f184 --- /dev/null +++ b/sys/whisper.cpp/bindings/go/go.mod @@ -0,0 +1,16 @@ +module github.com/ggerganov/whisper.cpp/bindings/go + +go 1.19 + +require ( + github.com/go-audio/wav v1.1.0 + github.com/stretchr/testify v1.8.1 +) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/go-audio/audio v1.0.0 // indirect + github.com/go-audio/riff v1.0.0 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/sys/whisper.cpp/bindings/go/go.sum b/sys/whisper.cpp/bindings/go/go.sum new file mode 100644 index 0000000..870ebdc --- /dev/null +++ b/sys/whisper.cpp/bindings/go/go.sum @@ -0,0 +1,23 @@ +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/go-audio/audio v1.0.0 h1:zS9vebldgbQqktK4H0lUqWrG8P0NxCJVqcj7ZpNnwd4= +github.com/go-audio/audio v1.0.0/go.mod h1:6uAu0+H2lHkwdGsAY+j2wHPNPpPoeg5AaEFh9FlA+Zs= +github.com/go-audio/riff v1.0.0 h1:d8iCGbDvox9BfLagY94fBynxSPHO80LmZCaOsmKxokA= +github.com/go-audio/riff v1.0.0/go.mod h1:l3cQwc85y79NQFCRB7TiPoNiaijp6q8Z0Uv38rVG498= +github.com/go-audio/wav v1.1.0 h1:jQgLtbqBzY7G+BM8fXF7AHUk1uHUviWS4X39d5rsL2g= +github.com/go-audio/wav v1.1.0/go.mod h1:mpe9qfwbScEbkd8uybLuIpTgHyrISw/OTuvjUW2iGtE= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/sys/whisper.cpp/bindings/go/params.go b/sys/whisper.cpp/bindings/go/params.go new file mode 100644 index 0000000..3c9dd5c --- /dev/null +++ b/sys/whisper.cpp/bindings/go/params.go @@ -0,0 +1,179 @@ +package whisper + +import ( + "fmt" +) + +/////////////////////////////////////////////////////////////////////////////// +// CGO + +/* +#include +*/ +import "C" + +/////////////////////////////////////////////////////////////////////////////// +// PUBLIC METHODS + +func (p *Params) SetTranslate(v bool) { + p.translate = toBool(v) +} + +func (p *Params) SetSplitOnWord(v bool) { + p.split_on_word = toBool(v) +} + +func (p *Params) SetNoContext(v bool) { + p.no_context = toBool(v) +} + +func (p *Params) SetSingleSegment(v bool) { + p.single_segment = toBool(v) +} + +func (p *Params) SetPrintSpecial(v bool) { + p.print_special = toBool(v) +} + +func (p *Params) SetPrintProgress(v bool) { + p.print_progress = toBool(v) +} + +func (p *Params) SetPrintRealtime(v bool) { + p.print_realtime = toBool(v) +} + +func (p *Params) SetPrintTimestamps(v bool) { + p.print_timestamps = toBool(v) +} + +func (p *Params) SetSpeedup(v bool) { + p.speed_up = toBool(v) +} + +// Set language id +func (p *Params) SetLanguage(lang int) error { + if lang == -1 { + p.language = nil + return nil + } + str := C.whisper_lang_str(C.int(lang)) + if str == nil { + return ErrInvalidLanguage + } else { + p.language = str + } + return nil +} + +// Get language id +func (p *Params) Language() int { + if p.language == nil { + return -1 + } + return int(C.whisper_lang_id(p.language)) +} + +// Threads available +func (p *Params) Threads() int { + return int(p.n_threads) +} + +// Set number of threads to use +func (p *Params) SetThreads(threads int) { + p.n_threads = C.int(threads) +} + +// Set start offset in ms +func (p *Params) SetOffset(offset_ms int) { + p.offset_ms = C.int(offset_ms) +} + +// Set audio duration to process in ms +func (p *Params) SetDuration(duration_ms int) { + p.duration_ms = C.int(duration_ms) +} + +// Set timestamp token probability threshold (~0.01) +func (p *Params) SetTokenThreshold(t float32) { + p.thold_pt = C.float(t) +} + +// Set timestamp token sum probability threshold (~0.01) +func (p *Params) SetTokenSumThreshold(t float32) { + p.thold_ptsum = C.float(t) +} + +// Set max segment length in characters +func (p *Params) SetMaxSegmentLength(n int) { + p.max_len = C.int(n) +} + +func (p *Params) SetTokenTimestamps(b bool) { + p.token_timestamps = toBool(b) +} + +// Set max tokens per segment (0 = no limit) +func (p *Params) SetMaxTokensPerSegment(n int) { + p.max_tokens = C.int(n) +} + +// Set audio encoder context +func (p *Params) SetAudioCtx(n int) { + p.audio_ctx = C.int(n) +} + +/////////////////////////////////////////////////////////////////////////////// +// PRIVATE METHODS + +func toBool(v bool) C.bool { + if v { + return C.bool(true) + } + return C.bool(false) +} + +/////////////////////////////////////////////////////////////////////////////// +// STRINGIFY + +func (p *Params) String() string { + str := "" +} diff --git a/sys/whisper.cpp/bindings/go/pkg/whisper/consts.go b/sys/whisper.cpp/bindings/go/pkg/whisper/consts.go new file mode 100644 index 0000000..5c22dc1 --- /dev/null +++ b/sys/whisper.cpp/bindings/go/pkg/whisper/consts.go @@ -0,0 +1,28 @@ +package whisper + +import ( + "errors" + + // Bindings + whisper "github.com/ggerganov/whisper.cpp/bindings/go" +) + +/////////////////////////////////////////////////////////////////////////////// +// ERRORS + +var ( + ErrUnableToLoadModel = errors.New("unable to load model") + ErrInternalAppError = errors.New("internal application error") + ErrProcessingFailed = errors.New("processing failed") + ErrUnsupportedLanguage = errors.New("unsupported language") + ErrModelNotMultilingual = errors.New("model is not multilingual") +) + +/////////////////////////////////////////////////////////////////////////////// +// CONSTANTS + +// SampleRate is the sample rate of the audio data. +const SampleRate = whisper.SampleRate + +// SampleBits is the number of bytes per sample. +const SampleBits = whisper.SampleBits diff --git a/sys/whisper.cpp/bindings/go/pkg/whisper/context.go b/sys/whisper.cpp/bindings/go/pkg/whisper/context.go new file mode 100644 index 0000000..f51d4f8 --- /dev/null +++ b/sys/whisper.cpp/bindings/go/pkg/whisper/context.go @@ -0,0 +1,316 @@ +package whisper + +import ( + "fmt" + "io" + "runtime" + "strings" + "time" + + // Bindings + whisper "github.com/ggerganov/whisper.cpp/bindings/go" +) + +/////////////////////////////////////////////////////////////////////////////// +// TYPES + +type context struct { + n int + model *model + params whisper.Params +} + +// Make sure context adheres to the interface +var _ Context = (*context)(nil) + +/////////////////////////////////////////////////////////////////////////////// +// LIFECYCLE + +func newContext(model *model, params whisper.Params) (Context, error) { + context := new(context) + context.model = model + context.params = params + + // Return success + return context, nil +} + +/////////////////////////////////////////////////////////////////////////////// +// PUBLIC METHODS + +// Set the language to use for speech recognition. +func (context *context) SetLanguage(lang string) error { + if context.model.ctx == nil { + return ErrInternalAppError + } + if !context.model.IsMultilingual() { + return ErrModelNotMultilingual + } + + if lang == "auto" { + context.params.SetLanguage(-1) + } else if id := context.model.ctx.Whisper_lang_id(lang); id < 0 { + return ErrUnsupportedLanguage + } else if err := context.params.SetLanguage(id); err != nil { + return err + } + // Return success + return nil +} + +func (context *context) IsMultilingual() bool { + return context.model.IsMultilingual() +} + +// Get language +func (context *context) Language() string { + id := context.params.Language() + if id == -1 { + return "auto" + } + return whisper.Whisper_lang_str(context.params.Language()) +} + +// Set translate flag +func (context *context) SetTranslate(v bool) { + context.params.SetTranslate(v) +} + +// Set speedup flag +func (context *context) SetSpeedup(v bool) { + context.params.SetSpeedup(v) +} + +func (context *context) SetSplitOnWord(v bool) { + context.params.SetSplitOnWord(v) +} + +// Set number of threads to use +func (context *context) SetThreads(v uint) { + context.params.SetThreads(int(v)) +} + +// Set time offset +func (context *context) SetOffset(v time.Duration) { + context.params.SetOffset(int(v.Milliseconds())) +} + +// Set duration of audio to process +func (context *context) SetDuration(v time.Duration) { + context.params.SetDuration(int(v.Milliseconds())) +} + +// Set timestamp token probability threshold (~0.01) +func (context *context) SetTokenThreshold(t float32) { + context.params.SetTokenThreshold(t) +} + +// Set timestamp token sum probability threshold (~0.01) +func (context *context) SetTokenSumThreshold(t float32) { + context.params.SetTokenSumThreshold(t) +} + +// Set max segment length in characters +func (context *context) SetMaxSegmentLength(n uint) { + context.params.SetMaxSegmentLength(int(n)) +} + +// Set token timestamps flag +func (context *context) SetTokenTimestamps(b bool) { + context.params.SetTokenTimestamps(b) +} + +// Set max tokens per segment (0 = no limit) +func (context *context) SetMaxTokensPerSegment(n uint) { + context.params.SetMaxTokensPerSegment(int(n)) +} + +// Set audio encoder context +func (context *context) SetAudioCtx(n uint) { + context.params.SetAudioCtx(int(n)) +} + +// ResetTimings resets the mode timings. Should be called before processing +func (context *context) ResetTimings() { + context.model.ctx.Whisper_reset_timings() +} + +// PrintTimings prints the model timings to stdout. +func (context *context) PrintTimings() { + context.model.ctx.Whisper_print_timings() +} + +// SystemInfo returns the system information +func (context *context) SystemInfo() string { + return fmt.Sprintf("system_info: n_threads = %d / %d | %s\n", + context.params.Threads(), + runtime.NumCPU(), + whisper.Whisper_print_system_info(), + ) +} + +// Use mel data at offset_ms to try and auto-detect the spoken language +// Make sure to call whisper_pcm_to_mel() or whisper_set_mel() first. +// Returns the probabilities of all languages. +func (context *context) WhisperLangAutoDetect(offset_ms int, n_threads int) ([]float32, error) { + langProbs, err := context.model.ctx.Whisper_lang_auto_detect(offset_ms, n_threads) + if err != nil { + return nil, err + } + return langProbs, nil +} + +// Process new sample data and return any errors +func (context *context) Process( + data []float32, + callNewSegment SegmentCallback, + callProgress ProgressCallback, +) error { + if context.model.ctx == nil { + return ErrInternalAppError + } + // If the callback is defined then we force on single_segment mode + if callNewSegment != nil { + context.params.SetSingleSegment(true) + } + + // We don't do parallel processing at the moment + processors := 0 + if processors > 1 { + if err := context.model.ctx.Whisper_full_parallel(context.params, data, processors, nil, func(new int) { + if callNewSegment != nil { + num_segments := context.model.ctx.Whisper_full_n_segments() + s0 := num_segments - new + for i := s0; i < num_segments; i++ { + callNewSegment(toSegment(context.model.ctx, i)) + } + } + }); err != nil { + return err + } + } else if err := context.model.ctx.Whisper_full(context.params, data, nil, func(new int) { + if callNewSegment != nil { + num_segments := context.model.ctx.Whisper_full_n_segments() + s0 := num_segments - new + for i := s0; i < num_segments; i++ { + callNewSegment(toSegment(context.model.ctx, i)) + } + } + }, func(progress int) { + if callProgress != nil { + callProgress(progress) + } + }); err != nil { + return err + } + + // Return success + return nil +} + +// Return the next segment of tokens +func (context *context) NextSegment() (Segment, error) { + if context.model.ctx == nil { + return Segment{}, ErrInternalAppError + } + if context.n >= context.model.ctx.Whisper_full_n_segments() { + return Segment{}, io.EOF + } + + // Populate result + result := toSegment(context.model.ctx, context.n) + + // Increment the cursor + context.n++ + + // Return success + return result, nil +} + +// Test for text tokens +func (context *context) IsText(t Token) bool { + switch { + case context.IsBEG(t): + return false + case context.IsSOT(t): + return false + case whisper.Token(t.Id) >= context.model.ctx.Whisper_token_eot(): + return false + case context.IsPREV(t): + return false + case context.IsSOLM(t): + return false + case context.IsNOT(t): + return false + default: + return true + } +} + +// Test for "begin" token +func (context *context) IsBEG(t Token) bool { + return whisper.Token(t.Id) == context.model.ctx.Whisper_token_beg() +} + +// Test for "start of transcription" token +func (context *context) IsSOT(t Token) bool { + return whisper.Token(t.Id) == context.model.ctx.Whisper_token_sot() +} + +// Test for "end of transcription" token +func (context *context) IsEOT(t Token) bool { + return whisper.Token(t.Id) == context.model.ctx.Whisper_token_eot() +} + +// Test for "start of prev" token +func (context *context) IsPREV(t Token) bool { + return whisper.Token(t.Id) == context.model.ctx.Whisper_token_prev() +} + +// Test for "start of lm" token +func (context *context) IsSOLM(t Token) bool { + return whisper.Token(t.Id) == context.model.ctx.Whisper_token_solm() +} + +// Test for "No timestamps" token +func (context *context) IsNOT(t Token) bool { + return whisper.Token(t.Id) == context.model.ctx.Whisper_token_not() +} + +// Test for token associated with a specific language +func (context *context) IsLANG(t Token, lang string) bool { + if id := context.model.ctx.Whisper_lang_id(lang); id >= 0 { + return whisper.Token(t.Id) == context.model.ctx.Whisper_token_lang(id) + } else { + return false + } +} + +/////////////////////////////////////////////////////////////////////////////// +// PRIVATE METHODS + +func toSegment(ctx *whisper.Context, n int) Segment { + return Segment{ + Num: n, + Text: strings.TrimSpace(ctx.Whisper_full_get_segment_text(n)), + Start: time.Duration(ctx.Whisper_full_get_segment_t0(n)) * time.Millisecond * 10, + End: time.Duration(ctx.Whisper_full_get_segment_t1(n)) * time.Millisecond * 10, + Tokens: toTokens(ctx, n), + } +} + +func toTokens(ctx *whisper.Context, n int) []Token { + result := make([]Token, ctx.Whisper_full_n_tokens(n)) + for i := 0; i < len(result); i++ { + data := ctx.Whisper_full_get_token_data(n, i) + + result[i] = Token{ + Id: int(ctx.Whisper_full_get_token_id(n, i)), + Text: ctx.Whisper_full_get_token_text(n, i), + P: ctx.Whisper_full_get_token_p(n, i), + Start: time.Duration(data.T0()) * time.Millisecond * 10, + End: time.Duration(data.T1()) * time.Millisecond * 10, + } + } + return result +} diff --git a/sys/whisper.cpp/bindings/go/pkg/whisper/context_test.go b/sys/whisper.cpp/bindings/go/pkg/whisper/context_test.go new file mode 100644 index 0000000..c8c6016 --- /dev/null +++ b/sys/whisper.cpp/bindings/go/pkg/whisper/context_test.go @@ -0,0 +1,55 @@ +package whisper_test + +import ( + "os" + "testing" + + // Packages + whisper "github.com/ggerganov/whisper.cpp/bindings/go/pkg/whisper" + assert "github.com/stretchr/testify/assert" +) + +const ( + ModelPath = "../../models/ggml-tiny.bin" + SamplePath = "../../samples/jfk.wav" +) + +func Test_Whisper_000(t *testing.T) { + assert := assert.New(t) + if _, err := os.Stat(ModelPath); os.IsNotExist(err) { + t.Skip("Skipping test, model not found:", ModelPath) + } + if _, err := os.Stat(SamplePath); os.IsNotExist(err) { + t.Skip("Skipping test, sample not found:", SamplePath) + } + + // Load model + model, err := whisper.New(ModelPath) + assert.NoError(err) + assert.NotNil(model) + assert.NoError(model.Close()) + + t.Log("languages=", model.Languages()) +} + +func Test_Whisper_001(t *testing.T) { + assert := assert.New(t) + if _, err := os.Stat(ModelPath); os.IsNotExist(err) { + t.Skip("Skipping test, model not found:", ModelPath) + } + if _, err := os.Stat(SamplePath); os.IsNotExist(err) { + t.Skip("Skipping test, sample not found:", SamplePath) + } + + // Load model + model, err := whisper.New(ModelPath) + assert.NoError(err) + assert.NotNil(model) + defer model.Close() + + // Get context for decoding + ctx, err := model.NewContext() + assert.NoError(err) + assert.NotNil(ctx) + +} diff --git a/sys/whisper.cpp/bindings/go/pkg/whisper/doc.go b/sys/whisper.cpp/bindings/go/pkg/whisper/doc.go new file mode 100644 index 0000000..fd4f1b9 --- /dev/null +++ b/sys/whisper.cpp/bindings/go/pkg/whisper/doc.go @@ -0,0 +1,4 @@ +/* +This is the higher-level speech-to-text whisper.cpp API for go +*/ +package whisper diff --git a/sys/whisper.cpp/bindings/go/pkg/whisper/interface.go b/sys/whisper.cpp/bindings/go/pkg/whisper/interface.go new file mode 100644 index 0000000..4744271 --- /dev/null +++ b/sys/whisper.cpp/bindings/go/pkg/whisper/interface.go @@ -0,0 +1,99 @@ +package whisper + +import ( + "io" + "time" +) + +/////////////////////////////////////////////////////////////////////////////// +// TYPES + +// SegmentCallback is the callback function for processing segments in real +// time. It is called during the Process function +type SegmentCallback func(Segment) + +// ProgressCallback is the callback function for reporting progress during +// processing. It is called during the Process function +type ProgressCallback func(int) + +// Model is the interface to a whisper model. Create a new model with the +// function whisper.New(string) +type Model interface { + io.Closer + + // Return a new speech-to-text context. + NewContext() (Context, error) + + // Return true if the model is multilingual. + IsMultilingual() bool + + // Return all languages supported. + Languages() []string +} + +// Context is the speach recognition context. +type Context interface { + SetLanguage(string) error // Set the language to use for speech recognition, use "auto" for auto detect language. + SetTranslate(bool) // Set translate flag + IsMultilingual() bool // Return true if the model is multilingual. + Language() string // Get language + + SetOffset(time.Duration) // Set offset + SetDuration(time.Duration) // Set duration + SetThreads(uint) // Set number of threads to use + SetSpeedup(bool) // Set speedup flag + SetSplitOnWord(bool) // Set split on word flag + SetTokenThreshold(float32) // Set timestamp token probability threshold + SetTokenSumThreshold(float32) // Set timestamp token sum probability threshold + SetMaxSegmentLength(uint) // Set max segment length in characters + SetTokenTimestamps(bool) // Set token timestamps flag + SetMaxTokensPerSegment(uint) // Set max tokens per segment (0 = no limit) + SetAudioCtx(uint) // Set audio encoder context + + // Process mono audio data and return any errors. + // If defined, newly generated segments are passed to the + // callback function during processing. + Process([]float32, SegmentCallback, ProgressCallback) error + + // After process is called, return segments until the end of the stream + // is reached, when io.EOF is returned. + NextSegment() (Segment, error) + + IsBEG(Token) bool // Test for "begin" token + IsSOT(Token) bool // Test for "start of transcription" token + IsEOT(Token) bool // Test for "end of transcription" token + IsPREV(Token) bool // Test for "start of prev" token + IsSOLM(Token) bool // Test for "start of lm" token + IsNOT(Token) bool // Test for "No timestamps" token + IsLANG(Token, string) bool // Test for token associated with a specific language + IsText(Token) bool // Test for text token + + // Timings + PrintTimings() + ResetTimings() + + SystemInfo() string +} + +// Segment is the text result of a speech recognition. +type Segment struct { + // Segment Number + Num int + + // Time beginning and end timestamps for the segment. + Start, End time.Duration + + // The text of the segment. + Text string + + // The tokens of the segment. + Tokens []Token +} + +// Token is a text or special token +type Token struct { + Id int + Text string + P float32 + Start, End time.Duration +} diff --git a/sys/whisper.cpp/bindings/go/pkg/whisper/model.go b/sys/whisper.cpp/bindings/go/pkg/whisper/model.go new file mode 100644 index 0000000..68a1502 --- /dev/null +++ b/sys/whisper.cpp/bindings/go/pkg/whisper/model.go @@ -0,0 +1,101 @@ +package whisper + +import ( + "fmt" + "os" + "runtime" + + // Bindings + whisper "github.com/ggerganov/whisper.cpp/bindings/go" +) + +/////////////////////////////////////////////////////////////////////////////// +// TYPES + +type model struct { + path string + ctx *whisper.Context +} + +// Make sure model adheres to the interface +var _ Model = (*model)(nil) + +/////////////////////////////////////////////////////////////////////////////// +// LIFECYCLE + +func New(path string) (Model, error) { + model := new(model) + if _, err := os.Stat(path); err != nil { + return nil, err + } else if ctx := whisper.Whisper_init(path); ctx == nil { + return nil, ErrUnableToLoadModel + } else { + model.ctx = ctx + model.path = path + } + + // Return success + return model, nil +} + +func (model *model) Close() error { + if model.ctx != nil { + model.ctx.Whisper_free() + } + + // Release resources + model.ctx = nil + + // Return success + return nil +} + +/////////////////////////////////////////////////////////////////////////////// +// STRINGIFY + +func (model *model) String() string { + str := "" +} + +/////////////////////////////////////////////////////////////////////////////// +// PUBLIC METHODS + +// Return true if model is multilingual (language and translation options are supported) +func (model *model) IsMultilingual() bool { + return model.ctx.Whisper_is_multilingual() != 0 +} + +// Return all recognized languages. Initially it is set to auto-detect +func (model *model) Languages() []string { + result := make([]string, 0, whisper.Whisper_lang_max_id()) + for i := 0; i < whisper.Whisper_lang_max_id(); i++ { + str := whisper.Whisper_lang_str(i) + if model.ctx.Whisper_lang_id(str) >= 0 { + result = append(result, str) + } + } + return result +} + +func (model *model) NewContext() (Context, error) { + if model.ctx == nil { + return nil, ErrInternalAppError + } + + // Create new context + params := model.ctx.Whisper_full_default_params(whisper.SAMPLING_GREEDY) + params.SetTranslate(false) + params.SetPrintSpecial(false) + params.SetPrintProgress(false) + params.SetPrintRealtime(false) + params.SetPrintTimestamps(false) + params.SetThreads(runtime.NumCPU()) + params.SetNoContext(true) + + // Return new context + return newContext(model, params) +} diff --git a/sys/whisper.cpp/bindings/go/samples/jfk.wav b/sys/whisper.cpp/bindings/go/samples/jfk.wav new file mode 100644 index 0000000..3184d37 Binary files /dev/null and b/sys/whisper.cpp/bindings/go/samples/jfk.wav differ diff --git a/sys/whisper.cpp/bindings/go/whisper.go b/sys/whisper.cpp/bindings/go/whisper.go new file mode 100644 index 0000000..9660662 --- /dev/null +++ b/sys/whisper.cpp/bindings/go/whisper.go @@ -0,0 +1,468 @@ +package whisper + +import ( + "errors" + "unsafe" +) + +/////////////////////////////////////////////////////////////////////////////// +// CGO + +/* +#cgo LDFLAGS: -lwhisper -lm -lstdc++ +#cgo darwin LDFLAGS: -framework Accelerate +#include +#include + +extern void callNewSegment(void* user_data, int new); +extern void callProgress(void* user_data, int progress); +extern bool callEncoderBegin(void* user_data); + +// Text segment callback +// Called on every newly generated text segment +// Use the whisper_full_...() functions to obtain the text segments +static void whisper_new_segment_cb(struct whisper_context* ctx, struct whisper_state* state, int n_new, void* user_data) { + if(user_data != NULL && ctx != NULL) { + callNewSegment(user_data, n_new); + } +} + +// Progress callback +// Called on every newly generated text segment +// Use the whisper_full_...() functions to obtain the text segments +static void whisper_progress_cb(struct whisper_context* ctx, struct whisper_state* state, int progress, void* user_data) { + if(user_data != NULL && ctx != NULL) { + callProgress(user_data, progress); + } +} + +// Encoder begin callback +// If not NULL, called before the encoder starts +// If it returns false, the computation is aborted +static bool whisper_encoder_begin_cb(struct whisper_context* ctx, struct whisper_state* state, void* user_data) { + if(user_data != NULL && ctx != NULL) { + return callEncoderBegin(user_data); + } + return false; +} + +// Get default parameters and set callbacks +static struct whisper_full_params whisper_full_default_params_cb(struct whisper_context* ctx, enum whisper_sampling_strategy strategy) { + struct whisper_full_params params = whisper_full_default_params(strategy); + params.new_segment_callback = whisper_new_segment_cb; + params.new_segment_callback_user_data = (void*)(ctx); + params.encoder_begin_callback = whisper_encoder_begin_cb; + params.encoder_begin_callback_user_data = (void*)(ctx); + params.progress_callback = whisper_progress_cb; + params.progress_callback_user_data = (void*)(ctx); + return params; +} +*/ +import "C" + +/////////////////////////////////////////////////////////////////////////////// +// TYPES + +type ( + Context C.struct_whisper_context + Token C.whisper_token + TokenData C.struct_whisper_token_data + SamplingStrategy C.enum_whisper_sampling_strategy + Params C.struct_whisper_full_params +) + +/////////////////////////////////////////////////////////////////////////////// +// GLOBALS + +const ( + SAMPLING_GREEDY SamplingStrategy = C.WHISPER_SAMPLING_GREEDY + SAMPLING_BEAM_SEARCH SamplingStrategy = C.WHISPER_SAMPLING_BEAM_SEARCH +) + +const ( + SampleRate = C.WHISPER_SAMPLE_RATE // Expected sample rate, samples per second + SampleBits = uint16(unsafe.Sizeof(C.float(0))) * 8 // Sample size in bits + NumFFT = C.WHISPER_N_FFT + HopLength = C.WHISPER_HOP_LENGTH + ChunkSize = C.WHISPER_CHUNK_SIZE +) + +var ( + ErrTokenizerFailed = errors.New("whisper_tokenize failed") + ErrAutoDetectFailed = errors.New("whisper_lang_auto_detect failed") + ErrConversionFailed = errors.New("whisper_convert failed") + ErrInvalidLanguage = errors.New("invalid language") +) + +/////////////////////////////////////////////////////////////////////////////// +// PUBLIC METHODS + +// Allocates all memory needed for the model and loads the model from the given file. +// Returns NULL on failure. +func Whisper_init(path string) *Context { + cPath := C.CString(path) + defer C.free(unsafe.Pointer(cPath)) + if ctx := C.whisper_init_from_file_with_params(cPath, C.whisper_context_default_params()); ctx != nil { + return (*Context)(ctx) + } else { + return nil + } +} + +// Frees all memory allocated by the model. +func (ctx *Context) Whisper_free() { + C.whisper_free((*C.struct_whisper_context)(ctx)) +} + +// Convert RAW PCM audio to log mel spectrogram. +// The resulting spectrogram is stored inside the provided whisper context. +func (ctx *Context) Whisper_pcm_to_mel(data []float32, threads int) error { + if C.whisper_pcm_to_mel((*C.struct_whisper_context)(ctx), (*C.float)(&data[0]), C.int(len(data)), C.int(threads)) == 0 { + return nil + } else { + return ErrConversionFailed + } +} + +// This can be used to set a custom log mel spectrogram inside the provided whisper context. +// Use this instead of whisper_pcm_to_mel() if you want to provide your own log mel spectrogram. +// n_mel must be 80 +func (ctx *Context) Whisper_set_mel(data []float32, n_mel int) error { + if C.whisper_set_mel((*C.struct_whisper_context)(ctx), (*C.float)(&data[0]), C.int(len(data)), C.int(n_mel)) == 0 { + return nil + } else { + return ErrConversionFailed + } +} + +// Run the Whisper encoder on the log mel spectrogram stored inside the provided whisper context. +// Make sure to call whisper_pcm_to_mel() or whisper_set_mel() first. +// offset can be used to specify the offset of the first frame in the spectrogram. +func (ctx *Context) Whisper_encode(offset, threads int) error { + if C.whisper_encode((*C.struct_whisper_context)(ctx), C.int(offset), C.int(threads)) == 0 { + return nil + } else { + return ErrConversionFailed + } +} + +// Run the Whisper decoder to obtain the logits and probabilities for the next token. +// Make sure to call whisper_encode() first. +// tokens + n_tokens is the provided context for the decoder. +// n_past is the number of tokens to use from previous decoder calls. +func (ctx *Context) Whisper_decode(tokens []Token, past, threads int) error { + if C.whisper_decode((*C.struct_whisper_context)(ctx), (*C.whisper_token)(&tokens[0]), C.int(len(tokens)), C.int(past), C.int(threads)) == 0 { + return nil + } else { + return ErrConversionFailed + } +} + +// Convert the provided text into tokens. The tokens pointer must be large enough to hold the resulting tokens. +// Returns the number of tokens on success +func (ctx *Context) Whisper_tokenize(text string, tokens []Token) (int, error) { + cText := C.CString(text) + defer C.free(unsafe.Pointer(cText)) + if n := C.whisper_tokenize((*C.struct_whisper_context)(ctx), cText, (*C.whisper_token)(&tokens[0]), C.int(len(tokens))); n >= 0 { + return int(n), nil + } else { + return 0, ErrTokenizerFailed + } +} + +// Return the id of the specified language, returns -1 if not found +// Examples: +// +// "de" -> 2 +// "german" -> 2 +func (ctx *Context) Whisper_lang_id(lang string) int { + return int(C.whisper_lang_id(C.CString(lang))) +} + +// Largest language id (i.e. number of available languages - 1) +func Whisper_lang_max_id() int { + return int(C.whisper_lang_max_id()) +} + +// Return the short string of the specified language id (e.g. 2 -> "de"), +// returns empty string if not found +func Whisper_lang_str(id int) string { + return C.GoString(C.whisper_lang_str(C.int(id))) +} + +// Use mel data at offset_ms to try and auto-detect the spoken language +// Make sure to call whisper_pcm_to_mel() or whisper_set_mel() first. +// Returns the probabilities of all languages. +// ref: https://github.com/openai/whisper/blob/main/whisper/decoding.py#L18-L69 +func (ctx *Context) Whisper_lang_auto_detect(offset_ms, n_threads int) ([]float32, error) { + probs := make([]float32, Whisper_lang_max_id()+1) + if n := int(C.whisper_lang_auto_detect((*C.struct_whisper_context)(ctx), C.int(offset_ms), C.int(n_threads), (*C.float)(&probs[0]))); n < 0 { + return nil, ErrAutoDetectFailed + } else { + return probs, nil + } +} + +func (ctx *Context) Whisper_n_len() int { + return int(C.whisper_n_len((*C.struct_whisper_context)(ctx))) +} + +func (ctx *Context) Whisper_n_vocab() int { + return int(C.whisper_n_vocab((*C.struct_whisper_context)(ctx))) +} + +func (ctx *Context) Whisper_n_text_ctx() int { + return int(C.whisper_n_text_ctx((*C.struct_whisper_context)(ctx))) +} + +func (ctx *Context) Whisper_n_audio_ctx() int { + return int(C.whisper_n_audio_ctx((*C.struct_whisper_context)(ctx))) +} + +func (ctx *Context) Whisper_is_multilingual() int { + return int(C.whisper_is_multilingual((*C.struct_whisper_context)(ctx))) +} + +// The probabilities for the next token +//func (ctx *Whisper_context) Whisper_get_probs() []float32 { +// return (*[1 << 30]float32)(unsafe.Pointer(C.whisper_get_probs((*C.struct_whisper_context)(ctx))))[:ctx.Whisper_n_vocab()] +//} + +// Token Id -> String. Uses the vocabulary in the provided context +func (ctx *Context) Whisper_token_to_str(token Token) string { + return C.GoString(C.whisper_token_to_str((*C.struct_whisper_context)(ctx), C.whisper_token(token))) +} + +// Special tokens +func (ctx *Context) Whisper_token_eot() Token { + return Token(C.whisper_token_eot((*C.struct_whisper_context)(ctx))) +} + +// Special tokens +func (ctx *Context) Whisper_token_sot() Token { + return Token(C.whisper_token_sot((*C.struct_whisper_context)(ctx))) +} + +// Special tokens +func (ctx *Context) Whisper_token_prev() Token { + return Token(C.whisper_token_prev((*C.struct_whisper_context)(ctx))) +} + +// Special tokens +func (ctx *Context) Whisper_token_solm() Token { + return Token(C.whisper_token_solm((*C.struct_whisper_context)(ctx))) +} + +// Special tokens +func (ctx *Context) Whisper_token_not() Token { + return Token(C.whisper_token_not((*C.struct_whisper_context)(ctx))) +} + +// Special tokens +func (ctx *Context) Whisper_token_beg() Token { + return Token(C.whisper_token_beg((*C.struct_whisper_context)(ctx))) +} + +// Special tokens +func (ctx *Context) Whisper_token_lang(lang_id int) Token { + return Token(C.whisper_token_lang((*C.struct_whisper_context)(ctx), C.int(lang_id))) +} + +// Task tokens +func (ctx *Context) Whisper_token_translate() Token { + return Token(C.whisper_token_translate((*C.struct_whisper_context)(ctx))) +} + +// Task tokens +func (ctx *Context) Whisper_token_transcribe() Token { + return Token(C.whisper_token_transcribe((*C.struct_whisper_context)(ctx))) +} + +// Performance information +func (ctx *Context) Whisper_print_timings() { + C.whisper_print_timings((*C.struct_whisper_context)(ctx)) +} + +// Performance information +func (ctx *Context) Whisper_reset_timings() { + C.whisper_reset_timings((*C.struct_whisper_context)(ctx)) +} + +// Print system information +func Whisper_print_system_info() string { + return C.GoString(C.whisper_print_system_info()) +} + +// Return default parameters for a strategy +func (ctx *Context) Whisper_full_default_params(strategy SamplingStrategy) Params { + // Get default parameters + return Params(C.whisper_full_default_params_cb((*C.struct_whisper_context)(ctx), C.enum_whisper_sampling_strategy(strategy))) +} + +// Run the entire model: PCM -> log mel spectrogram -> encoder -> decoder -> text +// Uses the specified decoding strategy to obtain the text. +func (ctx *Context) Whisper_full( + params Params, + samples []float32, + encoderBeginCallback func() bool, + newSegmentCallback func(int), + progressCallback func(int), +) error { + registerEncoderBeginCallback(ctx, encoderBeginCallback) + registerNewSegmentCallback(ctx, newSegmentCallback) + registerProgressCallback(ctx, progressCallback) + defer registerEncoderBeginCallback(ctx, nil) + defer registerNewSegmentCallback(ctx, nil) + defer registerProgressCallback(ctx, nil) + if C.whisper_full((*C.struct_whisper_context)(ctx), (C.struct_whisper_full_params)(params), (*C.float)(&samples[0]), C.int(len(samples))) == 0 { + return nil + } else { + return ErrConversionFailed + } +} + +// Split the input audio in chunks and process each chunk separately using whisper_full() +// It seems this approach can offer some speedup in some cases. +// However, the transcription accuracy can be worse at the beginning and end of each chunk. +func (ctx *Context) Whisper_full_parallel(params Params, samples []float32, processors int, encoderBeginCallback func() bool, newSegmentCallback func(int)) error { + registerEncoderBeginCallback(ctx, encoderBeginCallback) + registerNewSegmentCallback(ctx, newSegmentCallback) + defer registerEncoderBeginCallback(ctx, nil) + defer registerNewSegmentCallback(ctx, nil) + + if C.whisper_full_parallel((*C.struct_whisper_context)(ctx), (C.struct_whisper_full_params)(params), (*C.float)(&samples[0]), C.int(len(samples)), C.int(processors)) == 0 { + return nil + } else { + return ErrConversionFailed + } +} + +// Return the id of the autodetected language, returns -1 if not found +// Added to whisper.cpp in +// https://github.com/ggerganov/whisper.cpp/commit/a1c1583cc7cd8b75222857afc936f0638c5683d6 +// +// Examples: +// +// "de" -> 2 +// "german" -> 2 +func (ctx *Context) Whisper_full_lang_id() int { + return int(C.whisper_full_lang_id((*C.struct_whisper_context)(ctx))) +} + +// Number of generated text segments. +// A segment can be a few words, a sentence, or even a paragraph. +func (ctx *Context) Whisper_full_n_segments() int { + return int(C.whisper_full_n_segments((*C.struct_whisper_context)(ctx))) +} + +// Get the start and end time of the specified segment. +func (ctx *Context) Whisper_full_get_segment_t0(segment int) int64 { + return int64(C.whisper_full_get_segment_t0((*C.struct_whisper_context)(ctx), C.int(segment))) +} + +// Get the start and end time of the specified segment. +func (ctx *Context) Whisper_full_get_segment_t1(segment int) int64 { + return int64(C.whisper_full_get_segment_t1((*C.struct_whisper_context)(ctx), C.int(segment))) +} + +// Get the text of the specified segment. +func (ctx *Context) Whisper_full_get_segment_text(segment int) string { + return C.GoString(C.whisper_full_get_segment_text((*C.struct_whisper_context)(ctx), C.int(segment))) +} + +// Get number of tokens in the specified segment. +func (ctx *Context) Whisper_full_n_tokens(segment int) int { + return int(C.whisper_full_n_tokens((*C.struct_whisper_context)(ctx), C.int(segment))) +} + +// Get the token text of the specified token index in the specified segment. +func (ctx *Context) Whisper_full_get_token_text(segment int, token int) string { + return C.GoString(C.whisper_full_get_token_text((*C.struct_whisper_context)(ctx), C.int(segment), C.int(token))) +} + +// Get the token of the specified token index in the specified segment. +func (ctx *Context) Whisper_full_get_token_id(segment int, token int) Token { + return Token(C.whisper_full_get_token_id((*C.struct_whisper_context)(ctx), C.int(segment), C.int(token))) +} + +// Get token data for the specified token in the specified segment. +// This contains probabilities, timestamps, etc. +func (ctx *Context) Whisper_full_get_token_data(segment int, token int) TokenData { + return TokenData(C.whisper_full_get_token_data((*C.struct_whisper_context)(ctx), C.int(segment), C.int(token))) +} + +// Get the probability of the specified token in the specified segment. +func (ctx *Context) Whisper_full_get_token_p(segment int, token int) float32 { + return float32(C.whisper_full_get_token_p((*C.struct_whisper_context)(ctx), C.int(segment), C.int(token))) +} + +/////////////////////////////////////////////////////////////////////////////// +// CALLBACKS + +var ( + cbNewSegment = make(map[unsafe.Pointer]func(int)) + cbProgress = make(map[unsafe.Pointer]func(int)) + cbEncoderBegin = make(map[unsafe.Pointer]func() bool) +) + +func registerNewSegmentCallback(ctx *Context, fn func(int)) { + if fn == nil { + delete(cbNewSegment, unsafe.Pointer(ctx)) + } else { + cbNewSegment[unsafe.Pointer(ctx)] = fn + } +} + +func registerProgressCallback(ctx *Context, fn func(int)) { + if fn == nil { + delete(cbProgress, unsafe.Pointer(ctx)) + } else { + cbProgress[unsafe.Pointer(ctx)] = fn + } +} + +func registerEncoderBeginCallback(ctx *Context, fn func() bool) { + if fn == nil { + delete(cbEncoderBegin, unsafe.Pointer(ctx)) + } else { + cbEncoderBegin[unsafe.Pointer(ctx)] = fn + } +} + +//export callNewSegment +func callNewSegment(user_data unsafe.Pointer, new C.int) { + if fn, ok := cbNewSegment[user_data]; ok { + fn(int(new)) + } +} + +//export callProgress +func callProgress(user_data unsafe.Pointer, progress C.int) { + if fn, ok := cbProgress[user_data]; ok { + fn(int(progress)) + } +} + +//export callEncoderBegin +func callEncoderBegin(user_data unsafe.Pointer) C.bool { + if fn, ok := cbEncoderBegin[user_data]; ok { + if fn() { + return C.bool(true) + } else { + return C.bool(false) + } + } + return true +} + +func (t TokenData) T0() int64 { + return int64(t.t0) +} + +func (t TokenData) T1() int64 { + return int64(t.t1) +} + +func (t TokenData) Id() Token { + return Token(t.id) +} diff --git a/sys/whisper.cpp/bindings/go/whisper_test.go b/sys/whisper.cpp/bindings/go/whisper_test.go new file mode 100644 index 0000000..40648ff --- /dev/null +++ b/sys/whisper.cpp/bindings/go/whisper_test.go @@ -0,0 +1,113 @@ +package whisper_test + +import ( + "os" + "runtime" + "testing" + "time" + + // Packages + whisper "github.com/ggerganov/whisper.cpp/bindings/go" + wav "github.com/go-audio/wav" + assert "github.com/stretchr/testify/assert" +) + +const ( + ModelPath = "models/ggml-small.en.bin" + SamplePath = "samples/jfk.wav" +) + +func Test_Whisper_000(t *testing.T) { + assert := assert.New(t) + if _, err := os.Stat(ModelPath); os.IsNotExist(err) { + t.Skip("Skipping test, model not found:", ModelPath) + } + ctx := whisper.Whisper_init(ModelPath) + assert.NotNil(ctx) + ctx.Whisper_free() +} + +func Test_Whisper_001(t *testing.T) { + assert := assert.New(t) + if _, err := os.Stat(ModelPath); os.IsNotExist(err) { + t.Skip("Skipping test, model not found:", ModelPath) + } + if _, err := os.Stat(SamplePath); os.IsNotExist(err) { + t.Skip("Skipping test, sample not found:", SamplePath) + } + + // Open samples + fh, err := os.Open(SamplePath) + assert.NoError(err) + defer fh.Close() + + // Read samples + d := wav.NewDecoder(fh) + buf, err := d.FullPCMBuffer() + assert.NoError(err) + + // Run whisper + ctx := whisper.Whisper_init(ModelPath) + assert.NotNil(ctx) + defer ctx.Whisper_free() + params := ctx.Whisper_full_default_params(whisper.SAMPLING_GREEDY) + data := buf.AsFloat32Buffer().Data + err = ctx.Whisper_full(params, data, nil, nil, nil) + assert.NoError(err) + + // Print out tokens + num_segments := ctx.Whisper_full_n_segments() + assert.GreaterOrEqual(num_segments, 1) + for i := 0; i < num_segments; i++ { + str := ctx.Whisper_full_get_segment_text(i) + assert.NotEmpty(str) + t0 := time.Duration(ctx.Whisper_full_get_segment_t0(i)) * time.Millisecond + t1 := time.Duration(ctx.Whisper_full_get_segment_t1(i)) * time.Millisecond + t.Logf("[%6s->%-6s] %q", t0, t1, str) + } +} + +func Test_Whisper_002(t *testing.T) { + assert := assert.New(t) + for i := 0; i < whisper.Whisper_lang_max_id(); i++ { + str := whisper.Whisper_lang_str(i) + assert.NotEmpty(str) + t.Log(str) + } +} + +func Test_Whisper_003(t *testing.T) { + threads := runtime.NumCPU() + assert := assert.New(t) + if _, err := os.Stat(ModelPath); os.IsNotExist(err) { + t.Skip("Skipping test, model not found:", ModelPath) + } + if _, err := os.Stat(SamplePath); os.IsNotExist(err) { + t.Skip("Skipping test, sample not found:", SamplePath) + } + + // Open samples + fh, err := os.Open(SamplePath) + assert.NoError(err) + defer fh.Close() + + // Read samples + d := wav.NewDecoder(fh) + buf, err := d.FullPCMBuffer() + assert.NoError(err) + + // Make the model + ctx := whisper.Whisper_init(ModelPath) + assert.NotNil(ctx) + defer ctx.Whisper_free() + + // Get MEL + assert.NoError(ctx.Whisper_pcm_to_mel(buf.AsFloat32Buffer().Data, threads)) + + // Get Languages + languages, err := ctx.Whisper_lang_auto_detect(0, threads) + assert.NoError(err) + for i, p := range languages { + t.Logf("%s: %f", whisper.Whisper_lang_str(i), p) + } +} diff --git a/sys/whisper.cpp/bindings/java/README.md b/sys/whisper.cpp/bindings/java/README.md new file mode 100644 index 0000000..5255612 --- /dev/null +++ b/sys/whisper.cpp/bindings/java/README.md @@ -0,0 +1,71 @@ +# Java JNI bindings for Whisper + +This package provides Java JNI bindings for whisper.cpp. They have been tested on: + + * Darwin (OS X) 12.6 on x64_64 + * Ubuntu on x86_64 + * Windows on x86_64 + +The "low level" bindings are in `WhisperCppJnaLibrary`. The most simple usage is as follows: + +JNA will attempt to load the `whispercpp` shared library from: + +- jna.library.path +- jna.platform.library +- ~/Library/Frameworks +- /Library/Frameworks +- /System/Library/Frameworks +- classpath + +```java +import io.github.ggerganov.whispercpp.WhisperCpp; + +public class Example { + + public static void main(String[] args) { + WhisperCpp whisper = new WhisperCpp(); + // By default, models are loaded from ~/.cache/whisper/ and are usually named "ggml-${name}.bin" + // or you can provide the absolute path to the model file. + long context = whisper.initContext("base.en"); + try { + var whisperParams = whisper.getFullDefaultParams(WhisperSamplingStrategy.WHISPER_SAMPLING_GREEDY); + // custom configuration if required + whisperParams.temperature_inc = 0f; + + var samples = readAudio(); // divide each value by 32767.0f + whisper.fullTranscribe(whisperParams, samples); + + int segmentCount = whisper.getTextSegmentCount(context); + for (int i = 0; i < segmentCount; i++) { + String text = whisper.getTextSegment(context, i); + System.out.println(segment.getText()); + } + } finally { + whisper.freeContext(context); + } + } +} +``` + +## Building & Testing + +In order to build, you need to have the JDK 8 or higher installed. Run the tests with: + +```bash +git clone https://github.com/ggerganov/whisper.cpp.git +cd whisper.cpp/bindings/java + +./gradlew build +``` + +You need to have the `whisper` library in your [JNA library path](https://java-native-access.github.io/jna/4.2.1/com/sun/jna/NativeLibrary.html). On Windows the dll is included in the jar and you can update it: + +```bash +copy /y ..\..\build\bin\Release\whisper.dll build\generated\resources\main\win32-x86-64\whisper.dll +``` + + +## License + +The license for the Go bindings is the same as the license for the rest of the whisper.cpp project, which is the MIT License. See the `LICENSE` file for more details. + diff --git a/sys/whisper.cpp/bindings/java/build.gradle b/sys/whisper.cpp/bindings/java/build.gradle new file mode 100644 index 0000000..75f3a9c --- /dev/null +++ b/sys/whisper.cpp/bindings/java/build.gradle @@ -0,0 +1,133 @@ +plugins { + id 'java' + id 'java-library' + id 'maven-publish' + id 'signing' +} + +archivesBaseName = 'whispercpp' +group = 'io.github.ggerganov' +version = '1.4.0' + + +sourceCompatibility = 1.8 +targetCompatibility = 1.8 + +sourceSets { + main { + resources { + srcDirs = ['src/main/resources', 'build/generated/resources/main'] + } + } + test { + runtimeClasspath += files('build/generated/resources/main') + } +} + +tasks.register('copyLibwhisperDynlib', Copy) { + from '../../build' + include 'libwhisper.dynlib' + into 'build/generated/resources/main/darwin' +} + +tasks.register('copyLibwhisperSo', Copy) { + from '../../build' + include 'libwhisper.so' + into 'build/generated/resources/main/linux-x86-64' +} + +tasks.register('copyWhisperDll', Copy) { + from '../../build/Release' + include 'whisper.dll' + into 'build/generated/resources/main/windows-x86-64' +} + +tasks.register('copyLibs') { + dependsOn copyLibwhisperDynlib, copyLibwhisperSo, copyWhisperDll +} + +test { + systemProperty 'jna.library.path', project.file('build/generated/resources/main').absolutePath +} + +java { + withSourcesJar() + withJavadocJar() +} + +jar { + exclude '**/whisper_java.exp', '**/whisper_java.lib' +} + +javadoc { + options.addStringOption('Xdoclint:none', '-quiet') +} + +tasks.withType(Test) { + useJUnitPlatform() +} + +dependencies { + implementation "net.java.dev.jna:jna:5.13.0" + testImplementation "org.junit.jupiter:junit-jupiter:5.9.2" + testImplementation "org.assertj:assertj-core:3.24.2" +} + +repositories { + mavenCentral() +} + +publishing { + publications { + mavenJava(MavenPublication) { + artifactId = 'whispercpp' + from components.java + pom { + name = 'whispercpp' + description = "Java JNA bindings for OpenAI's Whisper model, implemented in C/C++" + url = 'https://github.com/ggerganov/whisper.cpp' + licenses { + license { + name = 'MIT licence' + url = 'https://raw.githubusercontent.com/ggerganov/whisper.cpp/master/LICENSE' + } + } + developers { + developer { + id = 'ggerganov' + name = 'Georgi Gerganov' + email = 'ggerganov@gmail.com' + } + developer { + id = 'nalbion' + name = 'Nicholas Albion' + email = 'nalbion@yahoo.com' + } + } + scm { + connection = 'scm:git:git://github.com/ggerganov/whisper.cpp.git' + url = 'https://github.com/ggerganov/whisper.cpp' + } + } + } + } + + repositories { + maven { + def releasesRepoUrl = 'https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/' + def snapshotsRepoUrl = 'https://s01.oss.sonatype.org/content/repositories/snapshots/' + url = version.endsWith('-SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl + credentials { + username = System.getenv("MAVEN_USERNAME") + password = System.getenv("MAVEN_PASSWORD") + } + } + } +} + +signing { + def signingKey = System.getenv("PGP_SECRET") + def signingPassword = System.getenv("PGP_PASSPHRASE") + useInMemoryPgpKeys(signingKey, signingPassword) + sign publishing.publications.mavenJava +} diff --git a/sys/whisper.cpp/bindings/java/gradle.properties b/sys/whisper.cpp/bindings/java/gradle.properties new file mode 100644 index 0000000..3ea68c2 --- /dev/null +++ b/sys/whisper.cpp/bindings/java/gradle.properties @@ -0,0 +1,6 @@ +org.gradle.jvmargs=-Xms256m -Xmx1024m +system.include.dir=/usr/include +#system.local.include.dir=../../include +system.local.include.dir=./build/generated/sources/headers/java/main +jni.include.dir=/usr/lib/jvm/java-8-openjdk-amd64/include/ +jni.lib.dir=/usr/lib/jvm/java-8-openjdk-amd64/lib/ diff --git a/sys/whisper.cpp/bindings/java/gradle/wrapper/gradle-wrapper.jar b/sys/whisper.cpp/bindings/java/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..ccebba7 Binary files /dev/null and b/sys/whisper.cpp/bindings/java/gradle/wrapper/gradle-wrapper.jar differ diff --git a/sys/whisper.cpp/bindings/java/gradle/wrapper/gradle-wrapper.properties b/sys/whisper.cpp/bindings/java/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..0c85a1f --- /dev/null +++ b/sys/whisper.cpp/bindings/java/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-bin.zip +networkTimeout=10000 +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/sys/whisper.cpp/bindings/java/gradlew b/sys/whisper.cpp/bindings/java/gradlew new file mode 100644 index 0000000..79a61d4 --- /dev/null +++ b/sys/whisper.cpp/bindings/java/gradlew @@ -0,0 +1,244 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/sys/whisper.cpp/bindings/java/gradlew.bat b/sys/whisper.cpp/bindings/java/gradlew.bat new file mode 100644 index 0000000..6689b85 --- /dev/null +++ b/sys/whisper.cpp/bindings/java/gradlew.bat @@ -0,0 +1,92 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/sys/whisper.cpp/bindings/java/settings.gradle b/sys/whisper.cpp/bindings/java/settings.gradle new file mode 100644 index 0000000..dbc6f38 --- /dev/null +++ b/sys/whisper.cpp/bindings/java/settings.gradle @@ -0,0 +1 @@ +rootProject.name = "whispercpp" diff --git a/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/WhisperContext.java b/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/WhisperContext.java new file mode 100644 index 0000000..0498eb4 --- /dev/null +++ b/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/WhisperContext.java @@ -0,0 +1,41 @@ +package io.github.ggerganov.whispercpp; + +import com.sun.jna.Structure; +import com.sun.jna.ptr.PointerByReference; +import io.github.ggerganov.whispercpp.ggml.GgmlType; +import io.github.ggerganov.whispercpp.WhisperModel; +import io.github.ggerganov.whispercpp.params.WhisperContextParams; + +import java.util.List; + +public class WhisperContext extends Structure { + int t_load_us = 0; + int t_start_us = 0; + + /** weight type (FP32 / FP16 / QX) */ + GgmlType wtype = GgmlType.GGML_TYPE_F16; + /** intermediate type (FP32 or FP16) */ + GgmlType itype = GgmlType.GGML_TYPE_F16; + +// WhisperModel model; + public PointerByReference model; +// whisper_vocab vocab; +// whisper_state * state = nullptr; + public PointerByReference vocab; + public PointerByReference state; + + /** populated by whisper_init_from_file_with_params() */ + String path_model; + WhisperContextParams params; + +// public static class ByReference extends WhisperContext implements Structure.ByReference { +// } +// +// public static class ByValue extends WhisperContext implements Structure.ByValue { +// } +// +// @Override +// protected List getFieldOrder() { +// return List.of("t_load_us", "t_start_us", "wtype", "itype", "model", "vocab", "state", "path_model"); +// } +} diff --git a/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/WhisperCpp.java b/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/WhisperCpp.java new file mode 100644 index 0000000..4c1594d --- /dev/null +++ b/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/WhisperCpp.java @@ -0,0 +1,207 @@ +package io.github.ggerganov.whispercpp; + +import com.sun.jna.Native; +import com.sun.jna.Pointer; +import io.github.ggerganov.whispercpp.bean.WhisperSegment; +import io.github.ggerganov.whispercpp.params.WhisperContextParams; +import io.github.ggerganov.whispercpp.params.WhisperFullParams; +import io.github.ggerganov.whispercpp.params.WhisperSamplingStrategy; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +/** + * Before calling most methods, you must call `initContext(modelPath)` to initialise the `ctx` Pointer. + */ +public class WhisperCpp implements AutoCloseable { + private WhisperCppJnaLibrary lib = WhisperCppJnaLibrary.instance; + private Pointer ctx = null; + private Pointer paramsPointer = null; + private Pointer greedyParamsPointer = null; + private Pointer beamParamsPointer = null; + + public File modelDir() { + String modelDirPath = System.getenv("XDG_CACHE_HOME"); + if (modelDirPath == null) { + modelDirPath = System.getProperty("user.home") + "/.cache"; + } + + return new File(modelDirPath, "whisper"); + } + + /** + * @param modelPath - absolute path, or just the name (eg: "base", "base-en" or "base.en") + */ + public void initContext(String modelPath) throws FileNotFoundException { + initContextImpl(modelPath, getContextDefaultParams()); + } + + /** + * @param modelPath - absolute path, or just the name (eg: "base", "base-en" or "base.en") + * @param params - params to use when initialising the context + */ + public void initContext(String modelPath, WhisperContextParams params) throws FileNotFoundException { + initContextImpl(modelPath, params); + } + + private void initContextImpl(String modelPath, WhisperContextParams params) throws FileNotFoundException { + if (ctx != null) { + lib.whisper_free(ctx); + } + + if (!modelPath.contains("/") && !modelPath.contains("\\")) { + if (!modelPath.endsWith(".bin")) { + modelPath = "ggml-" + modelPath.replace("-", ".") + ".bin"; + } + + modelPath = new File(modelDir(), modelPath).getAbsolutePath(); + } + + ctx = lib.whisper_init_from_file_with_params(modelPath, params); + + if (ctx == null) { + throw new FileNotFoundException(modelPath); + } + } + + /** + * Provides default params which can be used with `whisper_init_from_file_with_params()` etc. + * Because this function allocates memory for the params, the caller must call either: + * - call `whisper_free_context_params()` + * - `Native.free(Pointer.nativeValue(pointer));` + */ + public WhisperContextParams getContextDefaultParams() { + paramsPointer = lib.whisper_context_default_params_by_ref(); + WhisperContextParams params = new WhisperContextParams(paramsPointer); + params.read(); + return params; + } + + /** + * Provides default params which can be used with `whisper_full()` etc. + * Because this function allocates memory for the params, the caller must call either: + * - call `whisper_free_params()` + * - `Native.free(Pointer.nativeValue(pointer));` + * + * @param strategy - GREEDY + */ + public WhisperFullParams getFullDefaultParams(WhisperSamplingStrategy strategy) { + Pointer pointer; + + // whisper_full_default_params_by_ref allocates memory which we need to delete, so only create max 1 pointer for each strategy. + if (strategy == WhisperSamplingStrategy.WHISPER_SAMPLING_GREEDY) { + if (greedyParamsPointer == null) { + greedyParamsPointer = lib.whisper_full_default_params_by_ref(strategy.ordinal()); + } + pointer = greedyParamsPointer; + } else { + if (beamParamsPointer == null) { + beamParamsPointer = lib.whisper_full_default_params_by_ref(strategy.ordinal()); + } + pointer = beamParamsPointer; + } + + WhisperFullParams params = new WhisperFullParams(pointer); + params.read(); + return params; + } + + @Override + public void close() { + freeContext(); + freeParams(); + System.out.println("Whisper closed"); + } + + private void freeContext() { + if (ctx != null) { + lib.whisper_free(ctx); + } + } + + private void freeParams() { + if (paramsPointer != null) { + Native.free(Pointer.nativeValue(paramsPointer)); + paramsPointer = null; + } + if (greedyParamsPointer != null) { + Native.free(Pointer.nativeValue(greedyParamsPointer)); + greedyParamsPointer = null; + } + if (beamParamsPointer != null) { + Native.free(Pointer.nativeValue(beamParamsPointer)); + beamParamsPointer = null; + } + } + + /** + * Run the entire model: PCM -> log mel spectrogram -> encoder -> decoder -> text. + * Not thread safe for same context + * Uses the specified decoding strategy to obtain the text. + */ + public String fullTranscribe(WhisperFullParams whisperParams, float[] audioData) throws IOException { + if (ctx == null) { + throw new IllegalStateException("Model not initialised"); + } + + if (lib.whisper_full(ctx, whisperParams, audioData, audioData.length) != 0) { + throw new IOException("Failed to process audio"); + } + + int nSegments = lib.whisper_full_n_segments(ctx); + + StringBuilder str = new StringBuilder(); + + for (int i = 0; i < nSegments; i++) { + String text = lib.whisper_full_get_segment_text(ctx, i); + System.out.println("Segment:" + text); + str.append(text); + } + + return str.toString().trim(); + } + public List fullTranscribeWithTime(WhisperFullParams whisperParams, float[] audioData) throws IOException { + if (ctx == null) { + throw new IllegalStateException("Model not initialised"); + } + + if (lib.whisper_full(ctx, whisperParams, audioData, audioData.length) != 0) { + throw new IOException("Failed to process audio"); + } + + int nSegments = lib.whisper_full_n_segments(ctx); + List segments= new ArrayList<>(nSegments); + + + for (int i = 0; i < nSegments; i++) { + long t0 = lib.whisper_full_get_segment_t0(ctx, i); + String text = lib.whisper_full_get_segment_text(ctx, i); + long t1 = lib.whisper_full_get_segment_t1(ctx, i); + segments.add(new WhisperSegment(t0,t1,text)); + } + + return segments; + } + +// public int getTextSegmentCount(Pointer ctx) { +// return lib.whisper_full_n_segments(ctx); +// } +// public String getTextSegment(Pointer ctx, int index) { +// return lib.whisper_full_get_segment_text(ctx, index); +// } + + public String getSystemInfo() { + return lib.whisper_print_system_info(); + } + + public int benchMemcpy(int nthread) { + return lib.whisper_bench_memcpy(nthread); + } + + public int benchGgmlMulMat(int nthread) { + return lib.whisper_bench_ggml_mul_mat(nthread); + } +} diff --git a/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/WhisperCppJnaLibrary.java b/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/WhisperCppJnaLibrary.java new file mode 100644 index 0000000..56a3738 --- /dev/null +++ b/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/WhisperCppJnaLibrary.java @@ -0,0 +1,396 @@ +package io.github.ggerganov.whispercpp; + +import com.sun.jna.Library; +import com.sun.jna.Native; +import com.sun.jna.Pointer; +import io.github.ggerganov.whispercpp.model.WhisperModelLoader; +import io.github.ggerganov.whispercpp.model.WhisperTokenData; +import io.github.ggerganov.whispercpp.params.WhisperContextParams; +import io.github.ggerganov.whispercpp.params.WhisperFullParams; + +public interface WhisperCppJnaLibrary extends Library { + WhisperCppJnaLibrary instance = Native.load("whisper", WhisperCppJnaLibrary.class); + + String whisper_print_system_info(); + + /** + * DEPRECATED. Allocate (almost) all memory needed for the model by loading from a file. + * + * @param path_model Path to the model file + * @return Whisper context on success, null on failure + */ + Pointer whisper_init_from_file(String path_model); + + /** + * Provides default params which can be used with `whisper_init_from_file_with_params()` etc. + * Because this function allocates memory for the params, the caller must call either: + * - call `whisper_free_context_params()` + * - `Native.free(Pointer.nativeValue(pointer));` + */ + Pointer whisper_context_default_params_by_ref(); + + void whisper_free_context_params(Pointer params); + + /** + * Allocate (almost) all memory needed for the model by loading from a file. + * + * @param path_model Path to the model file + * @param params Pointer to whisper_context_params + * @return Whisper context on success, null on failure + */ + Pointer whisper_init_from_file_with_params(String path_model, WhisperContextParams params); + + /** + * Allocate (almost) all memory needed for the model by loading from a buffer. + * + * @param buffer Model buffer + * @param buffer_size Size of the model buffer + * @return Whisper context on success, null on failure + */ + Pointer whisper_init_from_buffer(Pointer buffer, int buffer_size); + + /** + * Allocate (almost) all memory needed for the model using a model loader. + * + * @param loader Model loader + * @return Whisper context on success, null on failure + */ + Pointer whisper_init(WhisperModelLoader loader); + + /** + * Allocate (almost) all memory needed for the model by loading from a file without allocating the state. + * + * @param path_model Path to the model file + * @return Whisper context on success, null on failure + */ + Pointer whisper_init_from_file_no_state(String path_model); + + /** + * Allocate (almost) all memory needed for the model by loading from a buffer without allocating the state. + * + * @param buffer Model buffer + * @param buffer_size Size of the model buffer + * @return Whisper context on success, null on failure + */ + Pointer whisper_init_from_buffer_no_state(Pointer buffer, int buffer_size); + +// Pointer whisper_init_from_buffer_no_state(Pointer buffer, long buffer_size); + + /** + * Allocate (almost) all memory needed for the model using a model loader without allocating the state. + * + * @param loader Model loader + * @return Whisper context on success, null on failure + */ + Pointer whisper_init_no_state(WhisperModelLoader loader); + + /** + * Allocate memory for the Whisper state. + * + * @param ctx Whisper context + * @return Whisper state on success, null on failure + */ + Pointer whisper_init_state(Pointer ctx); + + /** + * Free all allocated memory associated with the Whisper context. + * + * @param ctx Whisper context + */ + void whisper_free(Pointer ctx); + + /** + * Free all allocated memory associated with the Whisper state. + * + * @param state Whisper state + */ + void whisper_free_state(Pointer state); + + + /** + * Convert RAW PCM audio to log mel spectrogram. + * The resulting spectrogram is stored inside the default state of the provided whisper context. + * + * @param ctx - Pointer to a WhisperContext + * @return 0 on success + */ + int whisper_pcm_to_mel(Pointer ctx, final float[] samples, int n_samples, int n_threads); + + /** + * @param ctx Pointer to a WhisperContext + * @param state Pointer to WhisperState + * @param n_samples + * @param n_threads + * @return 0 on success + */ + int whisper_pcm_to_mel_with_state(Pointer ctx, Pointer state, final float[] samples, int n_samples, int n_threads); + + /** + * This can be used to set a custom log mel spectrogram inside the default state of the provided whisper context. + * Use this instead of whisper_pcm_to_mel() if you want to provide your own log mel spectrogram. + * n_mel must be 80 + * @return 0 on success + */ + int whisper_set_mel(Pointer ctx, final float[] data, int n_len, int n_mel); + int whisper_set_mel_with_state(Pointer ctx, Pointer state, final float[] data, int n_len, int n_mel); + + /** + * Run the Whisper encoder on the log mel spectrogram stored inside the default state in the provided whisper context. + * Make sure to call whisper_pcm_to_mel() or whisper_set_mel() first. + * Offset can be used to specify the offset of the first frame in the spectrogram. + * @return 0 on success + */ + int whisper_encode(Pointer ctx, int offset, int n_threads); + + int whisper_encode_with_state(Pointer ctx, Pointer state, int offset, int n_threads); + + /** + * Run the Whisper decoder to obtain the logits and probabilities for the next token. + * Make sure to call whisper_encode() first. + * tokens + n_tokens is the provided context for the decoder. + * n_past is the number of tokens to use from previous decoder calls. + * Returns 0 on success + * TODO: add support for multiple decoders + */ + int whisper_decode(Pointer ctx, Pointer tokens, int n_tokens, int n_past, int n_threads); + + /** + * @param ctx + * @param state + * @param tokens Pointer to int tokens + * @param n_tokens + * @param n_past + * @param n_threads + * @return + */ + int whisper_decode_with_state(Pointer ctx, Pointer state, Pointer tokens, int n_tokens, int n_past, int n_threads); + + /** + * Convert the provided text into tokens. + * The tokens pointer must be large enough to hold the resulting tokens. + * Returns the number of tokens on success, no more than n_max_tokens + * Returns -1 on failure + * TODO: not sure if correct + */ + int whisper_tokenize(Pointer ctx, String text, Pointer tokens, int n_max_tokens); + + /** Largest language id (i.e. number of available languages - 1) */ + int whisper_lang_max_id(); + + /** + * @return the id of the specified language, returns -1 if not found. + * Examples: + * "de" -> 2 + * "german" -> 2 + */ + int whisper_lang_id(String lang); + + /** @return the short string of the specified language id (e.g. 2 -> "de"), returns nullptr if not found */ + String whisper_lang_str(int id); + + /** + * Use mel data at offset_ms to try and auto-detect the spoken language. + * Make sure to call whisper_pcm_to_mel() or whisper_set_mel() first + * Returns the top language id or negative on failure + * If not null, fills the lang_probs array with the probabilities of all languages + * The array must be whisper_lang_max_id() + 1 in size + * + * ref: https://github.com/openai/whisper/blob/main/whisper/decoding.py#L18-L69 + */ + int whisper_lang_auto_detect(Pointer ctx, int offset_ms, int n_threads, float[] lang_probs); + + int whisper_lang_auto_detect_with_state(Pointer ctx, Pointer state, int offset_ms, int n_threads, float[] lang_probs); + + int whisper_n_len (Pointer ctx); // mel length + int whisper_n_len_from_state(Pointer state); // mel length + int whisper_n_vocab (Pointer ctx); + int whisper_n_text_ctx (Pointer ctx); + int whisper_n_audio_ctx (Pointer ctx); + int whisper_is_multilingual (Pointer ctx); + + int whisper_model_n_vocab (Pointer ctx); + int whisper_model_n_audio_ctx (Pointer ctx); + int whisper_model_n_audio_state(Pointer ctx); + int whisper_model_n_audio_head (Pointer ctx); + int whisper_model_n_audio_layer(Pointer ctx); + int whisper_model_n_text_ctx (Pointer ctx); + int whisper_model_n_text_state (Pointer ctx); + int whisper_model_n_text_head (Pointer ctx); + int whisper_model_n_text_layer (Pointer ctx); + int whisper_model_n_mels (Pointer ctx); + int whisper_model_ftype (Pointer ctx); + int whisper_model_type (Pointer ctx); + + /** + * Token logits obtained from the last call to whisper_decode(). + * The logits for the last token are stored in the last row + * Rows: n_tokens + * Cols: n_vocab + */ + float[] whisper_get_logits (Pointer ctx); + float[] whisper_get_logits_from_state(Pointer state); + + // Token Id -> String. Uses the vocabulary in the provided context + String whisper_token_to_str(Pointer ctx, int token); + String whisper_model_type_readable(Pointer ctx); + + // Special tokens + int whisper_token_eot (Pointer ctx); + int whisper_token_sot (Pointer ctx); + int whisper_token_prev(Pointer ctx); + int whisper_token_solm(Pointer ctx); + int whisper_token_not (Pointer ctx); + int whisper_token_beg (Pointer ctx); + int whisper_token_lang(Pointer ctx, int lang_id); + + // Task tokens + int whisper_token_translate (Pointer ctx); + int whisper_token_transcribe(Pointer ctx); + + // Performance information from the default state. + void whisper_print_timings(Pointer ctx); + void whisper_reset_timings(Pointer ctx); + + // Note: Even if `whisper_full_params is stripped back to just 4 ints, JNA throws "Invalid memory access" + // when `whisper_full_default_params()` tries to return a struct. + // WhisperFullParams whisper_full_default_params(int strategy); + + /** + * Provides default params which can be used with `whisper_full()` etc. + * Because this function allocates memory for the params, the caller must call either: + * - call `whisper_free_params()` + * - `Native.free(Pointer.nativeValue(pointer));` + * + * @param strategy - WhisperSamplingStrategy.value + */ + Pointer whisper_full_default_params_by_ref(int strategy); + + void whisper_free_params(Pointer params); + + /** + * Run the entire model: PCM -> log mel spectrogram -> encoder -> decoder -> text + * Not thread safe for same context + * Uses the specified decoding strategy to obtain the text. + */ + int whisper_full(Pointer ctx, WhisperFullParams params, final float[] samples, int n_samples); + + int whisper_full_with_state(Pointer ctx, Pointer state, WhisperFullParams params, final float[] samples, int n_samples); + + // Split the input audio in chunks and process each chunk separately using whisper_full_with_state() + // Result is stored in the default state of the context + // Not thread safe if executed in parallel on the same context. + // It seems this approach can offer some speedup in some cases. + // However, the transcription accuracy can be worse at the beginning and end of each chunk. + int whisper_full_parallel(Pointer ctx, WhisperFullParams params, final float[] samples, int n_samples, int n_processors); + + /** + * Number of generated text segments. + * A segment can be a few words, a sentence, or even a paragraph. + * @param ctx Pointer to WhisperContext + */ + int whisper_full_n_segments (Pointer ctx); + + /** + * @param state Pointer to WhisperState + */ + int whisper_full_n_segments_from_state(Pointer state); + + /** + * Language id associated with the context's default state. + * @param ctx Pointer to WhisperContext + */ + int whisper_full_lang_id(Pointer ctx); + + /** Language id associated with the provided state */ + int whisper_full_lang_id_from_state(Pointer state); + + /** + * Convert RAW PCM audio to log mel spectrogram but applies a Phase Vocoder to speed up the audio x2. + * The resulting spectrogram is stored inside the default state of the provided whisper context. + * @return 0 on success + */ + int whisper_pcm_to_mel_phase_vocoder(Pointer ctx, final float[] samples, int n_samples, int n_threads); + + int whisper_pcm_to_mel_phase_vocoder_with_state(Pointer ctx, Pointer state, final float[] samples, int n_samples, int n_threads); + + /** Get the start time of the specified segment. */ + long whisper_full_get_segment_t0(Pointer ctx, int i_segment); + + /** Get the start time of the specified segment from the state. */ + long whisper_full_get_segment_t0_from_state(Pointer state, int i_segment); + + /** Get the end time of the specified segment. */ + long whisper_full_get_segment_t1(Pointer ctx, int i_segment); + + /** Get the end time of the specified segment from the state. */ + long whisper_full_get_segment_t1_from_state(Pointer state, int i_segment); + + /** Get the text of the specified segment. */ + String whisper_full_get_segment_text(Pointer ctx, int i_segment); + + /** Get the text of the specified segment from the state. */ + String whisper_full_get_segment_text_from_state(Pointer state, int i_segment); + + /** Get the number of tokens in the specified segment. */ + int whisper_full_n_tokens(Pointer ctx, int i_segment); + + /** Get the number of tokens in the specified segment from the state. */ + int whisper_full_n_tokens_from_state(Pointer state, int i_segment); + + /** Get the token text of the specified token in the specified segment. */ + String whisper_full_get_token_text(Pointer ctx, int i_segment, int i_token); + + + /** Get the token text of the specified token in the specified segment from the state. */ + String whisper_full_get_token_text_from_state(Pointer ctx, Pointer state, int i_segment, int i_token); + + /** Get the token ID of the specified token in the specified segment. */ + int whisper_full_get_token_id(Pointer ctx, int i_segment, int i_token); + + /** Get the token ID of the specified token in the specified segment from the state. */ + int whisper_full_get_token_id_from_state(Pointer state, int i_segment, int i_token); + + /** Get token data for the specified token in the specified segment. */ + WhisperTokenData whisper_full_get_token_data(Pointer ctx, int i_segment, int i_token); + + /** Get token data for the specified token in the specified segment from the state. */ + WhisperTokenData whisper_full_get_token_data_from_state(Pointer state, int i_segment, int i_token); + + /** Get the probability of the specified token in the specified segment. */ + float whisper_full_get_token_p(Pointer ctx, int i_segment, int i_token); + + /** Get the probability of the specified token in the specified segment from the state. */ + float whisper_full_get_token_p_from_state(Pointer state, int i_segment, int i_token); + + /** + * Benchmark function for memcpy. + * + * @param nThreads Number of threads to use for the benchmark. + * @return The result of the benchmark. + */ + int whisper_bench_memcpy(int nThreads); + + /** + * Benchmark function for memcpy as a string. + * + * @param nThreads Number of threads to use for the benchmark. + * @return The result of the benchmark as a string. + */ + String whisper_bench_memcpy_str(int nThreads); + + /** + * Benchmark function for ggml_mul_mat. + * + * @param nThreads Number of threads to use for the benchmark. + * @return The result of the benchmark. + */ + int whisper_bench_ggml_mul_mat(int nThreads); + + /** + * Benchmark function for ggml_mul_mat as a string. + * + * @param nThreads Number of threads to use for the benchmark. + * @return The result of the benchmark as a string. + */ + String whisper_bench_ggml_mul_mat_str(int nThreads); +} diff --git a/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/bean/WhisperSegment.java b/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/bean/WhisperSegment.java new file mode 100644 index 0000000..da970b5 --- /dev/null +++ b/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/bean/WhisperSegment.java @@ -0,0 +1,47 @@ +package io.github.ggerganov.whispercpp.bean; + +/** + * Created by litonglinux@qq.com on 10/21/2023_7:48 AM + */ +public class WhisperSegment { + private long start, end; + private String sentence; + + public WhisperSegment() { + } + + public WhisperSegment(long start, long end, String sentence) { + this.start = start; + this.end = end; + this.sentence = sentence; + } + + public long getStart() { + return start; + } + + public long getEnd() { + return end; + } + + public String getSentence() { + return sentence; + } + + public void setStart(long start) { + this.start = start; + } + + public void setEnd(long end) { + this.end = end; + } + + public void setSentence(String sentence) { + this.sentence = sentence; + } + + @Override + public String toString() { + return "[" + start + " --> " + end + "]:" + sentence; + } +} diff --git a/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/callbacks/WhisperEncoderBeginCallback.java b/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/callbacks/WhisperEncoderBeginCallback.java new file mode 100644 index 0000000..3d228cb --- /dev/null +++ b/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/callbacks/WhisperEncoderBeginCallback.java @@ -0,0 +1,24 @@ +package io.github.ggerganov.whispercpp.callbacks; + +import com.sun.jna.Callback; +import com.sun.jna.Pointer; +import io.github.ggerganov.whispercpp.WhisperContext; +import io.github.ggerganov.whispercpp.model.WhisperState; + +/** + * Callback before the encoder starts. + * If not null, called before the encoder starts. + * If it returns false, the computation is aborted. + */ +public interface WhisperEncoderBeginCallback extends Callback { + + /** + * Callback method before the encoder starts. + * + * @param ctx The whisper context. + * @param state The whisper state. + * @param user_data User data. + * @return True if the computation should proceed, false otherwise. + */ + boolean callback(Pointer ctx, Pointer state, Pointer user_data); +} diff --git a/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/callbacks/WhisperLogitsFilterCallback.java b/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/callbacks/WhisperLogitsFilterCallback.java new file mode 100644 index 0000000..9777c76 --- /dev/null +++ b/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/callbacks/WhisperLogitsFilterCallback.java @@ -0,0 +1,25 @@ +package io.github.ggerganov.whispercpp.callbacks; + +import com.sun.jna.Callback; +import com.sun.jna.Pointer; +import io.github.ggerganov.whispercpp.model.WhisperTokenData; + +/** + * Callback to filter logits. + * Can be used to modify the logits before sampling. + * If not null, called after applying temperature to logits. + */ +public interface WhisperLogitsFilterCallback extends Callback { + + /** + * Callback method to filter logits. + * + * @param ctx The whisper context. + * @param state The whisper state. + * @param tokens The array of whisper_token_data. + * @param n_tokens The number of tokens. + * @param logits The array of logits. + * @param user_data User data. + */ + void callback(Pointer ctx, Pointer state, WhisperTokenData[] tokens, int n_tokens, float[] logits, Pointer user_data); +} diff --git a/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/callbacks/WhisperNewSegmentCallback.java b/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/callbacks/WhisperNewSegmentCallback.java new file mode 100644 index 0000000..27b1c61 --- /dev/null +++ b/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/callbacks/WhisperNewSegmentCallback.java @@ -0,0 +1,24 @@ +package io.github.ggerganov.whispercpp.callbacks; + +import com.sun.jna.Callback; +import com.sun.jna.Pointer; +import io.github.ggerganov.whispercpp.WhisperContext; +import io.github.ggerganov.whispercpp.model.WhisperState; + +/** + * Callback for the text segment. + * Called on every newly generated text segment. + * Use the whisper_full_...() functions to obtain the text segments. + */ +public interface WhisperNewSegmentCallback extends Callback { + + /** + * Callback method for the text segment. + * + * @param ctx The whisper context. + * @param state The whisper state. + * @param n_new The number of newly generated text segments. + * @param user_data User data. + */ + void callback(Pointer ctx, Pointer state, int n_new, Pointer user_data); +} diff --git a/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/callbacks/WhisperProgressCallback.java b/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/callbacks/WhisperProgressCallback.java new file mode 100644 index 0000000..c64f0ab --- /dev/null +++ b/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/callbacks/WhisperProgressCallback.java @@ -0,0 +1,22 @@ +package io.github.ggerganov.whispercpp.callbacks; + +import com.sun.jna.Callback; +import com.sun.jna.Pointer; +import io.github.ggerganov.whispercpp.WhisperContext; +import io.github.ggerganov.whispercpp.model.WhisperState; + +/** + * Callback for progress updates. + */ +public interface WhisperProgressCallback extends Callback { + + /** + * Callback method for progress updates. + * + * @param ctx The whisper context. + * @param state The whisper state. + * @param progress The progress value. + * @param user_data User data. + */ + void callback(Pointer ctx, Pointer state, int progress, Pointer user_data); +} diff --git a/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/ggml/GgmlTensor.java b/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/ggml/GgmlTensor.java new file mode 100644 index 0000000..2569957 --- /dev/null +++ b/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/ggml/GgmlTensor.java @@ -0,0 +1,4 @@ +package io.github.ggerganov.whispercpp.ggml; + +public class GgmlTensor { +} diff --git a/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/ggml/GgmlType.java b/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/ggml/GgmlType.java new file mode 100644 index 0000000..363120e --- /dev/null +++ b/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/ggml/GgmlType.java @@ -0,0 +1,18 @@ +package io.github.ggerganov.whispercpp.ggml; + +public enum GgmlType { + GGML_TYPE_F32, + GGML_TYPE_F16, + GGML_TYPE_Q4_0, + GGML_TYPE_Q4_1, + REMOVED_GGML_TYPE_Q4_2, // support has been removed + REMOVED_GGML_TYPE_Q4_3, // support has been removed + GGML_TYPE_Q5_0, + GGML_TYPE_Q5_1, + GGML_TYPE_Q8_0, + GGML_TYPE_Q8_1, + GGML_TYPE_I8, + GGML_TYPE_I16, + GGML_TYPE_I32, + GGML_TYPE_COUNT, +} diff --git a/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/model/EModel.java b/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/model/EModel.java new file mode 100644 index 0000000..b2475b3 --- /dev/null +++ b/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/model/EModel.java @@ -0,0 +1,10 @@ +package io.github.ggerganov.whispercpp.model; + +public enum EModel { + MODEL_UNKNOWN, + MODEL_TINY, + MODEL_BASE, + MODEL_SMALL, + MODEL_MEDIUM, + MODEL_LARGE, +} diff --git a/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/model/WhisperModel.java b/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/model/WhisperModel.java new file mode 100644 index 0000000..497ef42 --- /dev/null +++ b/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/model/WhisperModel.java @@ -0,0 +1,49 @@ +package io.github.ggerganov.whispercpp; + +import io.github.ggerganov.whispercpp.ggml.GgmlTensor; +import io.github.ggerganov.whispercpp.model.EModel; + +public class WhisperModel { +// EModel type = EModel.MODEL_UNKNOWN; +// +// WhisperHParams hparams; +// WhisperFilters filters; +// +// // encoder.positional_embedding +// GgmlTensor e_pe; +// +// // encoder.conv1 +// GgmlTensor e_conv_1_w; +// GgmlTensor e_conv_1_b; +// +// // encoder.conv2 +// GgmlTensor e_conv_2_w; +// GgmlTensor e_conv_2_b; +// +// // encoder.ln_post +// GgmlTensor e_ln_w; +// GgmlTensor e_ln_b; +// +// // decoder.positional_embedding +// GgmlTensor d_pe; +// +// // decoder.token_embedding +// GgmlTensor d_te; +// +// // decoder.ln +// GgmlTensor d_ln_w; +// GgmlTensor d_ln_b; +// +// std::vector layers_encoder; +// std::vector layers_decoder; +// +// // context +// struct ggml_context * ctx; +// +// // the model memory buffer is read-only and can be shared between processors +// std::vector * buf; +// +// // tensors +// int n_loaded; +// Map tensors; +} diff --git a/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/model/WhisperModelLoader.java b/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/model/WhisperModelLoader.java new file mode 100644 index 0000000..82615d9 --- /dev/null +++ b/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/model/WhisperModelLoader.java @@ -0,0 +1,62 @@ +package io.github.ggerganov.whispercpp.model; + +import com.sun.jna.Callback; +import com.sun.jna.Pointer; +import com.sun.jna.Structure; + + +public class WhisperModelLoader extends Structure { + public Pointer context; + public ReadFunction read; + public EOFFunction eof; + public CloseFunction close; + + public static class ReadFunction implements Callback { + public Pointer invoke(Pointer ctx, Pointer output, int readSize) { + // TODO + return ctx; + } + } + + public static class EOFFunction implements Callback { + public boolean invoke(Pointer ctx) { + // TODO + return false; + } + } + + public static class CloseFunction implements Callback { + public void invoke(Pointer ctx) { + // TODO + } + } + +// public WhisperModelLoader(Pointer p) { +// super(p); +// read = new ReadFunction(); +// eof = new EOFFunction(); +// close = new CloseFunction(); +// read.setCallback(this); +// eof.setCallback(this); +// close.setCallback(this); +// read.write(); +// eof.write(); +// close.write(); +// } + + public WhisperModelLoader() { + super(); + } + + public interface ReadCallback extends Callback { + Pointer invoke(Pointer ctx, Pointer output, int readSize); + } + + public interface EOFCallback extends Callback { + boolean invoke(Pointer ctx); + } + + public interface CloseCallback extends Callback { + void invoke(Pointer ctx); + } +} diff --git a/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/model/WhisperState.java b/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/model/WhisperState.java new file mode 100644 index 0000000..af93772 --- /dev/null +++ b/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/model/WhisperState.java @@ -0,0 +1,4 @@ +package io.github.ggerganov.whispercpp.model; + +public class WhisperState { +} diff --git a/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/model/WhisperTokenData.java b/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/model/WhisperTokenData.java new file mode 100644 index 0000000..bfa83f9 --- /dev/null +++ b/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/model/WhisperTokenData.java @@ -0,0 +1,50 @@ +package io.github.ggerganov.whispercpp.model; + +import com.sun.jna.Structure; + +import java.util.Arrays; +import java.util.List; + +/** + * Structure representing token data. + */ +public class WhisperTokenData extends Structure { + + /** Token ID. */ + public int id; + + /** Forced timestamp token ID. */ + public int tid; + + /** Probability of the token. */ + public float p; + + /** Log probability of the token. */ + public float plog; + + /** Probability of the timestamp token. */ + public float pt; + + /** Sum of probabilities of all timestamp tokens. */ + public float ptsum; + + /** + * Start time of the token (token-level timestamp data). + * Do not use if you haven't computed token-level timestamps. + */ + public long t0; + + /** + * End time of the token (token-level timestamp data). + * Do not use if you haven't computed token-level timestamps. + */ + public long t1; + + /** Voice length of the token. */ + public float vlen; + + @Override + protected List getFieldOrder() { + return Arrays.asList("id", "tid", "p", "plog", "pt", "ptsum", "t0", "t1", "vlen"); + } +} diff --git a/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/params/BeamSearchParams.java b/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/params/BeamSearchParams.java new file mode 100644 index 0000000..fd621dd --- /dev/null +++ b/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/params/BeamSearchParams.java @@ -0,0 +1,19 @@ +package io.github.ggerganov.whispercpp.params; + +import com.sun.jna.Structure; + +import java.util.Arrays; +import java.util.List; + +public class BeamSearchParams extends Structure { + /** ref: ... */ + public int beam_size; + + /** ref: ... */ + public float patience; + + @Override + protected List getFieldOrder() { + return Arrays.asList("beam_size", "patience"); + } +} diff --git a/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/params/CBool.java b/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/params/CBool.java new file mode 100644 index 0000000..1f6814b --- /dev/null +++ b/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/params/CBool.java @@ -0,0 +1,30 @@ +package io.github.ggerganov.whispercpp.params; + +import com.sun.jna.IntegerType; + +import java.util.function.BooleanSupplier; + +public class CBool extends IntegerType implements BooleanSupplier { + public static final int SIZE = 1; + public static final CBool FALSE = new CBool(0); + public static final CBool TRUE = new CBool(1); + + + public CBool() { + this(0); + } + + public CBool(long value) { + super(SIZE, value, true); + } + + @Override + public boolean getAsBoolean() { + return intValue() == 1; + } + + @Override + public String toString() { + return intValue() == 1 ? "true" : "false"; + } +} diff --git a/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/params/GreedyParams.java b/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/params/GreedyParams.java new file mode 100644 index 0000000..e3b0138 --- /dev/null +++ b/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/params/GreedyParams.java @@ -0,0 +1,16 @@ +package io.github.ggerganov.whispercpp.params; + +import com.sun.jna.Structure; + +import java.util.Collections; +import java.util.List; + +public class GreedyParams extends Structure { + /** ... */ + public int best_of; + + @Override + protected List getFieldOrder() { + return Collections.singletonList("best_of"); + } +} diff --git a/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/params/WhisperContextParams.java b/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/params/WhisperContextParams.java new file mode 100644 index 0000000..cf98d2c --- /dev/null +++ b/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/params/WhisperContextParams.java @@ -0,0 +1,31 @@ +package io.github.ggerganov.whispercpp.params; + +import com.sun.jna.*; + +import java.util.Arrays; +import java.util.List; + +/** + * Parameters for the whisper_init_from_file_with_params() function. + * If you change the order or add new parameters, make sure to update the default values in whisper.cpp: + * whisper_context_default_params() + */ +public class WhisperContextParams extends Structure { + + public WhisperContextParams(Pointer p) { + super(p); + } + + /** Use GPU for inference Number (default = true) */ + public CBool use_gpu; + + /** Use GPU for inference Number (default = true) */ + public void useGpu(boolean enable) { + use_gpu = enable ? CBool.TRUE : CBool.FALSE; + } + + @Override + protected List getFieldOrder() { + return Arrays.asList("use_gpu"); + } +} diff --git a/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/params/WhisperFilters.java b/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/params/WhisperFilters.java new file mode 100644 index 0000000..b035243 --- /dev/null +++ b/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/params/WhisperFilters.java @@ -0,0 +1,10 @@ +package io.github.ggerganov.whispercpp.params; + +import java.util.List; + +public class WhisperFilters { + int n_mel; + int n_fft; + + List data; +} diff --git a/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/params/WhisperFullParams.java b/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/params/WhisperFullParams.java new file mode 100644 index 0000000..43c9a0d --- /dev/null +++ b/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/params/WhisperFullParams.java @@ -0,0 +1,331 @@ +package io.github.ggerganov.whispercpp.params; + +import com.sun.jna.*; +import io.github.ggerganov.whispercpp.callbacks.WhisperEncoderBeginCallback; +import io.github.ggerganov.whispercpp.callbacks.WhisperLogitsFilterCallback; +import io.github.ggerganov.whispercpp.callbacks.WhisperNewSegmentCallback; +import io.github.ggerganov.whispercpp.callbacks.WhisperProgressCallback; + +import java.util.Arrays; +import java.util.List; + +/** + * Parameters for the whisper_full() function. + * If you change the order or add new parameters, make sure to update the default values in whisper.cpp: + * whisper_full_default_params() + */ +public class WhisperFullParams extends Structure { + + public WhisperFullParams(Pointer p) { + super(p); +// super(p, ALIGN_MSVC); +// super(p, ALIGN_GNUC); + } + + /** Sampling strategy for whisper_full() function. */ + public int strategy; + + /** Number of threads. (default = 4) */ + public int n_threads; + + /** Maximum tokens to use from past text as a prompt for the decoder. (default = 16384) */ + public int n_max_text_ctx; + + /** Start offset in milliseconds. (default = 0) */ + public int offset_ms; + + /** Audio duration to process in milliseconds. (default = 0) */ + public int duration_ms; + + /** Translate flag. (default = false) */ + public CBool translate; + + /** The compliment of translateMode() */ + public void transcribeMode() { + translate = CBool.FALSE; + } + + /** The compliment of transcribeMode() */ + public void translateMode() { + translate = CBool.TRUE; + } + + /** Flag to indicate whether to use past transcription (if any) as an initial prompt for the decoder. (default = true) */ + public CBool no_context; + + /** Flag to indicate whether to use past transcription (if any) as an initial prompt for the decoder. (default = true) */ + public void enableContext(boolean enable) { + no_context = enable ? CBool.FALSE : CBool.TRUE; + } + + /** Generate timestamps or not? */ + public CBool no_timestamps; + + /** Flag to force single segment output (useful for streaming). (default = false) */ + public CBool single_segment; + + /** Flag to force single segment output (useful for streaming). (default = false) */ + public void singleSegment(boolean single) { + single_segment = single ? CBool.TRUE : CBool.FALSE; + } + + /** Flag to print special tokens (e.g., <SOT>, <EOT>, <BEG>, etc.). (default = false) */ + public CBool print_special; + + /** Flag to print special tokens (e.g., <SOT>, <EOT>, <BEG>, etc.). (default = false) */ + public void printSpecial(boolean enable) { + print_special = enable ? CBool.TRUE : CBool.FALSE; + } + + /** Flag to print progress information. (default = true) */ + public CBool print_progress; + + /** Flag to print progress information. (default = true) */ + public void printProgress(boolean enable) { + print_progress = enable ? CBool.TRUE : CBool.FALSE; + } + + /** Flag to print results from within whisper.cpp (avoid it, use callback instead). (default = true) */ + public CBool print_realtime; + + /** Flag to print results from within whisper.cpp (avoid it, use callback instead). (default = true) */ + public void printRealtime(boolean enable) { + print_realtime = enable ? CBool.TRUE : CBool.FALSE; + } + + /** Flag to print timestamps for each text segment when printing realtime. (default = true) */ + public CBool print_timestamps; + + /** Flag to print timestamps for each text segment when printing realtime. (default = true) */ + public void printTimestamps(boolean enable) { + print_timestamps = enable ? CBool.TRUE : CBool.FALSE; + } + + /** [EXPERIMENTAL] Flag to enable token-level timestamps. (default = false) */ + public CBool token_timestamps; + + /** [EXPERIMENTAL] Flag to enable token-level timestamps. (default = false) */ + public void tokenTimestamps(boolean enable) { + token_timestamps = enable ? CBool.TRUE : CBool.FALSE; + } + + /** [EXPERIMENTAL] Timestamp token probability threshold (~0.01). (default = 0.01) */ + public float thold_pt; + + /** [EXPERIMENTAL] Timestamp token sum probability threshold (~0.01). */ + public float thold_ptsum; + + /** Maximum segment length in characters. (default = 0) */ + public int max_len; + + /** Flag to split on word rather than on token (when used with max_len). (default = false) */ + public CBool split_on_word; + + /** Flag to split on word rather than on token (when used with max_len). (default = false) */ + public void splitOnWord(boolean enable) { + split_on_word = enable ? CBool.TRUE : CBool.FALSE; + } + + /** Maximum tokens per segment (0, default = no limit) */ + public int max_tokens; + + /** Flag to speed up the audio by 2x using Phase Vocoder. (default = false) */ + public CBool speed_up; + + /** Flag to speed up the audio by 2x using Phase Vocoder. (default = false) */ + public void speedUp(boolean enable) { + speed_up = enable ? CBool.TRUE : CBool.FALSE; + } + + /** Overwrite the audio context size (0 = use default). */ + public int audio_ctx; + + /** Enable tinydiarize (default = false) */ + public CBool tdrz_enable; + + /** Enable tinydiarize (default = false) */ + public void tdrzEnable(boolean enable) { + tdrz_enable = enable ? CBool.TRUE : CBool.FALSE; + } + + /** Tokens to provide to the whisper decoder as an initial prompt. + * These are prepended to any existing text context from a previous call. */ + public String initial_prompt; + + /** Prompt tokens. (int*) */ + public Pointer prompt_tokens; + + public void setPromptTokens(int[] tokens) { + Memory mem = new Memory(tokens.length * 4L); + mem.write(0, tokens, 0, tokens.length); + prompt_tokens = mem; + } + + /** Number of prompt tokens. */ + public int prompt_n_tokens; + + /** Language for auto-detection. + * For auto-detection, set to `null`, `""`, or "auto". */ + public String language; + + /** Flag to indicate whether to detect language automatically. */ + public CBool detect_language; + + /** Flag to indicate whether to detect language automatically. */ + public void detectLanguage(boolean enable) { + detect_language = enable ? CBool.TRUE : CBool.FALSE; + } + + // Common decoding parameters. + + /** Flag to suppress blank tokens. */ + public CBool suppress_blank; + + public void suppressBlanks(boolean enable) { + suppress_blank = enable ? CBool.TRUE : CBool.FALSE; + } + + /** Flag to suppress non-speech tokens. */ + public CBool suppress_non_speech_tokens; + + /** Flag to suppress non-speech tokens. */ + public void suppressNonSpeechTokens(boolean enable) { + suppress_non_speech_tokens = enable ? CBool.TRUE : CBool.FALSE; + } + + /** Initial decoding temperature. */ + public float temperature; + + /** Maximum initial timestamp. */ + public float max_initial_ts; + + /** Length penalty. */ + public float length_penalty; + + // Fallback parameters. + + /** Temperature increment. */ + public float temperature_inc; + + /** Entropy threshold (similar to OpenAI's "compression_ratio_threshold"). */ + public float entropy_thold; + + /** Log probability threshold. */ + public float logprob_thold; + + /** No speech threshold. */ + public float no_speech_thold; + + /** Greedy decoding parameters. */ + public GreedyParams greedy; + + /** + * Beam search decoding parameters. + */ + public BeamSearchParams beam_search; + + public void setBestOf(int bestOf) { + if (greedy == null) { + greedy = new GreedyParams(); + } + greedy.best_of = bestOf; + } + + public void setBeamSize(int beamSize) { + if (beam_search == null) { + beam_search = new BeamSearchParams(); + } + beam_search.beam_size = beamSize; + } + + public void setBeamSizeAndPatience(int beamSize, float patience) { + if (beam_search == null) { + beam_search = new BeamSearchParams(); + } + beam_search.beam_size = beamSize; + beam_search.patience = patience; + } + + /** + * Callback for every newly generated text segment. + * WhisperNewSegmentCallback + */ + public Pointer new_segment_callback; + + /** + * User data for the new_segment_callback. + */ + public Pointer new_segment_callback_user_data; + + /** + * Callback on each progress update. + * WhisperProgressCallback + */ + public Pointer progress_callback; + + /** + * User data for the progress_callback. + */ + public Pointer progress_callback_user_data; + + /** + * Callback each time before the encoder starts. + * WhisperEncoderBeginCallback + */ + public Pointer encoder_begin_callback; + + /** + * User data for the encoder_begin_callback. + */ + public Pointer encoder_begin_callback_user_data; + + /** + * Callback by each decoder to filter obtained logits. + * WhisperLogitsFilterCallback + */ + public Pointer logits_filter_callback; + + /** + * User data for the logits_filter_callback. + */ + public Pointer logits_filter_callback_user_data; + + + public void setNewSegmentCallback(WhisperNewSegmentCallback callback) { + new_segment_callback = CallbackReference.getFunctionPointer(callback); + } + + public void setProgressCallback(WhisperProgressCallback callback) { + progress_callback = CallbackReference.getFunctionPointer(callback); + } + + public void setEncoderBeginCallbackeginCallbackCallback(WhisperEncoderBeginCallback callback) { + encoder_begin_callback = CallbackReference.getFunctionPointer(callback); + } + + public void setLogitsFilterCallback(WhisperLogitsFilterCallback callback) { + logits_filter_callback = CallbackReference.getFunctionPointer(callback); + } + + /** Grammar stuff */ + public Pointer grammar_rules; + public long n_grammar_rules; + public long i_start_rule; + public float grammar_penalty; + + @Override + protected List getFieldOrder() { + return Arrays.asList("strategy", "n_threads", "n_max_text_ctx", "offset_ms", "duration_ms", "translate", + "no_context", "single_segment", "no_timestamps", + "print_special", "print_progress", "print_realtime", "print_timestamps", "token_timestamps", + "thold_pt", "thold_ptsum", "max_len", "split_on_word", "max_tokens", "speed_up", "audio_ctx", + "tdrz_enable", "initial_prompt", "prompt_tokens", "prompt_n_tokens", "language", "detect_language", + "suppress_blank", "suppress_non_speech_tokens", "temperature", "max_initial_ts", "length_penalty", + "temperature_inc", "entropy_thold", "logprob_thold", "no_speech_thold", "greedy", "beam_search", + "new_segment_callback", "new_segment_callback_user_data", + "progress_callback", "progress_callback_user_data", + "encoder_begin_callback", "encoder_begin_callback_user_data", + "logits_filter_callback", "logits_filter_callback_user_data", + "grammar_rules", "n_grammar_rules", "i_start_rule", "grammar_penalty"); + } +} diff --git a/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/params/WhisperHParams.java b/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/params/WhisperHParams.java new file mode 100644 index 0000000..99feae0 --- /dev/null +++ b/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/params/WhisperHParams.java @@ -0,0 +1,15 @@ +package io.github.ggerganov.whispercpp.params; + +public class WhisperHParams { + int n_vocab = 51864; + int n_audio_ctx = 1500; + int n_audio_state = 384; + int n_audio_head = 6; + int n_audio_layer = 4; + int n_text_ctx = 448; + int n_text_state = 384; + int n_text_head = 6; + int n_text_layer = 4; + int n_mels = 80; + int ftype = 1; +} diff --git a/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/params/WhisperSamplingStrategy.java b/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/params/WhisperSamplingStrategy.java new file mode 100644 index 0000000..a32c793 --- /dev/null +++ b/sys/whisper.cpp/bindings/java/src/main/java/io/github/ggerganov/whispercpp/params/WhisperSamplingStrategy.java @@ -0,0 +1,10 @@ +package io.github.ggerganov.whispercpp.params; + +/** Available sampling strategies */ +public enum WhisperSamplingStrategy { + /** similar to OpenAI's GreedyDecoder */ + WHISPER_SAMPLING_GREEDY, + + /** similar to OpenAI's BeamSearchDecoder */ + WHISPER_SAMPLING_BEAM_SEARCH +} diff --git a/sys/whisper.cpp/bindings/java/src/test/java/io/github/ggerganov/whispercpp/WhisperCppTest.java b/sys/whisper.cpp/bindings/java/src/test/java/io/github/ggerganov/whispercpp/WhisperCppTest.java new file mode 100644 index 0000000..034726a --- /dev/null +++ b/sys/whisper.cpp/bindings/java/src/test/java/io/github/ggerganov/whispercpp/WhisperCppTest.java @@ -0,0 +1,144 @@ +package io.github.ggerganov.whispercpp; + +import static org.junit.jupiter.api.Assertions.*; + +import io.github.ggerganov.whispercpp.bean.WhisperSegment; +import io.github.ggerganov.whispercpp.params.CBool; +import io.github.ggerganov.whispercpp.params.WhisperFullParams; +import io.github.ggerganov.whispercpp.params.WhisperSamplingStrategy; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; +import java.io.File; +import java.io.FileNotFoundException; +import java.util.List; + +class WhisperCppTest { + private static WhisperCpp whisper = new WhisperCpp(); + private static boolean modelInitialised = false; + + @BeforeAll + static void init() throws FileNotFoundException { + // By default, models are loaded from ~/.cache/whisper/ and are usually named "ggml-${name}.bin" + // or you can provide the absolute path to the model file. + //String modelName = "../../models/ggml-tiny.bin"; + String modelName = "../../models/ggml-tiny.en.bin"; + try { + whisper.initContext(modelName); + //whisper.getFullDefaultParams(WhisperSamplingStrategy.WHISPER_SAMPLING_GREEDY); + //whisper.getJavaDefaultParams(WhisperSamplingStrategy.WHISPER_SAMPLING_BEAM_SEARCH); + modelInitialised = true; + } catch (FileNotFoundException ex) { + System.out.println("Model " + modelName + " not found"); + } + } + + @Test + void testGetDefaultFullParams_BeamSearch() { + // When + WhisperFullParams params = whisper.getFullDefaultParams(WhisperSamplingStrategy.WHISPER_SAMPLING_BEAM_SEARCH); + + // Then + assertEquals(WhisperSamplingStrategy.WHISPER_SAMPLING_BEAM_SEARCH.ordinal(), params.strategy); + assertNotEquals(0, params.n_threads); + assertEquals(16384, params.n_max_text_ctx); + assertFalse(params.translate); + assertEquals(0.01f, params.thold_pt); + assertEquals(5, params.beam_search.beam_size); + assertEquals(-1.0f, params.beam_search.patience); + } + + @Test + void testGetDefaultFullParams_Greedy() { + // When + WhisperFullParams params = whisper.getFullDefaultParams(WhisperSamplingStrategy.WHISPER_SAMPLING_GREEDY); + + // Then + assertEquals(WhisperSamplingStrategy.WHISPER_SAMPLING_GREEDY.ordinal(), params.strategy); + assertNotEquals(0, params.n_threads); + assertEquals(16384, params.n_max_text_ctx); + assertEquals(5, params.greedy.best_of); + } + + @Test + void testFullTranscribe() throws Exception { + if (!modelInitialised) { + System.out.println("Model not initialised, skipping test"); + return; + } + + // Given + File file = new File(System.getProperty("user.dir"), "../../samples/jfk.wav"); + AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(file); + + byte[] b = new byte[audioInputStream.available()]; + float[] floats = new float[b.length / 2]; + + //WhisperFullParams params = whisper.getFullDefaultParams(WhisperSamplingStrategy.WHISPER_SAMPLING_GREEDY); + WhisperFullParams params = whisper.getFullDefaultParams(WhisperSamplingStrategy.WHISPER_SAMPLING_BEAM_SEARCH); + params.setProgressCallback((ctx, state, progress, user_data) -> System.out.println("progress: " + progress)); + params.print_progress = CBool.FALSE; + //params.initial_prompt = "and so my fellow Americans um, like"; + + + try { + audioInputStream.read(b); + + for (int i = 0, j = 0; i < b.length; i += 2, j++) { + int intSample = (int) (b[i + 1]) << 8 | (int) (b[i]) & 0xFF; + floats[j] = intSample / 32767.0f; + } + + // When + String result = whisper.fullTranscribe(params, floats); + + // Then + System.err.println(result); + assertEquals("And so my fellow Americans ask not what your country can do for you " + + "ask what you can do for your country.", + result.replace(",", "")); + } finally { + audioInputStream.close(); + } + } + + @Test + void testFullTranscribeWithTime() throws Exception { + if (!modelInitialised) { + System.out.println("Model not initialised, skipping test"); + return; + } + + // Given + File file = new File(System.getProperty("user.dir"), "../../samples/jfk.wav"); + AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(file); + + byte[] b = new byte[audioInputStream.available()]; + float[] floats = new float[b.length / 2]; + + //WhisperFullParams params = whisper.getFullDefaultParams(WhisperSamplingStrategy.WHISPER_SAMPLING_GREEDY); + WhisperFullParams params = whisper.getFullDefaultParams(WhisperSamplingStrategy.WHISPER_SAMPLING_BEAM_SEARCH); + params.setProgressCallback((ctx, state, progress, user_data) -> System.out.println("progress: " + progress)); + params.print_progress = CBool.FALSE; + //params.initial_prompt = "and so my fellow Americans um, like"; + + try { + audioInputStream.read(b); + + for (int i = 0, j = 0; i < b.length; i += 2, j++) { + int intSample = (int) (b[i + 1]) << 8 | (int) (b[i]) & 0xFF; + floats[j] = intSample / 32767.0f; + } + + List segments = whisper.fullTranscribeWithTime(params, floats); + assertTrue(segments.size() > 0, "The size of segments should be greater than 0"); + for (WhisperSegment segment : segments) { + System.out.println(segment); + } + } finally { + audioInputStream.close(); + } + } + +} diff --git a/sys/whisper.cpp/bindings/java/src/test/java/io/github/ggerganov/whispercpp/WhisperJnaLibraryTest.java b/sys/whisper.cpp/bindings/java/src/test/java/io/github/ggerganov/whispercpp/WhisperJnaLibraryTest.java new file mode 100644 index 0000000..07a340c --- /dev/null +++ b/sys/whisper.cpp/bindings/java/src/test/java/io/github/ggerganov/whispercpp/WhisperJnaLibraryTest.java @@ -0,0 +1,17 @@ +package io.github.ggerganov.whispercpp; + +import static org.junit.jupiter.api.Assertions.*; + +import org.junit.jupiter.api.Test; + +class WhisperJnaLibraryTest { + + @Test + void testWhisperPrint_system_info() { + String systemInfo = WhisperCppJnaLibrary.instance.whisper_print_system_info(); + // eg: "AVX = 1 | AVX2 = 1 | AVX512 = 0 | FMA = 1 | NEON = 0 | ARM_FMA = 0 | F16C = 1 | FP16_VA = 0 + // | WASM_SIMD = 0 | BLAS = 0 | SSE3 = 1 | VSX = 0 | COREML = 0 | " + System.out.println("System info: " + systemInfo); + assertTrue(systemInfo.length() > 10); + } +} diff --git a/sys/whisper.cpp/bindings/javascript/.gitignore b/sys/whisper.cpp/bindings/javascript/.gitignore new file mode 100644 index 0000000..17b4c53 --- /dev/null +++ b/sys/whisper.cpp/bindings/javascript/.gitignore @@ -0,0 +1 @@ +publish.log diff --git a/sys/whisper.cpp/bindings/javascript/CMakeLists.txt b/sys/whisper.cpp/bindings/javascript/CMakeLists.txt new file mode 100644 index 0000000..6b5af79 --- /dev/null +++ b/sys/whisper.cpp/bindings/javascript/CMakeLists.txt @@ -0,0 +1,41 @@ +set(TARGET libwhisper) + +add_executable(${TARGET} + emscripten.cpp + ) + +target_link_libraries(${TARGET} PRIVATE + whisper + ) + +unset(EXTRA_FLAGS) + +if (WHISPER_WASM_SINGLE_FILE) + set(EXTRA_FLAGS "-s SINGLE_FILE=1") + message(STATUS "Embedding WASM inside whisper.js") + + add_custom_command( + TARGET ${TARGET} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy + ${CMAKE_BINARY_DIR}/bin/libwhisper.js + ${CMAKE_CURRENT_SOURCE_DIR}/whisper.js + ) + + add_custom_command( + TARGET ${TARGET} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy + ${CMAKE_BINARY_DIR}/bin/libwhisper.worker.js + ${CMAKE_CURRENT_SOURCE_DIR}/libwhisper.worker.js + ) +endif() + +set_target_properties(${TARGET} PROPERTIES LINK_FLAGS " \ + --bind \ + -s MODULARIZE=1 \ + -s EXPORT_NAME=\"'whisper_factory'\" \ + -s FORCE_FILESYSTEM=1 \ + -s USE_PTHREADS=1 \ + -s PTHREAD_POOL_SIZE=8 \ + -s ALLOW_MEMORY_GROWTH=1 \ + ${EXTRA_FLAGS} \ + ") diff --git a/sys/whisper.cpp/bindings/javascript/README.md b/sys/whisper.cpp/bindings/javascript/README.md new file mode 100644 index 0000000..3947d25 --- /dev/null +++ b/sys/whisper.cpp/bindings/javascript/README.md @@ -0,0 +1,78 @@ +# whisper.cpp + +Node.js package for Whisper speech recognition + +Package: https://www.npmjs.com/package/whisper.cpp + +## Details + +The performance is comparable to when running `whisper.cpp` in the browser via WASM. + +The API is currently very rudimentary: [bindings/javascript/emscripten.cpp](/bindings/javascript/emscripten.cpp) + +For sample usage check [tests/test-whisper.js](/tests/test-whisper.js) + +## Package building + test + +```bash +# load emscripten +source /path/to/emsdk/emsdk_env.sh + +# clone repo +git clone https://github.com/ggerganov/whisper.cpp +cd whisper.cpp + +# grab base.en model +./models/download-ggml-model.sh base.en + +# prepare PCM sample for testing +ffmpeg -i samples/jfk.wav -f f32le -acodec pcm_f32le samples/jfk.pcmf32 + +# build +mkdir build-em && cd build-em +emcmake cmake .. && make -j + +# run test +node --experimental-wasm-threads --experimental-wasm-simd ../tests/test-whisper.js + +# publish npm package +make publish-npm +``` + +## Sample run + +```java +$ node --experimental-wasm-threads --experimental-wasm-simd ../tests/test-whisper.js + +whisper_model_load: loading model from 'whisper.bin' +whisper_model_load: n_vocab = 51864 +whisper_model_load: n_audio_ctx = 1500 +whisper_model_load: n_audio_state = 512 +whisper_model_load: n_audio_head = 8 +whisper_model_load: n_audio_layer = 6 +whisper_model_load: n_text_ctx = 448 +whisper_model_load: n_text_state = 512 +whisper_model_load: n_text_head = 8 +whisper_model_load: n_text_layer = 6 +whisper_model_load: n_mels = 80 +whisper_model_load: f16 = 1 +whisper_model_load: type = 2 +whisper_model_load: adding 1607 extra tokens +whisper_model_load: mem_required = 506.00 MB +whisper_model_load: ggml ctx size = 140.60 MB +whisper_model_load: memory size = 22.83 MB +whisper_model_load: model size = 140.54 MB + +system_info: n_threads = 8 / 10 | AVX = 0 | AVX2 = 0 | AVX512 = 0 | NEON = 0 | F16C = 0 | FP16_VA = 0 | WASM_SIMD = 1 | BLAS = 0 | + +operator(): processing 176000 samples, 11.0 sec, 8 threads, 1 processors, lang = en, task = transcribe ... + +[00:00:00.000 --> 00:00:11.000] And so my fellow Americans, ask not what your country can do for you, ask what you can do for your country. + +whisper_print_timings: load time = 162.37 ms +whisper_print_timings: mel time = 183.70 ms +whisper_print_timings: sample time = 4.27 ms +whisper_print_timings: encode time = 8582.63 ms / 1430.44 ms per layer +whisper_print_timings: decode time = 436.16 ms / 72.69 ms per layer +whisper_print_timings: total time = 9370.90 ms +``` diff --git a/sys/whisper.cpp/bindings/javascript/emscripten.cpp b/sys/whisper.cpp/bindings/javascript/emscripten.cpp new file mode 100644 index 0000000..b442c1f --- /dev/null +++ b/sys/whisper.cpp/bindings/javascript/emscripten.cpp @@ -0,0 +1,93 @@ +// +// This is the Javascript API of whisper.cpp +// +// Very crude at the moment. +// Feel free to contribute and make this better! +// +// See the tests/test-whisper.js for sample usage +// + +#include "whisper.h" + +#include +#include + +#include +#include + +struct whisper_context * g_context; + +EMSCRIPTEN_BINDINGS(whisper) { + emscripten::function("init", emscripten::optional_override([](const std::string & path_model) { + if (g_context == nullptr) { + g_context = whisper_init_from_file_with_params(path_model.c_str(), whisper_context_default_params()); + if (g_context != nullptr) { + return true; + } else { + return false; + } + } + + return false; + })); + + emscripten::function("free", emscripten::optional_override([]() { + if (g_context) { + whisper_free(g_context); + g_context = nullptr; + } + })); + + emscripten::function("full_default", emscripten::optional_override([](const emscripten::val & audio, const std::string & lang, bool translate) { + if (g_context == nullptr) { + return -1; + } + + struct whisper_full_params params = whisper_full_default_params(whisper_sampling_strategy::WHISPER_SAMPLING_GREEDY); + + params.print_realtime = true; + params.print_progress = false; + params.print_timestamps = true; + params.print_special = false; + params.translate = translate; + params.language = whisper_is_multilingual(g_context) ? lang.c_str() : "en"; + params.n_threads = std::min(8, (int) std::thread::hardware_concurrency()); + params.offset_ms = 0; + + std::vector pcmf32; + const int n = audio["length"].as(); + + emscripten::val heap = emscripten::val::module_property("HEAPU8"); + emscripten::val memory = heap["buffer"]; + + pcmf32.resize(n); + + emscripten::val memoryView = audio["constructor"].new_(memory, reinterpret_cast(pcmf32.data()), n); + memoryView.call("set", audio); + + // print system information + { + printf("\n"); + printf("system_info: n_threads = %d / %d | %s\n", + params.n_threads, std::thread::hardware_concurrency(), whisper_print_system_info()); + + printf("\n"); + printf("%s: processing %d samples, %.1f sec, %d threads, %d processors, lang = %s, task = %s ...\n", + __func__, int(pcmf32.size()), float(pcmf32.size())/WHISPER_SAMPLE_RATE, + params.n_threads, 1, + params.language, + params.translate ? "translate" : "transcribe"); + + printf("\n"); + } + + // run whisper + { + whisper_reset_timings(g_context); + whisper_full(g_context, params, pcmf32.data(), pcmf32.size()); + whisper_print_timings(g_context); + } + + return 0; + })); +} diff --git a/sys/whisper.cpp/bindings/javascript/libwhisper.worker.js b/sys/whisper.cpp/bindings/javascript/libwhisper.worker.js new file mode 100644 index 0000000..db2083a --- /dev/null +++ b/sys/whisper.cpp/bindings/javascript/libwhisper.worker.js @@ -0,0 +1 @@ +"use strict";var Module={};var ENVIRONMENT_IS_NODE=typeof process=="object"&&typeof process.versions=="object"&&typeof process.versions.node=="string";if(ENVIRONMENT_IS_NODE){var nodeWorkerThreads=require("worker_threads");var parentPort=nodeWorkerThreads.parentPort;parentPort.on("message",data=>onmessage({data:data}));var fs=require("fs");Object.assign(global,{self:global,require:require,Module:Module,location:{href:__filename},Worker:nodeWorkerThreads.Worker,importScripts:f=>(0,eval)(fs.readFileSync(f,"utf8")+"//# sourceURL="+f),postMessage:msg=>parentPort.postMessage(msg),performance:global.performance||{now:Date.now}})}var initializedJS=false;function threadPrintErr(){var text=Array.prototype.slice.call(arguments).join(" ");if(ENVIRONMENT_IS_NODE){fs.writeSync(2,text+"\n");return}console.error(text)}function threadAlert(){var text=Array.prototype.slice.call(arguments).join(" ");postMessage({cmd:"alert",text:text,threadId:Module["_pthread_self"]()})}var err=threadPrintErr;self.alert=threadAlert;Module["instantiateWasm"]=(info,receiveInstance)=>{var module=Module["wasmModule"];Module["wasmModule"]=null;var instance=new WebAssembly.Instance(module,info);return receiveInstance(instance)};self.onunhandledrejection=e=>{throw e.reason||e};function handleMessage(e){try{if(e.data.cmd==="load"){let messageQueue=[];self.onmessage=e=>messageQueue.push(e);self.startWorker=instance=>{Module=instance;postMessage({"cmd":"loaded"});for(let msg of messageQueue){handleMessage(msg)}self.onmessage=handleMessage};Module["wasmModule"]=e.data.wasmModule;for(const handler of e.data.handlers){Module[handler]=(...args)=>{postMessage({cmd:"callHandler",handler:handler,args:args})}}Module["wasmMemory"]=e.data.wasmMemory;Module["buffer"]=Module["wasmMemory"].buffer;Module["ENVIRONMENT_IS_PTHREAD"]=true;if(typeof e.data.urlOrBlob=="string"){importScripts(e.data.urlOrBlob)}else{var objectUrl=URL.createObjectURL(e.data.urlOrBlob);importScripts(objectUrl);URL.revokeObjectURL(objectUrl)}whisper_factory(Module)}else if(e.data.cmd==="run"){Module["__emscripten_thread_init"](e.data.pthread_ptr,0,0,1);Module["__emscripten_thread_mailbox_await"](e.data.pthread_ptr);Module["establishStackSpace"]();Module["PThread"].receiveObjectTransfer(e.data);Module["PThread"].threadInitTLS();if(!initializedJS){Module["__embind_initialize_bindings"]();initializedJS=true}try{Module["invokeEntryPoint"](e.data.start_routine,e.data.arg)}catch(ex){if(ex!="unwind"){throw ex}}}else if(e.data.cmd==="cancel"){if(Module["_pthread_self"]()){Module["__emscripten_thread_exit"](-1)}}else if(e.data.target==="setimmediate"){}else if(e.data.cmd==="checkMailbox"){if(initializedJS){Module["checkMailbox"]()}}else if(e.data.cmd){err(`worker.js received unknown command ${e.data.cmd}`);err(e.data)}}catch(ex){if(Module["__emscripten_thread_crashed"]){Module["__emscripten_thread_crashed"]()}throw ex}}self.onmessage=handleMessage; diff --git a/sys/whisper.cpp/bindings/javascript/package-tmpl.json b/sys/whisper.cpp/bindings/javascript/package-tmpl.json new file mode 100644 index 0000000..d8ba210 --- /dev/null +++ b/sys/whisper.cpp/bindings/javascript/package-tmpl.json @@ -0,0 +1,26 @@ +{ + "name": "whisper.cpp", + "version": "@PROJECT_VERSION@", + "description": "Whisper speech recognition", + "main": "whisper.js", + "scripts": { + "test": "echo \"todo: add tests\" && exit 0" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/ggerganov/whisper.cpp" + }, + "keywords": [ + "openai", + "whisper", + "speech-to-text", + "speech-recognition", + "transformer" + ], + "author": "Georgi Gerganov", + "license": "MIT", + "bugs": { + "url": "https://github.com/ggerganov/whisper.cpp/issues" + }, + "homepage": "https://github.com/ggerganov/whisper.cpp#readme" +} diff --git a/sys/whisper.cpp/bindings/javascript/package.json b/sys/whisper.cpp/bindings/javascript/package.json new file mode 100644 index 0000000..2bc6f6f --- /dev/null +++ b/sys/whisper.cpp/bindings/javascript/package.json @@ -0,0 +1,26 @@ +{ + "name": "whisper.cpp", + "version": "1.5.1", + "description": "Whisper speech recognition", + "main": "whisper.js", + "scripts": { + "test": "echo \"todo: add tests\" && exit 0" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/ggerganov/whisper.cpp" + }, + "keywords": [ + "openai", + "whisper", + "speech-to-text", + "speech-recognition", + "transformer" + ], + "author": "Georgi Gerganov", + "license": "MIT", + "bugs": { + "url": "https://github.com/ggerganov/whisper.cpp/issues" + }, + "homepage": "https://github.com/ggerganov/whisper.cpp#readme" +} diff --git a/sys/whisper.cpp/bindings/javascript/whisper.js b/sys/whisper.cpp/bindings/javascript/whisper.js new file mode 100644 index 0000000..5dcd5e6 --- /dev/null +++ b/sys/whisper.cpp/bindings/javascript/whisper.js @@ -0,0 +1,19 @@ + +var whisper_factory = (() => { + var _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined; + if (typeof __filename !== 'undefined') _scriptDir = _scriptDir || __filename; + return ( +function(moduleArg = {}) { + +function GROWABLE_HEAP_I8(){if(wasmMemory.buffer!=HEAP8.buffer){updateMemoryViews()}return HEAP8}function GROWABLE_HEAP_U8(){if(wasmMemory.buffer!=HEAP8.buffer){updateMemoryViews()}return HEAPU8}function GROWABLE_HEAP_I16(){if(wasmMemory.buffer!=HEAP8.buffer){updateMemoryViews()}return HEAP16}function GROWABLE_HEAP_U16(){if(wasmMemory.buffer!=HEAP8.buffer){updateMemoryViews()}return HEAPU16}function GROWABLE_HEAP_I32(){if(wasmMemory.buffer!=HEAP8.buffer){updateMemoryViews()}return HEAP32}function GROWABLE_HEAP_U32(){if(wasmMemory.buffer!=HEAP8.buffer){updateMemoryViews()}return HEAPU32}function GROWABLE_HEAP_F32(){if(wasmMemory.buffer!=HEAP8.buffer){updateMemoryViews()}return HEAPF32}function GROWABLE_HEAP_F64(){if(wasmMemory.buffer!=HEAP8.buffer){updateMemoryViews()}return HEAPF64}var Module=moduleArg;var readyPromiseResolve,readyPromiseReject;Module["ready"]=new Promise((resolve,reject)=>{readyPromiseResolve=resolve;readyPromiseReject=reject});var moduleOverrides=Object.assign({},Module);var arguments_=[];var thisProgram="./this.program";var quit_=(status,toThrow)=>{throw toThrow};var ENVIRONMENT_IS_WEB=typeof window=="object";var ENVIRONMENT_IS_WORKER=typeof importScripts=="function";var ENVIRONMENT_IS_NODE=typeof process=="object"&&typeof process.versions=="object"&&typeof process.versions.node=="string";var ENVIRONMENT_IS_PTHREAD=Module["ENVIRONMENT_IS_PTHREAD"]||false;var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var read_,readAsync,readBinary,setWindowTitle;if(ENVIRONMENT_IS_NODE){var fs=require("fs");var nodePath=require("path");if(ENVIRONMENT_IS_WORKER){scriptDirectory=nodePath.dirname(scriptDirectory)+"/"}else{scriptDirectory=__dirname+"/"}read_=(filename,binary)=>{filename=isFileURI(filename)?new URL(filename):nodePath.normalize(filename);return fs.readFileSync(filename,binary?undefined:"utf8")};readBinary=filename=>{var ret=read_(filename,true);if(!ret.buffer){ret=new Uint8Array(ret)}return ret};readAsync=(filename,onload,onerror,binary=true)=>{filename=isFileURI(filename)?new URL(filename):nodePath.normalize(filename);fs.readFile(filename,binary?undefined:"utf8",(err,data)=>{if(err)onerror(err);else onload(binary?data.buffer:data)})};if(!Module["thisProgram"]&&process.argv.length>1){thisProgram=process.argv[1].replace(/\\/g,"/")}arguments_=process.argv.slice(2);quit_=(status,toThrow)=>{process.exitCode=status;throw toThrow};Module["inspect"]=()=>"[Emscripten Module object]";let nodeWorkerThreads;try{nodeWorkerThreads=require("worker_threads")}catch(e){console.error('The "worker_threads" module is not supported in this node.js build - perhaps a newer version is needed?');throw e}global.Worker=nodeWorkerThreads.Worker}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WORKER){scriptDirectory=self.location.href}else if(typeof document!="undefined"&&document.currentScript){scriptDirectory=document.currentScript.src}if(_scriptDir){scriptDirectory=_scriptDir}if(scriptDirectory.indexOf("blob:")!==0){scriptDirectory=scriptDirectory.substr(0,scriptDirectory.replace(/[?#].*/,"").lastIndexOf("/")+1)}else{scriptDirectory=""}if(!ENVIRONMENT_IS_NODE){read_=url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(ENVIRONMENT_IS_WORKER){readBinary=url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=(url,onload,onerror)=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=()=>{if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response);return}onerror()};xhr.onerror=onerror;xhr.send(null)}}setWindowTitle=title=>document.title=title}else{}if(ENVIRONMENT_IS_NODE){if(typeof performance=="undefined"){global.performance=require("perf_hooks").performance}}var defaultPrint=console.log.bind(console);var defaultPrintErr=console.error.bind(console);if(ENVIRONMENT_IS_NODE){defaultPrint=(...args)=>fs.writeSync(1,args.join(" ")+"\n");defaultPrintErr=(...args)=>fs.writeSync(2,args.join(" ")+"\n")}var out=Module["print"]||defaultPrint;var err=Module["printErr"]||defaultPrintErr;Object.assign(Module,moduleOverrides);moduleOverrides=null;if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];if(Module["quit"])quit_=Module["quit"];var wasmBinary;if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];var noExitRuntime=Module["noExitRuntime"]||true;if(typeof WebAssembly!="object"){abort("no native wasm support detected")}var wasmMemory;var wasmModule;var ABORT=false;var EXITSTATUS;function assert(condition,text){if(!condition){abort(text)}}var HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateMemoryViews(){var b=wasmMemory.buffer;Module["HEAP8"]=HEAP8=new Int8Array(b);Module["HEAP16"]=HEAP16=new Int16Array(b);Module["HEAPU8"]=HEAPU8=new Uint8Array(b);Module["HEAPU16"]=HEAPU16=new Uint16Array(b);Module["HEAP32"]=HEAP32=new Int32Array(b);Module["HEAPU32"]=HEAPU32=new Uint32Array(b);Module["HEAPF32"]=HEAPF32=new Float32Array(b);Module["HEAPF64"]=HEAPF64=new Float64Array(b)}var INITIAL_MEMORY=Module["INITIAL_MEMORY"]||16777216;assert(INITIAL_MEMORY>=65536,"INITIAL_MEMORY should be larger than STACK_SIZE, was "+INITIAL_MEMORY+"! (STACK_SIZE="+65536+")");if(ENVIRONMENT_IS_PTHREAD){wasmMemory=Module["wasmMemory"]}else{if(Module["wasmMemory"]){wasmMemory=Module["wasmMemory"]}else{wasmMemory=new WebAssembly.Memory({"initial":INITIAL_MEMORY/65536,"maximum":2147483648/65536,"shared":true});if(!(wasmMemory.buffer instanceof SharedArrayBuffer)){err("requested a shared WebAssembly.Memory but the returned buffer is not a SharedArrayBuffer, indicating that while the browser has SharedArrayBuffer it does not have WebAssembly threads support - you may need to set a flag");if(ENVIRONMENT_IS_NODE){err("(on node you may need: --experimental-wasm-threads --experimental-wasm-bulk-memory and/or recent version)")}throw Error("bad memory")}}}updateMemoryViews();INITIAL_MEMORY=wasmMemory.buffer.byteLength;var wasmTable;var __ATPRERUN__=[];var __ATINIT__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;var runtimeKeepaliveCounter=0;function keepRuntimeAlive(){return noExitRuntime||runtimeKeepaliveCounter>0}function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function initRuntime(){runtimeInitialized=true;if(ENVIRONMENT_IS_PTHREAD)return;if(!Module["noFSInit"]&&!FS.init.initialized)FS.init();FS.ignorePermissions=false;TTY.init();callRuntimeCallbacks(__ATINIT__)}function postRun(){if(ENVIRONMENT_IS_PTHREAD)return;if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}function addOnInit(cb){__ATINIT__.unshift(cb)}function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function getUniqueRunDependency(id){return id}function addRunDependency(id){runDependencies++;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}}function removeRunDependency(id){runDependencies--;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}function abort(what){if(Module["onAbort"]){Module["onAbort"](what)}what="Aborted("+what+")";err(what);ABORT=true;EXITSTATUS=1;what+=". Build with -sASSERTIONS for more info.";var e=new WebAssembly.RuntimeError(what);readyPromiseReject(e);throw e}var dataURIPrefix="data:application/octet-stream;base64,";function isDataURI(filename){return filename.startsWith(dataURIPrefix)}function isFileURI(filename){return filename.startsWith("file://")}var wasmBinaryFile;wasmBinaryFile="data:application/octet-stream;base64,AGFzbQEAAAABvwRJYAF/AGABfwF/YAJ/fwBgA39/fwF/YAJ/fwF/YAN/f38AYAR/f39/AGAGf39/f39/AX9gBH9/f38Bf2AAAGAFf39/f38Bf2AFf39/f38AYAZ/f39/f38AYAh/f39/f39/fwF/YAABf2AHf39/f39/fwF/YAd/f39/f39/AGABfQF9YAV/fn5+fgBgA39+fwF+YAV/f39/fgF/YAR/f39/AX5gBH9+fn8AYAp/f39/f39/f39/AX9gB39/f39/fn4Bf2AGf39/f35+AX9gBX9/fn9/AGADf39/AXxgBH9/f38BfGAEf39+fgF/YAJ/fgBgAXwBfWACfH8BfGAFf39+fn4Bf2AIf39/f39/f38AYAx/f39/f39/f39/f38Bf2ADf35/AX9gD39/f39/f39/f39/f39/fwBgCn9/f39/f39/f38AYAt/f39/f39/f39/fwF/YAZ/fH9/f38Bf2AJf39/f39/f39/AGAFf39/f3wBf2AAAXxgA39/fgF/YAABfmACf3wAYAJ9fQF9YAN/f30Bf2AEfn5+fgF/YAJ+fwF/YAN/f3wBf2ABfABgCH9/fn5+f39/AX9gBX9/f399AGAGf39+fn9/AX9gAn5+AXxgAnx8AXxgBH9/fn4AYAR/f35/AX9gA39/fwF9YAR/f39+AX5gA39/fgBgAn5+AX1gAn9/AX5gA35+fgF/YAF+AX9gAXwBfGABfwF+YAJ9fwF/YAV/f399fQBgBH9/f30AYAl/f39/f39/f38BfwKmAjABYQFiAAABYQFjAAUBYQFkAAUBYQFlACsBYQFmAAABYQFnAAsBYQFoAAkBYQFpABABYQFqAAQBYQFrAAEBYQFsAAUBYQFtAAABYQFuAAABYQFvAAkBYQFwAAEBYQFxAAgBYQFyAAMBYQFzAAIBYQF0AAUBYQF1AAgBYQF2AAEBYQF3AAABYQF4ABsBYQF5AAoBYQF6ABABYQFBAA4BYQFCAA4BYQFDAAoBYQFEAAQBYQFFAAQBYQFGAAEBYQFHAAUBYQFIAAgBYQFJABwBYQFKAAABYQFLAAABYQFMAAgBYQFNAAMBYQFOAAgBYQFPAAkBYQFQAAABYQFRAA4BYQFSAAIBYQFTAAYBYQFUAAIBYQFVAAYBYQFWAAQBYQFhAgOAAoCAAgOdB5sHAAUBAQEFEQkEBAIC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Sw0BCyABUCACQv///////////wCDIgtCgICAgICAwP//AFQgC0KAgICAgIDA//8AURtFBEAgAkKAgICAgIAghCEKDAILIANQIARC////////////AIMiAkKAgICAgIDA//8AVCACQoCAgICAgMD//wBRG0UEQCAEQoCAgICAgCCEIQogAyEBDAILIAEgC0KAgICAgIDA//8AhYRQBEAgAiADhFAEQEKAgICAgIDg//8AIQpCACEBDAMLIApCgICAgICAwP//AIQhCkIAIQEMAgsgAyACQoCAgICAgMD//wCFhFAEQCABIAuEIRlCACEBIBlQBEBCgICAgICA4P//ACEKDAMLIApCgICAgICAwP//AIQhCgwCCyABIAuEUARAQgAhAQwCCyACIAOEUARAQgAhAQwCCyALQv///////z9YBEAgBUHQAGogASANIAEgDSANUCIGG3kgBkEGdK18pyIGQQ9rEGdBECAGayEGIAUpA1giDUIgiCEOIAUpA1AhAQsgAkL///////8/Vg0AIAVBQGsgAyAMIAMgDCAMUCIIG3kgCEEGdK18pyIIQQ9rEGcgBiAIa0EQaiEGIAUpA0ghDCAFKQNAIQMLIANCD4YiC0KAgP7/D4MiAiABQiCIIgR+IhAgC0IgiCITIAFC/////w+DIgF+fCIPQiCGIhEgASACfnwiCyARVK0gAiANQv////8PgyINfiIVIAQgE358IhEgDEIPhiISIANCMYiEQv////8PgyIDIAF+fCIUIA8gEFStQiCGIA9CIIiEfCIPIAIgDkKAgASEIgx+IhYgDSATfnwiDiASQiCIQoCAgIAIhCICIAF+fCIQIAMgBH58IhJCIIZ8Ihd8IQEgByAJaiAGakH//wBrIQYCQCACIAR+IhggDCATfnwiBCAYVK0gBCAEIAMgDX58IgRWrXwgAiAMfnwgBCAEIBEgFVStIBEgFFatfHwiBFatfCADIAx+IgMgAiANfnwiAiADVK1CIIYgAkIgiIR8IAQgAkIghnwiAiAEVK18IAIgAiAQIBJWrSAOIBZUrSAOIBBWrXx8QiCGIBJCIIiEfCICVq18IAIgAiAPIBRUrSAPIBdWrXx8IgJWrXwiBEKAgICAgIDAAINCAFIEQCAGQQFqIQYMAQsgC0I/iCEaIARCAYYgAkI/iIQhBCACQgGGIAFCP4iEIQIg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IAIgAToADwJAIAAtAAtBB3YEQCAAKAIAIQEgAEEBNgIEDAELIAAiASABLQALQYABcUEBcjoACyABIAEtAAtB/wBxOgALCyABIAItAA86AAAgAkEAOgAOIAEgAi0ADjoAASACQRBqJAAL9gIDA38BfAF9IwBBEGsiASQAAn0gALwiA0H/////B3EiAkHan6T6A00EQEMAAIA/IAJBgICAzANJDQEaIAC7EIIBDAELIAJB0aftgwRNBEAgAkHkl9uABE8EQEQYLURU+yEJQEQYLURU+yEJwCADQQBIGyAAu6AQggGMDAILIAC7IQQgA0EASARAIAREGC1EVPsh+T+gEIEBDAILRBgtRFT7Ifk/IAShEIEBDAELIAJB1eOIhwRNBEAgAkHg27+FBE8EQEQYLURU+yEZQEQYLURU+yEZwCADQQBIGyAAu6AQggEMAgsgA0EASARARNIhM3982RLAIAC7oRCBAQwCCyAAu0TSITN/fNkSwKAQgQEMAQsgACAAkyACQYCAgPwHTw0AGgJAAkACQAJAIAAgAUEIahCvBEEDcQ4DAAECAwsgASsDCBCCAQwDCyABKwMImhCBAQwCCyABKwMIEIIBjAwBCyABKwMIEIEBCyEFIAFBEGokACAFCw0AIAAoAgAQ+wMaIAALDQAgACgCABD9AxogAAurAQICfgF/IAApAyAhASAAKQMYIQIgACgCACIDQRBrQXFNBEAgA0EkbEGYmgFqKAIAIAAoAjAgACgCEEEBa2xqIAAoAjQgAqdBAWtsaiAAKAI4IAGnQQFrbGogACgCPCAAKAIoQQFrbGoPCyAANQI0IAJCAX1+IAApAxAgADUCMH4gA0EkbEGUmgFqNQIAf3wgADUCOCABQgF9fnwgADUCPCAAKQMoQgF9fnynCw4AIABB0ABqEDtB0ABqC8EBAQN/IwBBEGsiBSQAAkAgAiAALQALQQd2BH8gACgCCEH/////B3FBAWsFQQoLIgQCfyAALQALQQd2BEAgACgCBAwBCyAALQALQf8AcQsiA2tNBEAgAkUNAQJ/IAAtAAtBB3YEQCAAKAIADAELIAALIgQgA2ogASACEHggACACIANqIgEQmQEgBUEAOgAPIAEgBGogBS0ADzoAAAwBCyAAIAQgAiAEayADaiADIANBACACIAEQzQELIAVBEGokACAAC3UBAX4gACABIAR+IAIgA358IANCIIgiAiABQiCIIgR+fCADQv////8PgyIDIAFC/////w+DIgF+IgVCIIggAyAEfnwiA0IgiHwgASACfiADQv////8Pg3wiAUIgiHw3AwggACAFQv////8PgyABQiCGhDcDAAsYACAALQAAQSBxRQRAIAEgAiAAEM8CGgsLRgECfyMAQRBrIgUkACAFIAI2AgwgBSAENgIIIAVBBGogBUEMahB9IQYgACABIAMgBSgCCBCxASEAIAYQfCAFQRBqJAAgAAvtAQECfwJ/IAAtAAtBB3YEQCAAKAIEDAELIAAtAAtB/wBxCyEEAkAgAiABa0EFSA0AIARFDQAgASACEOoBIAJBBGshBAJ/IAAtAAtBB3YEQCAAKAIEDAELIAAtAAtB/wBxCwJ/IAAtAAtBB3YEQCAAKAIADAELIAALIgJqIQUCQANAAkAgAiwAACEAIAEgBE8NAAJAIABBAEwNACAAQf8ATg0AIAAgASgCAEcNAwsgAUEEaiEBIAIgBSACa0EBSmohAgwBCwsgAEEATA0BIABB/wBODQEgAiwAACAEKAIAQQFrSw0BCyADQQQ2AgALC3YBAX8jAEEQayICJAAgAC0AC0EHdgRAIAAgACgCACAAKAIIQf////8HcRDxAQsgACABKAIINgIIIAAgASkCADcCACABIAEtAAtBgAFxOgALIAEgAS0AC0H/AHE6AAsgAkEAOgAPIAEgAi0ADzoAACACQRBqJAALUAEBfgJAIANBwABxBEAgASADQUBqrYYhAkIAIQEMAQsgA0UNACACIAOtIgSGIAFBwAAgA2utiIQhAiABIASGIQELIAAgATcDACAAIAI3AwgLbwEBfyMAQYACayIFJAACQCACIANMDQAgBEGAwARxDQAgBSABQf8BcSACIANrIgNBgAIgA0GAAkkiARsQoQEgAUUEQANAIAAgBUGAAhBjIANBgAJrIgNB/wFLDQALCyAAIAUgAxBjCyAFQYACaiQAC3oBA38CQAJAIAAiAUEDcUUNACABLQAARQRAQQAPCwNAIAFBAWoiAUEDcUUNASABLQAADQALDAELA0AgASICQQRqIQEgAigCACIDQX9zIANBgYKECGtxQYCBgoR4cUUNAAsDQCACIgFBAWohAiABLQAADQALCyABIABrC4oDAgN/AXwjAEEQayIBJAACQCAAvCIDQf////8HcSICQdqfpPoDTQRAIAJBgICAzANJDQEgALsQgQEhAAwBCyACQdGn7YMETQRAIAC7IQQgAkHjl9uABE0EQCADQQBIBEAgBEQYLURU+yH5P6AQggGMIQAMAwsgBEQYLURU+yH5v6AQggEhAAwCC0QYLURU+yEJwEQYLURU+yEJQCADQQBOGyAEoJoQgQEhAAwBCyACQdXjiIcETQRAIAJB39u/hQRNBEAgALshBCADQQBIBEAgBETSITN/fNkSQKAQggEhAAwDCyAERNIhM3982RLAoBCCAYwhAAwCC0QYLURU+yEZQEQYLURU+yEZwCADQQBIGyAAu6AQgQEhAAwBCyACQYCAgPwHTwRAIAAgAJMhAAwBCwJAAkACQAJAIAAgAUEIahCvBEEDcQ4DAAECAwsgASsDCBCBASEADAMLIAErAwgQggEhAAwCCyABKwMImhCBASEADAELIAErAwgQggGMIQALIAFBEGokACAACzgCA38BfiMAQRBrIgAkACAAENgBIAApAwAhAyAAKAIIIQIgAEEQaiQAIAJB6AdtrCADQsCEPX58C9YBAQJ/IwBBEGsiBCQAAkACQCACQQtJBEAgACIDIAAtAAtBgAFxIAJyOgALIAAgAC0AC0H/AHE6AAsMAQsgAkHv////B0sNASAEQQhqIAAgAkELTwR/IAJBEGpBcHEiAyADQQFrIgMgA0ELRhsFQQoLQQFqEMMBIAQoAgwaIAAgBCgCCCIDNgIAIAAgACgCCEGAgICAeHEgBCgCDEH/////B3FyNgIIIAAgACgCCEGAgICAeHI2AgggACACNgIECyADIAEgAkEBahB4IARBEGokAA8LEE0ACwoAIABB5Ig1EHkLBABBAAuJAgEHfyABIAAoAggiAyAAKAIEIgJrQQJ1TQRAIAAgAQR/IAJBACABQQJ0IgD8CwAgACACagUgAgs2AgQPCwJAIAIgACgCACIFa0ECdSIHIAFqIgRBgICAgARJBEBB/////wMgAyAFayIDQQF1IgggBCAEIAhJGyADQfz///8HTxsiAwRAIANBgICAgARPDQIgA0ECdBAxIQYLIAdBAnQgBmoiBEEAIAFBAnQiAfwLACABIARqIQEgAiAFRwRAA0AgBEEEayIEIAJBBGsiAioCADgCACACIAVHDQALCyAAIAYgA0ECdGo2AgggACABNgIEIAAgBDYCACAFBEAgBRAvCw8LEDYACxBIAAstACACRQRAIAAoAgQgASgCBEYPCyAAIAFGBEBBAQ8LIAAoAgQgASgCBBCfAUULUgEBfyABQQFrIgJBEE0EfyACQQJ0QcyoA2ooAgAFQakiCyECIABB2LQDNgIAIABB3LUDNgIAIABBBGogAhCLAyAAIAE2AgggAEGYoAM2AgAgAAvHCQIEfwZ+IwBB8ABrIgYkACAEQv///////////wCDIQkCQAJAIAFQIgUgAkL///////////8AgyIKQoCAgICAgMD//wB9QoCAgICAgMCAgH9UIApQG0UEQCADQgBSIAlCgICAgICAwP//AH0iC0KAgICAgIDAgIB/ViALQoCAgICAgMCAgH9RGw0BCyAFIApCgICAgICAwP//AFQgCkKAgICAgIDA//8AURtFBEAgAkKAgICAgIAghCEEIAEhAwwCCyADUCAJQoCAgICAgMD//wBUIAlCgICAgICAwP//AFEbRQRAIARCgICAgICAIIQhBAwCCyABIApCgICAgICAwP//AIWEUARAQoCAgICAgOD//wAgAiABIAOFIAIgBIVCgICAgICAgICAf4WEUCIFGyEEQgAgASAFGyEDDAILIAMgCUKAgICAgIDA//8AhYRQDQEgASAKhFAEQCADIAmEQgBSDQIgASADgyEDIAIgBIMhBAwCCyADIAmEQgBSDQAgASEDIAIhBAwBCyADIAEgASADVCAJIApWIAkgClEbIggbIQogBCACIAgbIgtC////////P4MhCSACIAQgCBsiAkIwiKdB//8BcSEHIAtCMIinQf//AXEiBUUEQCAGQeAAaiAKIAkgCiAJIAlQIgUbeSAFQQZ0rXynIgVBD2sQZyAGKQNoIQkgBikDYCEKQRAgBWshBQsgASADIAgbIQMgAkL///////8/gyEEIAdFBEAgBkHQAGogAyAEIAMgBCAEUCIHG3kgB0EGdK18pyIHQQ9rEGdBECAHayEHIAYpA1ghBCAGKQNQIQMLIARCA4YgA0I9iIRCgICAgICAgASEIQEgCUIDhiAKQj2IhCEOIAIgC4UhDQJ+IANCA4YiAiAFIAdGDQAaIAUgB2siB0H/AEsEQEIAIQFCAQwBCyAGQUBrIAIgAUGAASAHaxBnIAZBMGogAiABIAcQsAEgBikDOCEBIAYpAzAgBikDQCAGKQNIhEIAUq2ECyEJIA5CgICAgICAgASEIQwgCkIDhiEKAkAgDUIAUwRAQgAhA0IAIQQgCSAKhSABIAyFhFANAiAKIAl9IQIgDCABfSAJIApWrX0iBEL/////////A1YNASAGQSBqIAIgBCACIAQgBFAiBxt5IAdBBnStfKdBDGsiBxBnIAUgB2shBSAGKQMoIQQgBikDICECDAELIAkgCnwiAiAJVK0gASAMfHwiBEKAgICAgICACINQDQAgCUIBgyAEQj+GIAJCAYiEhCECIAVBAWohBSAEQgGIIQQLIAtCgICAgICAgICAf4MhASAFQf//AU4EQCABQoCAgICAgMD//wCEIQRCACEDDAELQQAhBwJAIAVBAEoEQCAFIQcMAQsgBkEQaiACIAQgBUH/AGoQZyAGIAIgBEEBIAVrELABIAYpAwAgBikDECAGKQMYhEIAUq2EIQIgBikDCCEECyACp0EHcSIFQQRLrSAEQj2GIAJCA4iEIgJ8IgMgAlStIARCA4hC////////P4MgB61CMIaEIAGEfCEEAkAgBUEERgRAIAQgA0IBgyIBIAN8IgMgAVStfCEEDAELIAVFDQELCyAAIAM3AwAgACAENwMIIAZB8ABqJAALCgAgAEHsiDUQeQsuAQF/IwBBEGsiAyQAIAMgAjYCDCAAQcQBakHAACABIAIQsQEaIANBEGokACAAC2QAIAIoAgRBsAFxIgJBIEYEQCABDwsCQCACQRBHDQACQAJAIAAtAAAiAkEraw4DAAEAAQsgAEEBag8LIAEgAGtBAkgNACACQTBHDQAgAC0AAUEgckH4AEcNACAAQQJqIQALIAALPQECfwJ/IAAtAAtBB3YEQCAAKAIADAELIAALIQEjAEEQayIAJAAgACABNgIMIAAoAgwhAiAAQRBqJAAgAgt+AgJ/AX4jAEEQayIDJAAgAAJ+IAFFBEBCAAwBCyADIAEgAUEfdSICcyACayICrUIAIAJnIgJB0QBqEGcgAykDCEKAgICAgIDAAIVBnoABIAJrrUIwhnwgAUGAgICAeHGtQiCGhCEEIAMpAwALNwMAIAAgBDcDCCADQRBqJAALDAAgASACIAAQgQQaCycAIAAoAgAiACABEEwiARCuA0UEQBBHAAsgACgCCCABQQJ0aigCAAuPBAEDfyACQYAETwRAIAAgASAC/AoAACAADwsgACACaiEEAkAgACABc0EDcUUEQAJ/IAAgAEEDcUUNABogACACRQ0AGiAAIAEgAEF/cyICIAQgAEEBaiIDIAMgBEkbaiIDIAJBA3EiAiACIANLG0EBaiIC/AoAACABIAJqIQEgACACagshAgJAIARBfHEiA0HAAEkNACACIANBQGoiBUsNAANAIAIgASgCADYCACACIAEoAgQ2AgQgAiABKAIINgIIIAIgASgCDDYCDCACIAEoAhA2AhAgAiABKAIUNgIUIAIgASgCGDYCGCACIAEoAhw2AhwgAiABKAIgNgIgIAIgASgCJDYCJCACIAEoAig2AiggAiABKAIsNgIsIAIgASgCMDYCMCACIAEoAjQ2AjQgAiABKAI4NgI4IAIgASgCPDYCPCABQUBrIQEgAkFAayICIAVNDQALCyACIANPDQEgAiABIAJBf3MgAyACQQRqIgUgAyAFSxtqQXxxQQRqIgP8CgAAIAEgA2ohASACIANqIQIMAQsgBEEESQRAIAAhAgwBCyAAIARBBGsiA0sEQCAAIQIMAQsgACECA0AgAiABLQAAOgAAIAIgAS0AAToAASACIAEtAAI6AAIgAiABLQADOgADIAFBBGohASACQQRqIgIgA00NAAsLIAIgBEkEQCACIAEgBCACa/wKAAALIAALIAAjAEEQayIBJAAgAEIANwIAIABBADYCCCABQRBqJAALEgAgACgCACIABEAgABDhAxoLCxEAIAAgASgCABDhAzYCACAAC0cBAn8gACABNwNwIAAgACgCLCAAKAIEIgNrrDcDeCAAKAIIIQICQCABUA0AIAIgA2usIAFXDQAgAyABp2ohAgsgACACNgJoCx8AIABBzABqIgBBAP5BAgBBgICAgARxBEAgABCMAQsLkAEBBH8CQCMDKAIYIgEgACgCTEH/////e3FGDQBBASEDIABBzABqIgJBACAB/kgCAEUNACACQQAgAUGAgICABHIiBP5IAgAiAEUNAANAIABBgICAgARyIQECQCAAQYCAgIAEcUUEQCAAIAIgACAB/kgCAEcNAQsgAiABEK4ECyACQQAgBP5IAgAiAA0ACwsgAwtLAQJ8IAAgAKIiASAAoiICIAEgAaKiIAFEp0Y7jIfNxj6iRHTnyuL5ACq/oKIgAiABRLL7bokQEYE/okR3rMtU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ay0AADoAACADQQRrIgMgAkEEayICLQAAOgAAIAIgB0cNAAsLIAAoAhQhAgsgACAINgIcIAAgCTYCGCAAIAU2AhQgAkUNAQsgAhAvCw8LEDYACxA2AAsgAiABOgAAIAAgAkEBajYCGAuUBAEEfyABIAAgAUYiAjoADAJAIAINAANAIAEoAggiAi0ADA0BAkAgAiACKAIIIgMoAgAiBEYEQAJAIAMoAgQiBEUNACAELQAMDQAMAgsCQCABIAIoAgBGBEAgAiEBDAELIAIgAigCBCIBKAIAIgA2AgQgASAABH8gACACNgIIIAIoAggFIAMLNgIIIAIoAggiACAAKAIAIAJHQQJ0aiABNgIAIAEgAjYCACACIAE2AgggASgCCCIDKAIAIQILIAFBAToADCADQQA6AAwgAyACKAIEIgA2AgAgAARAIAAgAzYCCAsgAiADKAIINgIIIAMoAggiACAAKAIAIANHQQJ0aiACNgIAIAIgAzYCBCADIAI2AggPCwJAIARFDQAgBC0ADA0ADAELAkAgASACKAIARwRAIAIhAQwBCyACIAEoAgQiADYCACABIAAEfyAAIAI2AgggAigCCAUgAws2AgggAigCCCIAIAAoAgAgAkdBAnRqIAE2AgAgASACNgIEIAIgATYCCCABKAIIIQMLIAFBAToADCADQQA6AAwgAyADKAIEIgAoAgAiATYCBCABBEAgASADNgIICyAAIAMoAgg2AgggAygCCCIBIAEoAgAgA0dBAnRqIAA2AgAgACADNgIAIAMgADYCCAwCCyAEQQxqIQUgAkEBOgAMIAMgACADRjoADCAFQQE6AAAgAyIBIABHDQALCwucAgEEfyAAKAKIASIBBEAgACABNgKMASABEC8LIAAoAnwiAQRAIAAgATYCgAEgARAvCyAAKAJwIgEEQCAAIAE2AnQgARAvCyAAKAJkIgEEQCAAIAE2AmggARAvCyAAKAJEIgMEQCADIQIgAyAAKAJIIgFHBEADQCABQQxrIgIoAgAiBARAIAFBCGsgBDYCACAEEC8LIAIiASADRw0ACyAAKAJEIQILIAAgAzYCSCACEC8LIAAoAjgiAwRAIAMhAiADIAAoAjwiAUcEQANAIAFBDGsiAigCACIEBEAgAUEIayAENgIAIAQQLwsgAiIBIANHDQALIAAoAjghAgsgACADNgI8IAIQLwsgACgCACIBBEAgACABNgIEIAEQLwsLcAEDfyABEGkiAkHw////B0kEQAJAIAJBCk0EQCAAIAI6AAsgACEDDAELIAJBD3JBAWoiBBAxIQMgACAEQYCAgIB4cjYCCCAAIAM2AgAgACACNgIECyADIAEgAvwKAAAgAiADakEAOgAAIAAPCxBNAAseAQF/IAAEQCAAKAIAIgEEQCAAIAERAAALIAAQLwsLhQEBAn8jAEEQayICJAAgACgCBCEDIAAgARCpAQJAIAMgACgCBCIDTg0AIAAoAgwgA0ECdGpBBGsoAgAgAUYNACACQcwTNgIIIAJBp/cANgIEIAJBxyY2AgBBqMICKAIAIgBBpeMAIAIQMCAAEDMaQazCAigCABAzGkEBEAAACyACQRBqJAALsAYBCH8jAEHQAGsiBCQAIAQgACkCGDcDSAJAAkACQAJAAkACfyMAQSBrIgIkACAEKAJMIQYgASAEKAJIIgdwIgghAwJAAkADQAJAIAYgA0ECdGoiCSgCACIFRQ0AIAEgBUYNACADQQFqIgNBACADIAdHGyIDIAhHDQEMAgsLIANBf0YNAAJAAkAgASAFRgRAQX4hAwwBCyAFDQEgCSABNgIACyACQSBqJAAgAwwDCyACQfkuNgIYIAJBiO8ANgIUIAJBxyY2AhBBqMICKAIAIgNBpeMAIAJBEGoQMAwBCyACQfAvNgIIIAJBge8ANgIEIAJBxyY2AgBBqMICKAIAIgNBpeMAIAIQMAsgAxAzGgwFC0F+Rg0AIAFBFEEAIAAoAiAiAkEBRhtqKAKMASIDBEAgACADEKkBIAAoAiAhAgsgAUEQQQQgAkEBRhtqKAKMASIDBEAgACADEKkBIAAoAiAhAgsgAUEMQQggAkEBRhtqKAKMASIDBEAgACADEKkBIAAoAiAhAgsgAUEIQQwgAkEBRhtqKAKMASIDBEAgACADEKkBIAAoAiAhAgsgAUEUQQAgAUEEQRAgAkEBRhtqKAKMASIDBH8gACADEKkBIAAoAiAFIAILQQFHG2ooAowBIgIEQCAAIAIQqQELAkAgASgCQA0AIAEoAogBDQAgACgCCCICIAAoAgBODQIgAS0AxAFFBEAgBCACNgIAIAFB0yUgBBB0GiAAKAIIIQILIAAoAhQgAkECdGogATYCACAAIAJBAWo2AggMAQsgACgCBCICIAAoAgBODQIgAS0AxAFFBEAgBCACNgIgIAFB2yUgBEEgahB0GiAAKAIEIQILIAJBAnQiAyAAKAIMaiABNgIAIAAoAhAiBQRAIAMgBWogASgCiAE2AgALIAAgAkEBajYCBAsgBEHQAGokAA8LIARBox42AhggBEGA9wA2AhQgBEHHJjYCEEGowgIoAgAiAEGl4wAgBEEQahAwDAELIARBwh42AjggBEGJ9wA2AjQgBEHHJjYCMEGowgIoAgAiAEGl4wAgBEEwahAwCyAAEDMaC0GswgIoAgAQMxpBARAAAAsTACABQQF0QcCpA2pBAiAAEIEEC9EBAQF/An8jAEEwayIDJAACQCABKAKIAUUEQCAAIAEoAgAgASgCDCABQRBqQQBBABBKIgBFBEAgA0GSLzYCGCADQbAUNgIUIANBxyY2AhBBqMICKAIAIgBBpeMAIANBEGoQMAwCCyAAIAE2AowBIABBADYCiAEgAEETNgJAIAAgAjgCRCADQTBqJAAgAAwCCyADQf4gNgIoIANBvR42AiQgA0HHJjYCIEGowgIoAgAiAEGl4wAgA0EgahAwCyAAEDMaQazCAigCABAzGkEBEAAACwvwAgIDfwZ+An8jAEEwayIDJAACQAJ/AkACQCACKQMQIAEpAxBSDQAgASkDGCIGIAIpAxgiB4FCAFINACABKQMgIgggAikDICIJgUIAUg0AIAEpAygiCiACKQMoIguBQgBSDQAgAUEQaiEEAkAgASgCiAENACACKAKIAQ0ADAILAkAgBiAHUg0AIAggCVINAEEBIQUgCiALUQ0CCyADQb3WADYCGCADQbYaNgIUIANBxyY2AhBBqMICKAIAIgBBpeMAIANBEGoQMAwDCyADQZnXADYCKCADQbAaNgIkIANBxyY2AiBBqMICKAIAIgBBpeMAIANBIGoQMAwCCyAAIAEoAgAgASgCDCAEQQBBABBKIgRBBjYCQEEAIAVFDQAaIAAgBCgCACAEKAIMIARBEGpBAEEAEEoLIQAgBCABNgKMASAEIAA2AogBIAQgAjYCkAEgA0EwaiQAIAQMAQsgABAzGkGswgIoAgAQMxpBARAAAAsLdgEBfyMAQRBrIgIkACACIAA2AgwCQCAAIAFGDQADQCACIAFBAWsiATYCCCAAIAFPDQEgAigCDCIALQAAIQEgACACKAIIIgAtAAA6AAAgACABOgAAIAIgAigCDEEBaiIANgIMIAIoAgghAQwACwALIAJBEGokAAvbCAEBf0EAQQH+HgLw1DRBAEoEQANAQQBBAf4lAvDUNBoQAxDXAUEAQQH+HgLw1DRBAEoNAAsLAkACQCAAQcC6A0YNACAAQfS6A0YEQEEBIQEMAQsgAEGouwNGBEBBAiEBDAELIABB3LsDRgRAQQMhAQwBCyAAQZC8A0YEQEEEIQEMAQsgAEHEvANGBEBBBSEBDAELIABB+LwDRgRAQQYhAQwBCyAAQay9A0YEQEEHIQEMAQsgAEHgvQNGBEBBCCEBDAELIABBlL4DRgRAQQkhAQwBCyAAQci+A0YEQEEKIQEMAQsgAEH8vgNGBEBBCyEBDAELIABBsL8DRgRAQQwhAQwBCyAAQeS/A0YEQEENIQEMAQsgAEGYwANGBEBBDiEBDAELIABBzMADRgRAQQ8hAQwBCyAAQYDBA0YEQEEQIQEMAQsgAEG0wQNGBEBBESEBDAELIABB6MEDRgRAQRIhAQwBCyAAQZzCA0YEQEETIQEMAQsgAEHQwgNGBEBBFCEBDAELIABBhMMDRgRAQRUhAQwBCyAAQbjDA0YEQEEWIQEMAQsgAEHswwNGBEBBFyEBDAELIABBoMQDRgRAQRghAQwBCyAAQdTEA0YEQEEZIQEMAQsgAEGIxQNGBEBBGiEBDAELIABBvMUDRgRAQRshAQwBCyAAQfDFA0YEQEEcIQEMAQsgAEGkxgNGBEBBHSEBDAELIABB2MYDRgRAQR4hAQwBCyAAQYzHA0YEQEEfIQEMAQsgAEHAxwNGBEBBICEBDAELIABB9McDRgRAQSEhAQwBCyAAQajIA0YEQEEiIQEMAQsgAEHcyANGBEBBIyEBDAELIABBkMkDRgRAQSQhAQwBCyAAQcTJA0YEQEElIQEMAQsgAEH4yQNGBEBBJiEBDAELIABBrMoDRgRAQSchAQwBCyAAQeDKA0YEQEEoIQEMAQsgAEGUywNGBEBBKSEBDAELIABByMsDRgRAQSohAQwBCyAAQfzLA0YEQEErIQEMAQsgAEGwzANGBEBBLCEBDAELIABB5MwDRgRAQS0hAQwBCyAAQZjNA0YEQEEuIQEMAQsgAEHMzQNGBEBBLyEBDAELIABBgM4DRgRAQTAhAQwBCyAAQbTOA0YEQEExIQEMAQsgAEHozgNGBEBBMiEBDAELIABBnM8DRgRAQTMhAQwBCyAAQdDPA0YEQEE0IQEMAQsgAEGE0ANGBEBBNSEBDAELIABBuNADRgRAQTYhAQwBCyAAQezQA0YEQEE3IQEMAQsgAEGg0QNGBEBBOCEBDAELIABB1NEDRgRAQTkhAQwBCyAAQYjSA0YEQEE6IQEMAQsgAEG80gNGBEBBOyEBDAELIABB8NIDRgRAQTwhAQwBCyAAQaTTA0YEQEE9IQEMAQsgAEHY0wNGBEBBPiEBDAELIABBjNQDRw0BQT8hAQsgAUE0bEG8ugNqQQA6AAAgAC0ACEUNACAAKAIEEC8LQQBBAf4lAvDUNBoL2wECAX8CfkEBIQQCQCAAQgBSIAFC////////////AIMiBUKAgICAgIDA//8AViAFQoCAgICAgMD//wBRGw0AIAJCAFIgA0L///////////8AgyIGQoCAgICAgMD//wBWIAZCgICAgICAwP//AFEbDQAgACAChCAFIAaEhFAEQEEADwsgASADg0IAWQRAQX8hBCAAIAJUIAEgA1MgASADURsNASAAIAKFIAEgA4WEQgBSDwtBfyEEIAAgAlYgASADVSABIANRGw0AIAAgAoUgASADhYRCAFIhBAsgBAtQAQF+AkAgA0HAAHEEQCACIANBQGqtiCEBQgAhAgwBCyADRQ0AIAJBwAAgA2uthiABIAOtIgSIhCEBIAIgBIghAgsgACABNwMAIAAgAjcDCAupAQEDfyMAQaABayIEJAAgBCAAIARBngFqIAEbIgU2ApQBQX8hACAEIAFBAWsiBkEAIAEgBk8bNgKYASAEQQBBkAH8CwAgBEF/NgJMIARBzgE2AiQgBEF/NgJQIAQgBEGfAWo2AiwgBCAEQZQBajYCVAJAIAFBAEgEQCMDQRxqQT02AgAMAQsgBUEAOgAAIAQgAiADQcwBQc0BEMQCIQALIARBoAFqJAAgAAuoAQACQCABQYAITgRAIABEAAAAAAAA4H+iIQAgAUH/D0kEQCABQf8HayEBDAILIABEAAAAAAAA4H+iIQBB/RcgASABQf0XThtB/g9rIQEMAQsgAUGBeEoNACAARAAAAAAAAGADoiEAIAFBuHBLBEAgAUHJB2ohAQwBCyAARAAAAAAAAGADoiEAQfBoIAEgAUHwaEwbQZIPaiEBCyAAIAFB/wdqrUI0hr+iCzABAX8gASMDIgIoAkggAEECdGoiACgCAEcEQCAAIAE2AgAgAiACLQAqQQFyOgAqCwtlAQF/AkAgAEUNACABQQBIDQAgAEEDcQ0AIAFFBEAPCyAAQQAgAEEA/kgC4O80IgIgACACRhshAgJAIAFB/////wdGDQAgACACRw0AIAFBAkkNASABQQFrIQELIAAgAf4AAgAaCwuHAgECfyMAQRBrIgYkACAAIAI2AgQgAEHUrwE2AgAgAEEIaiICIAEoAgAiBzYCACAHQQRqQQH+HgIAGiAAIAEpAgQ3AgwgAEEUakEAQcQA/AsAIAAgBToAWiAAIAQ6AFkgACADOgBYIAYgAigCACIBNgIAIAFBBGpBAf4eAgAaIAZBBGoiAyAGIgIoAgBBmAFqEOcBQQEhASAGKAIIIAYtAA8iBCAEwCIEQQBIIgUbQQFGBEAgBigCBCADIAUbLQAAQcMARyEBCyAEQQBIBEAgBigCBBAvCyACKAIAIgJBBGpBf/4eAgBFBEAgAiACKAIAKAIIEQAACyAAIAE6AFsgBkEQaiQAIAALHwBBCBBgIAAQigMiAEHAtgM2AgAgAEHgtgNBBxACAAuLBAEHfyMAQSBrIgMkACAAKAIAIgZFBEAgACgCFCEIIAMgACkCBDcDGCAIIANBGGogARBYQQJ0aigCACEGCwJAIAEoAsABDQAgASgCuAEEQCAAIAEQkAEMAQsCQAJAIAEoAkBBAmsOOAAAAQAAAAAAAAEBAQEBAQEBAQABAQEBAAEBAQEBAQEBAQEAAAABAAEBAQEBAQEBAQEBAQEBAQEAAQsDQCABIAdBAnRqKAKMASICRQ0BAkAgAigCCCAGKAIARw0AIAMgACkCBDcDECADQRBqIAIQWCEFIAIoAsABRQ0AIAAoAgwgBUEDdGoiBCgCAEEBRw0AIAQoAgQNACABKAIAIAIoAgBHDQAgASkDECACKQMQUg0AIAEoAjAgAigCMEcNACABKQMYIAIpAxhSDQAgASgCNCACKAI0Rw0AIAEpAyAgAikDIFINACABKAI4IAIoAjhHDQAgASkDKCACKQMoUg0AIAEoAjwgAigCPEcNACACKAK4ASIFBEAgAyAAKQIENwMIIANBCGogBRBYIQQgACgCDCAEQQN0aiIEKAIEQQFHDQEgBCgCAA0BIAUoAsABIAIoAsABRw0BIAEgBTYCuAEgBEECNgIEIAAgARCQAQwECyABIAI2ArgBIARBATYCBCAAIAEQkAEMAwsgB0EBaiIHQQZHDQALCyAGIAEQ6QQLIANBIGokAAsQACAAKAIABEAQmgIACyAACxkAIAEgAhCdAyEBIAAgAjYCBCAAIAE2AgALhgIBBH8jAEEQayIFJAAgARCTAyECIwBBEGsiAyQAAkAgAkHv////A00EQAJAIAJBAkkEQCAAIAAtAAtBgAFxIAJyOgALIAAgAC0AC0H/AHE6AAsgACEEDAELIANBCGogACACQQJPBH8gAkEEakF8cSIEIARBAWsiBCAEQQJGGwVBAQtBAWoQuQEgAygCDBogACADKAIIIgQ2AgAgACAAKAIIQYCAgIB4cSADKAIMQf////8HcXI2AgggACAAKAIIQYCAgIB4cjYCCCAAIAI2AgQLIAQgASACEJ4BIANBADYCBCAEIAJBAnRqIAMoAgQ2AgAgA0EQaiQADAELEE0ACyAFQRBqJAAL5AEBBn8jAEEQayIFJAAgACgCBCEDAn8gAigCACAAKAIAayIEQf////8HSQRAIARBAXQMAQtBfwsiBEEEIAQbIQQgASgCACEHIAAoAgAhCCADQfYBRgR/QQAFIAAoAgALIAQQxAEiBgRAIANB9gFHBEAgACgCABogAEEANgIACyAFQfUBNgIEIAAgBUEIaiAGIAVBBGoQUSIDEL4DIAMoAgAhBiADQQA2AgAgBgRAIAYgAygCBBEAAAsgASAAKAIAIAcgCGtqNgIAIAIgACgCACAEQXxxajYCACAFQRBqJAAPCxBHAAs7AQJ/IwBBIGsiBSQAIAUgBDcDECAFIAM3AwggBSACNwMAIAAgAUEDIAVBAEEAEEohBiAFQSBqJAAgBguODAIGfwJ9IwBBQGoiAyQAQQBBAf4eAvDUNEEASgRAA0BBAEEB/iUC8NQ0GhADENcBQQBBAf4eAvDUNEEASg0ACwtB5NQELQAARQRAIANBMGoQ2AEDQCACQQJ0QfDUBGogAkH//wFxQYCAgPgDcr5DAAAAv5IgAkERdCIBQQR2QYCAgIAHcr5DAACAB5QgAUGAgIDAAEkbvCACQRB0QYCAgIB4cXIiBDYCACACQQF0IgFB8NQUakGA/AEgBL4iB0MAAAA/lCAHQypCTD+UIAdDEyc3PZQgB5RDAACAP5KUEI0EQwAAgD+SlCIIi0MAAIB3lEMAAIAIlEGAgICIByAIvCIEQQF0IgVBgICAeHEiBiAGQYCAgIgHTRtBAXZBgICAPGq+krwiBkENdkGA+AFxIAZB/x9xaiAFQYCAgHhLGyAEQRB2QYCAAnFyOwEAIAFB8NQcakGA/AFDAACAPyAHQyPb2b+UEEVDAACAP5KVIAeUIgiLQwAAgHeUQwAAgAiUQYCAgIgHIAi8IgRBAXQiBUGAgIB4cSIGIAZBgICAiAdNG0EBdkGAgIA8ar6SvCIGQQ12QYD4AXEgBkH/H3FqIAVBgICAeEsbIARBEHZBgIACcXI7AQAgAUHw1CRqQYD8ASAHIAeMEEVDAACAP5KVIgiLQwAAgHeUQwAAgAiUQYCAgIgHIAi8IgRBAXQiBUGAgIB4cSIGIAZBgICAiAdNG0EBdkGAgIA8ar6SvCIGQQ12QYD4AXEgBkH/H3FqIAVBgICAeEsbIARBEHZBgIACcXI7AQAgAUHw1CxqQYD8ASAHEEUiB0MAAIB3lEMAAIAIlEGAgICIByAHvCIBQQF0IgRBgICAeHEiBSAFQYCAgIgHTRtBAXZBgICAPGq+krwiBUENdkGA+AFxIAVB/x9xaiAEQYCAgHhLGyABQRB2QYCAAnFyOwEAIAJBAWoiAkGAgARHDQALIANBMGoiARDYASABENgBQby6A0EAQaiaAfwLACABENgBQcLVNEEBOgAAQbTVNEEBOgAAQa7VNEEBOgAAQazVNEEBOgAAQaTVNEGBAjsBAEGi1TRBAToAAEGa1TRBAToAAEGX1TRBgQI7AABBhNU0QQE6AABBuNU0QQE6AABBktY0QQE6AABB5NQEQQE6AAALQQAhAgJAAkACQAJAAkADQCACQTRsQby6A2oiAS0AAEUEQCACIQQMAgsgAkEBciIEQTRsQby6A2oiAS0AAEUNASACQQJyIgRBNGxBvLoDaiIBLQAARQ0BIAJBA3IiBEE0bEG8ugNqIgEtAABFDQEgAkEEaiICQcAARw0AC0EAIQIMAQsgAUEBOgAAIARBNGxBwLoDaiECIAAoAgAiAUUEQCAAQQQ2AgBBBCEBCyABIAFBA2pBfHEiBSAAKAIEIgQbIQYCQCAEIgENACAFRQRAQQAhAUHUuQMoAgBBAE4EQEGIuQMQgAEhAQsCQEGR3wBBiLkDEKsEQQBIDQACQEHYuQMoAgBBCkYNAEGcuQMoAgAiBUGYuQMoAgBGDQBBnLkDIAVBAWo2AgAgBUEKOgAADAELENICCyABBEBBiLkDEH8LQQAhAQwBCyADQQA2AjAgA0EwakEEIAUQgwQiAQRAIAMCfyABQTBHBEBB+RMgAUEcRw0BGkGHHwwBC0HNCAs2AiQgA0HjJTYCICADIAW4RAAAAAAAALA+ojkDKEHd9wAgA0EgahCiBEEAIQEMAQsgAygCMCEBCyACIAAtAAgiADoACiACIAA6AAkgAiAERToACCACIAE2AgQgAiAGNgIAIAL9DAAAAAAAAAAAAAAAAAAAAAD9CwALIAL9DAAAAAAAAAAAAAAAAAAAAAD9CwAbIAJCADcAKCABRQ0BIAFBA3ENAgtBAEEB/iUC8NQ0GiADQUBrJAAgAg8LIANBoS82AgggA0HpETYCBCADQccmNgIAQajCAigCACIAQaXjACADEDAMAQsgA0H7wAA2AhggA0HrETYCFCADQccmNgIQQajCAigCACIAQaXjACADQRBqEDALIAAQMxpBrMICKAIAEDMaQQEQAAALkAMBAn8jAEEQayIKJAAgCiAANgIMAkACQAJAIAMoAgAgAkcNAEErIQsgACAJKAJgRwRAQS0hCyAJKAJkIABHDQELIAMgAkEBajYCACACIAs6AAAMAQsCQAJ/IAYtAAtBB3YEQCAGKAIEDAELIAYtAAtB/wBxC0UNACAAIAVHDQBBACEAIAgoAgAiASAHa0GfAUoNAiAEKAIAIQAgCCABQQRqNgIAIAEgADYCAAwBC0F/IQAgCSAJQegAaiAKQQxqELICIAlrIgZB3ABKDQEgBkECdSEFAkACQAJAIAFBCGsOAwACAAELIAEgBUoNAQwDCyABQRBHDQAgBkHYAEgNACADKAIAIgEgAkYNAiABIAJrQQJKDQIgAUEBay0AAEEwRw0CQQAhACAEQQA2AgAgAyABQQFqNgIAIAEgBUHA6QJqLQAAOgAADAILIAMgAygCACIAQQFqNgIAIAAgBUHA6QJqLQAAOgAAIAQgBCgCAEEBajYCAEEAIQAMAQtBACEAIARBADYCAAsgCkEQaiQAIAALCgAgAEGsiTUQeQuMAwEDfyMAQRBrIgokACAKIAA6AA8CQAJAAkAgAygCACACRw0AQSshCyAAQf8BcSIMIAktABhHBEBBLSELIAktABkgDEcNAQsgAyACQQFqNgIAIAIgCzoAAAwBCwJAAn8gBi0AC0EHdgRAIAYoAgQMAQsgBi0AC0H/AHELRQ0AIAAgBUcNAEEAIQAgCCgCACIBIAdrQZ8BSg0CIAQoAgAhACAIIAFBBGo2AgAgASAANgIADAELQX8hACAJIAlBGmogCkEPahC1AiAJayIFQRdKDQECQAJAAkAgAUEIaw4DAAIAAQsgASAFSg0BDAMLIAFBEEcNACAFQRZIDQAgAygCACIBIAJGDQIgASACa0ECSg0CIAFBAWstAABBMEcNAkEAIQAgBEEANgIAIAMgAUEBajYCACABIAVBwOkCai0AADoAAAwCCyADIAMoAgAiAEEBajYCACAAIAVBwOkCai0AADoAACAEIAQoAgBBAWo2AgBBACEADAELQQAhACAEQQA2AgALIApBEGokACAACwoAIABBpIk1EHkLYwIBfwF+IwBBEGsiAiQAIAACfiABRQRAQgAMAQsgAiABrUIAIAFnIgFB0QBqEGcgAikDCEKAgICAgIDAAIVBnoABIAFrrUIwhnwhAyACKQMACzcDACAAIAM3AwggAkEQaiQACxkAIAEgAhDzAyEBIAAgAjYCBCAAIAE2AgALuQgBC38gAEUEQCABEDsPCyABQUBPBEAjA0EcakEwNgIAQQAPCwJAQYyGNS0AAEECcQRAQZCGNRBWDQELAn9BECABQQtqQXhxIAFBC0kbIQUgAEEIayIEKAIEIghBeHEhAgJAIAhBA3FFBEBBACAFQYACSQ0CGiAFQQRqIAJNBEAgBCEDIAIgBWtBwII1KAIAQQF0TQ0CC0EADAILIAIgBGohBgJAIAIgBU8EQCACIAVrIgNBEEkNASAEIAhBAXEgBXJBAnI2AgQgBCAFaiICIANBA3I2AgQgBiAGKAIEQQFyNgIEIAIgAxD0AQwBC0HogjUoAgAgBkYEQEHcgjUoAgAgAmoiAiAFTQ0CIAQgCEEBcSAFckECcjYCBCAEIAVqIgMgAiAFayICQQFyNgIEQdyCNSACNgIAQeiCNSADNgIADAELQeSCNSgCACAGRgRAQdiCNSgCACACaiICIAVJDQICQCACIAVrIgNBEE8EQCAEIAhBAXEgBXJBAnI2AgQgBCAFaiIHIANBAXI2AgQgAiAEaiICIAM2AgAgAiACKAIEQX5xNgIEDAELIAQgCEEBcSACckECcjYCBCACIARqIgMgAygCBEEBcjYCBEEAIQMLQeSCNSAHNgIAQdiCNSADNgIADAELIAYoAgQiB0ECcQ0BIAdBeHEgAmoiCSAFSQ0BIAkgBWshCwJAIAdB/wFNBEAgBigCDCIDIAYoAggiAkYEQEHQgjVB0II1KAIAQX4gB0EDdndxNgIADAILIAIgAzYCDCADIAI2AggMAQsgBigCGCEKAkAgBiAGKAIMIgJHBEBB4II1KAIAGiAGKAIIIgMgAjYCDCACIAM2AggMAQsCQCAGQRRqIgMoAgAiB0UEQCAGKAIQIgdFDQEgBkEQaiEDCwNAIAMhDCAHIgJBFGoiAygCACIHDQAgAkEQaiEDIAIoAhAiBw0ACyAMQQA2AgAMAQtBACECCyAKRQ0AAkAgBigCHCIDQQJ0QYCFNWoiBygCACAGRgRAIAcgAjYCACACDQFB1II1QdSCNSgCAEF+IAN3cTYCAAwCCyAKQRBBFCAKKAIQIAZGG2ogAjYCACACRQ0BCyACIAo2AhggBigCECIDBEAgAiADNgIQIAMgAjYCGAsgBigCFCIDRQ0AIAIgAzYCFCADIAI2AhgLIAtBD00EQCAEIAhBAXEgCXJBAnI2AgQgBCAJaiIDIAMoAgRBAXI2AgQMAQsgBCAIQQFxIAVyQQJyNgIEIAQgBWoiAyALQQNyNgIEIAQgCWoiAiACKAIEQQFyNgIEIAMgCxD0AQsgBCEDCyADCyEDQYyGNS0AAEECcQRAQZCGNRBSGgsgAwRAIANBCGoPCyABEDsiA0UEQEEADwsgAyAAQXxBeCAAQQRrKAIAIgRBA3EbIARBeHFqIgQgASABIARLGxB6GiAAEC8LIAMLXwECfyAAQQdqQXhxIQICQANAIAJBAEGcugP+EAIAIgAgAmoiASAATRsNASABPwBBEHRLBEAgARAeRQ0CC0EAIAAgAf5IApy6AyAARw0ACyAADwsjA0EcakEwNgIAQX8LgwECBX8BfgJAIABCgICAgBBUBEAgACEHDAELA0AgAUEBayIBIAAgAEIKgCIHQgp+fadBMHI6AAAgAEL/////nwFWIQUgByEAIAUNAAsLIAenIgIEQANAIAFBAWsiASACIAJBCm4iA0EKbGtBMHI6AAAgAkEJSyEGIAMhAiAGDQALCyABCxoAIAAgARCOBCIAQQAgAC0AACABQf8BcUYbC88FAQh/IwBBEGsiBSQAIAACfyAFQQhqIQMgASEGAkACQEGY1jQiBEGY1jRHBEAgASgCACIHQajWNCgCACIBTg0BC0GY1jQoAgAhBEGY1jQhAwJAQZTWNCgCAEGY1jRHBEACQCAERQRAQZjWNCEBA0AgASgCCCIDKAIAIAFGIQkgAyEBIAkNAAsMAQsgBCEBA0AgASIDKAIEIgENAAsLIAYoAgAiBiADKAIQTA0BCyAERQ0CIAUgAzYCDCADQQRqDAMLQZjWNCgCACIBRQ0BQZjWNCEEA0ACQCABIgMoAhAiASAGSgRAIAMiBCgCACIBDQIMAQsgASAGTg0AIANBBGohBCADKAIEIgENAQsLIAUgAzYCDCAEDAILIAEgB0gEQAJAQZzWNCgCACIGRQRAQZjWNCEBA0AgASgCCCIDKAIAIAFHIQogAyEBIAoNAAsMAQsgBiEBA0AgASIDKAIAIgENAAsLAkAgA0GY1jRHBEAgByADKAIQTg0BCyAGRQRAIAVBmNY0NgIMQZzWNAwECyAFIAM2AgwgAwwDC0GY1jQoAgAiAUUNAQNAAkAgASIDKAIQIgEgB0oEQCADIgQoAgAiAQ0CDAELIAEgB04NACADQQRqIQQgAygCBCIBDQELCyAFIAM2AgwgBAwCCyAFQZjWNDYCDCADQZjWNDYCACADDAELIAVBmNY0NgIMQZjWNAsiBCgCACIBBH9BAAVBIBAxIgEgAigCADYCECABQRRqIQMCQCACLAAPQQBOBEAgAyACKQIENwIAIAMgAigCDDYCCAwBCyADIAIoAgQgAigCCBBsCyABIAUoAgw2AgggAUIANwIAIAQgATYCACABIQJBlNY0KAIAKAIAIgMEQEGU1jQgAzYCACAEKAIAIQILQZjWNCgCACACEKQBQZzWNEGc1jQoAgBBAWo2AgBBAQs6AAQgACABNgIAIAVBEGokAAuIAQEDf0GcEBA7IQEgABDoBCEDIAEgACgCFCICIAIoAgwRAQAiAjYCDCABIAM2AgggAUEANgIEIAEgADYCACABQRxqQQBBgBD8CwAgAUEBNgIQIAEgAyACIAMgAnBrIAJwIgJqNgIUIAEgACgCHCACazYCGEEIEDsiABCCBDYCBCAAIAE2AgAgAAvfBwEKfyMAQSBrIggkACAAKAIAIgNFBEAgACgCFCEKIAggACkCBDcDGCAKIAhBGGogARBYQQJ0aigCACEDCwJAAkAgAygCACIAIAEoAghHDQAgASgCwAEhBSAAIAEQ5wQhACADKAIMIgIgACACcGsgAnAhAiADLQCYEEUEQCADKAIAIgYoAhAiBARAIAYgASAEEQIACwsgACACaiEGAkAgAygCECIAQQBMBEBBACEBDAELIAUgBmohCUEAIQEDQCAFIAMgAUEDdGoiAigCFCIEIAIoAhgiB2pGBEAgAiAGIAdqIgc2AhggASAAQQFrIgZODQMgAyABQQFqIgVBA3RqIgkoAhQgBCAHakcNAyACIAkoAhggB2o2AhggAyAGNgIQIAUgBk4NAwJAIAAgAWtBAmsiAkECSQRAIAUhAQwBCyAFIAJBfnEiBGohAUEAIQADQCADIAAgBWpBA3RqIgcgB/0AAhz9CwIUIABBAmoiACAERw0ACyACIARGDQQLIANBFGohAANAIAAgAUEDdGogACABQQFqIgFBA3RqKQIANwIAIAEgBkcNAAsMAwsgBCAJRgRAIAIgBTYCFCACIAYgB2oiBjYCGCABRQ0DIAUgAUEDdCADaiICKAIMIAIoAhAiBGpHDQMgAiAEIAZqNgIQIAMgAEEBayIFNgIQIAEgBU4NAwJAIAUgAWsiBkECSQRAIAEhAAwBCyABIAZBfnEiBGohAEEAIQIDQCADIAEgAmpBA3RqIgcgB/0AAhz9CwIUIAJBAmoiAiAERw0ACyAEIAZGDQQLIANBFGohAQNAIAEgAEEDdGogASAAQQFqIgBBA3RqKQIANwIAIAAgBUcNAAsMAwsgAUEBaiIBIABHDQALIABBgAJODQJBACEBAkADQCADIAFBA3RqKAIUIAVPDQEgAUEBaiIBIABHDQALIAAhAQwBCyAAIAFMDQAgACABQX9zaiELIAAgAWtBA3EiCQRAQQAhAiADQRRqIQQDQCAEIABBA3RqIAQgAEEBayIAQQN0aikCADcCACACQQFqIgIgCUcNAAsLIAtBAksEQCADQRRqIQQDQCAEIABBA3RqIgIgAkEIaykCADcCACACQRBrIAJBGGsiAv0AAgD9CwIAIAIgBCAAQQRrIgBBA3RqKQIANwIAIAAgAUoNAAsLIAMoAhAhAAsgAyABQQN0aiIBIAY2AhggASAFNgIUIAMgAEEBajYCEAsgCEEgaiQADwsgCEH52wA2AgggCEHTATYCBCAIQb0nNgIAQajCAigCACIAQaXjACAIEDAgABAzGkGswgIoAgAQMxpBARAAAAuaywcFO37VAX8TfSB7BHwjAEFAaiKEASQAAkACQAJAAkACQAJAAkACQAJAAkACQCAABEACQCABKAJAIj1FDQACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQCA9QQFrDkQ/AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaQEBAQBscHR4fICEiIyQlJicoKSorLC0uLzAyMzE0NTY3ODk6Ozw9PkALIAEoAowBIVYgASgCkAEhXSMAQYADayJUJAACQAJAIFYoAgAiPUEOSw0AAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkBBASA9dEHM+wFxRQRAAkACQAJAID0EQCA9QQFHDRggXSgCAA4CAgEDCyBdKQMQIg8gVikDEFINBSBWKQMYIg4gXSkDGCILgUIAUg0FIFYpAyAiAyBdKQMgIgeBQgBSDQUgVikDKCICIF0pAygiCYFCAFINBSAPIAEpAxBSDQUgDiABKQMYUg0FIAMgASkDIFINBSACIAEpAyhSDQUCQCAAKAIADgMFAAUACyABKAIwQQRHDQYgVigCMEEERw0HIAEoAjwhWCABKAI4IVogASgCNCFNIF0oAjwhWyBdKAI4IVIgXSgCNCFOIFYoAjwhTCBWKAI4IUkgVigCNCFRIAIgAyAOfiIMfqciPiAAKAIIIj1qQQFrID1tIj0gACgCBGwiPyA9aiIAID4gACA+SBshPSBdKAIwIllBBEcEQCA9ID9MDQUgD0IAVw0FIFlBAUYgD0ITVnEhSiAPQgGDIQYgD0J8gyEEIA+nIgAgXSgCwAEiS2pBA2ohRyBWKALAASJGIABBAnQiAGohSCABKALAASJFIABqIUEgPawhBSA/rCEUA0AgRiBMIBQgDH8iCKciPWwiRGogSSAUIAggDH59IgIgDn8iA6ciAWwiQ2ogUSACIAMgDn59IgKnIgBsIkJqIVMgACBNbCJAIAEgWmwiPyBFID0gWGwiAGpqaiFXIE4gAiALgadsIj4gUiADIAeBp2wiPSBLIFsgCCAJgadsIgFqamohUEIAIQICQAJAIEpFDQAgVyBIIEIgQ2ogRGpqSSBTIEEgPyBAaiAAamoiAElxDQAgVyBHID0gPmogAWpqSSAAIFBLcQ0A/QwAAAAAAQAAAAIAAAADAAAAIaYCA0AgVyACp0ECdCIAaiAAIFNq/QACACBQIKYC/RsAav0JAgAgUCCmAv0bAWoqAgD9IAEgUCCmAv0bAmoqAgD9IAIgUCCmAv0bA2oqAgD9IAP95AH9CwIAIKYC/QwEAAAABAAAAAQAAAAEAAAA/a4BIaYCIAJCBHwiAiAEUg0ACyAEIgIgD1ENAQsgAkIBhCEDIAanBEAgVyACpyIBQQJ0IgBqIAAgU2oqAgAgUCABIFlsaioCAJI4AgAgAyECCyADIA9RDQADQCBXIAKnIgFBAnQiAGogACBTaioCACBQIAEgWWxqKgIAkjgCACBXIAFBAWoiAUECdCIAaiAAIFNqKgIAIFAgASBZbGoqAgCSOAIAIAJCAnwiAiAPUg0ACwsgFEIBfCIUIAVSDQALDAULID0gP0wNBCAPpyJTQQBMDQQgXSgCwAEhRiBWKALAASFLIAEoAsABIUdBACBTayFIIFNBAXEhRSBTQXxxIQEgPawhBCA/rCECIFNBEEkhQQNAIEsgTCACIAx/IganIkRsIkNqIEkgAiAGIAx+fSIDIA5/IgWnIj1sIkJqIFEgAyAFIA5+fSIDpyIAbCJAaiFKIAAgTWwiPyA9IFpsIj4gRyBEIFhsIj1qamohRCBGIFsgBiAJgadsaiBSIAUgB4GnbGogTiADIAuBp2xqIVlBACEAAkACQCBBDQAgPyBHaiA9aiA+aiI9IEAgS2ogQ2ogQmprQRBJDQAgPSBZa0EQSQ0AA0AgRCAAQQJ0Ij1qID0gSmr9AAIAID0gWWr9AAIA/eQB/QsCACAAQQRqIgAgAUcNAAsgASIAIFNGDQELIABBf3Mh3QEgRQRAIEQgAEECdCI+aiA+IEpqKgIAID4gWWoqAgCSOAIAIABBAXIhAAsg3QEgSEYNAANAIEQgAEECdCI9aiA9IEpqKgIAID0gWWoqAgCSOAIAIEQgPUEEaiI9aiA9IEpqKgIAID0gWWoqAgCSOAIAIABBAmoiACBTRw0ACwsgAkIBfCICIARSDQALDAQLIFYpAxAiByBdKQMQUg0HIFYpAxgiCSBdKQMYUg0HIFYpAyAiAyBdKQMgUg0HIFYpAygiAiBdKQMoUg0HIAcgASkDEFINByAJIAEpAxhSDQcgAyABKQMgUg0HIAIgASkDKFINBwJAIAAoAgAOAwQABAALIAEoAgBBAUcNCCABKAIwQQJHDQkgVigCMEECRw0KIAIgAyAJfiIIfqciPyAAKAIIIj1qQQFrID1tIT4gXSgCMEECRgRAID4gACgCBGwiPSA9ID5qIgAgPyAAID9IGyIATg0EIAdCAFcNBCABKAI8IUkgASgCOCFRIAEoAjQhSiBdKAI8IUsgXSgCOCFHIF0oAjQhRiBWKAI8IUggVigCOCFFIFYoAjQhQSBdKALAASFaIFYoAsABIU0gASgCwAEhWyAHQnyDIQMgAKwhBiA9rCEEA0AgWiBLIAQgCH8iAqciTGwiRGogRyAEIALEIAh+fSIFIAl/IgKnIgFsIkNqIEYgBSACIAl+faciAGwiQmohUiAAIEFsIkAgASBFbCI/IE0gSCBMbCI+ampqIU4gACBKbCI9IAEgUWwiASBbIEkgTGwiAGpqaiFMQgAhAgJAAkAgB0IEVA0AID0gW2ogAGogAWoiACBAIE1qID5qID9qa0EISQ0AIAAgQiBaaiBEaiBDamtBCEkNAANAIEwgAqdBAXQiAGr9DAB+AAAAfgAAAH4AAAB+AAAgACBOav0EAQAipQL9GwBBAnRB8NQEav0JAgAgpQL9GwFBAnRB8NQEaioCAP0gASClAv0bAkECdEHw1ARqKgIA/SACIKUC/RsDQQJ0QfDUBGoqAgD9IAMgACBSav0EAQAipQL9GwBBAnRB8NQEav0JAgAgpQL9GwFBAnRB8NQEaioCAP0gASClAv0bAkECdEHw1ARqKgIA/SACIKUC/RsDQQJ0QfDUBGoqAgD9IAP95AEipwL94AH9DAAAgHcAAIB3AACAdwAAgHf95gH9DAAAgAgAAIAIAACACAAAgAj95gEgpwJBAf2rASKoAv0MAAAA/wAAAP8AAAD/AAAA//1O/QwAAABxAAAAcQAAAHEAAABx/bkBQQH9rQH9DAAAgAcAAIAHAACABwAAgAf9rgH95AEipQJBDf2tAf0MAHwAAAB8AAAAfAAAAHwAAP1OIKUC/Qz/DwAA/w8AAP8PAAD/DwAA/U79rgEgqAL9DAAAAP8AAAD/AAAA/wAAAP/9PP1SIKcCQRD9rQH9DACAAAAAgAAAAIAAAACAAAD9Tv1QIKcC/Q0AAQQFCAkMDQABAAEAAQAB/VsBAAAgAkIEfCICIANSDQALIAMiAiAHUQ0BCwNAIEwgAqdBAXQiAGpBgPwBIAAgTmovAQBBAnRB8NQEaioCACAAIFJqLwEAQQJ0QfDUBGoqAgCSIpICi0MAAIB3lEMAAIAIlEGAgICIByCSArwiPUEBdCIBQYCAgHhxIgAgAEGAgICIB00bQQF2QYCAgDxqvpK8IgBBDXZBgPgBcSAAQf8fcWogAUGAgIB4SxsgPUEQdkGAgAJxcjsBACACQgF8IgIgB1INAAsLIARCAXwiBCAGUg0ACwwECyBUQf4gNgJYIFRB0jY2AlQgVEHHJjYCUEGowgIoAgAiAEGl4wAgVEHQAGoQMAxfCyBWKQMQIgsgXSkDEFINCiBWKQMYIgcgXSkDGFINCiBWKQMgIgMgXSkDIFINCiBWKQMoIgIgXSkDKFINCiALIAEpAxBSDQogByABKQMYUg0KIAMgASkDIFINCiACIAEpAyhSDQoCQCAAKAIADgMDAAMACyABKAI8IVIgASgCOCFOIAEoAjQhTCBdKAI8IUkgXSgCOCFRIF0oAjQhSiBWKAI8IUsgVigCOCFHIFYoAjQhRiABKAIwIUAgXSgCMCHfASBWKAIwId4BIAAoAgghQiAAKAIEIQACQAJAAkACQCABKAIAIj0OAgACAQsgQEEERg0CIFRBiNAANgLYASBUQek1NgLUASBUQccmNgLQAUGowgIoAgAiAEGl4wAgVEHQAWoQMAxhCyBUQek4NgKoASBUQew1NgKkASBUQccmNgKgAUGowgIoAgAiAEGl4wAgVEGgAWoQMAxgCyBAQQJHDQwLIN4BQQJHDQwgAiADIAd+Igl+pyJAIEJqQQFrIEJtIT4g3wFBBEYEQCA+IAAgPmwiQ2oiACBAIAAgQEgbIQAgPUEBRwRAIAAgQ0wNBCALQgBXDQQgXSgCwAEhPyBWKALAASE+IAEoAsABIT0gC0J+gyEIIAtCAYMhBiAArCEFIEOsIQMDQCA/IEkgAyAJfyICpyJAbGogUSADIALEIAl+fSIEIAd/IgKnIgFsaiBKIAQgAiAHfn2nIgBsaiFDID4gQCBLbGogASBHbGogACBGbGohQiA9IEAgUmxqIAEgTmxqIAAgTGxqIUBCACECQgAhBCALQgFSBEADQCBAIAKnIgFBAnQiAGogQiABQQF0ai8BAEECdEHw1ARqKgIAIAAgQ2oqAgCSOAIAIEAgAUEBciIBQQJ0IgBqIEIgAUEBdGovAQBBAnRB8NQEaioCACAAIENqKgIAkjgCACACQgJ8IQIgBEICfCIEIAhSDQALCyAGpwRAIEAgAqciAUECdCIAaiBCIAFBAXRqLwEAQQJ0QfDUBGoqAgAgACBDaioCAJI4AgALIANCAXwiAyAFUg0ACwwECyAAIENMDQMgC0IAVw0DIF0oAsABIUIgVigCwAEhSCABKALAASFFIAtCfIMhAyAArCEGIEOsIQQDQCBCIEkgBCAJfyICpyJDbGogUSAEIALEIAl+fSIFIAd/IgKnIgFsaiBKIAUgAiAHfn2nIgBsaiFBIAAgRmwiQCABIEdsIj8gSCBDIEtsIj5qamohRCAAIExsIj0gASBObCIBIEUgQyBSbCIAampqIUNCACECAkACQCALQgRUDQAgPSBFaiAAaiABaiBAIEhqID5qID9qa0EISQ0AA0AgQyACpyIBQQF0IgBq/QwAfgAAAH4AAAB+AAAAfgAAIAAgRGr9BAEAIqUC/RsAQQJ0QfDUBGr9CQIAIKUC/RsBQQJ0QfDUBGoqAgD9IAEgpQL9GwJBAnRB8NQEaioCAP0gAiClAv0bA0ECdEHw1ARqKgIA/SADIEEgAUECdGr9AAIA/eQBIqcC/eAB/QwAAIB3AACAdwAAgHcAAIB3/eYB/QwAAIAIAACACAAAgAgAAIAI/eYBIKcCQQH9qwEiqAL9DAAAAP8AAAD/AAAA/wAAAP/9Tv0MAAAAcQAAAHEAAABxAAAAcf25AUEB/a0B/QwAAIAHAACABwAAgAcAAIAH/a4B/eQBIqUCQQ39rQH9DAB8AAAAfAAAAHwAAAB8AAD9TiClAv0M/w8AAP8PAAD/DwAA/w8AAP1O/a4BIKgC/QwAAAD/AAAA/wAAAP8AAAD//Tz9UiCnAkEQ/a0B/QwAgAAAAIAAAACAAAAAgAAA/U79UCCnAv0NAAEEBQgJDA0AAQABAAEAAf1bAQAAIAJCBHwiAiADUg0ACyADIgIgC1ENAQsDQCBDIAKnIgFBAXQiAGpBgPwBIAAgRGovAQBBAnRB8NQEaioCACBBIAFBAnRqKgIAkiKSAotDAACAd5RDAACACJRBgICAiAcgkgK8Ij1BAXQiAUGAgIB4cSIAIABBgICAiAdNG0EBdkGAgIA8ar6SvCIAQQ12QYD4AXEgAEH/H3FqIAFBgICAeEsbID1BEHZBgIACcXI7AQAgAkIBfCICIAtSDQALCyAEQgF8IgQgBlINAAsMAwsgVEH+IDYCuAEgVEGcNjYCtAEgVEHHJjYCsAFBqMICKAIAIgBBpeMAIFRBsAFqEDAMXgsgVEH+IDYCSCBUQbc3NgJEIFRBxyY2AkBBqMICKAIAIgBBpeMAIFRBQGsQMAxdCyBWKQMQIgQgXSkDEFINCyBWKQMYIgggXSkDGFINCyBWKQMgIgMgXSkDIFINCyBWKQMoIgIgXSkDKFINCyAEIAEpAxBSDQsgCCABKQMYUg0LIAMgASkDIFINCyACIAEpAyhSDQsCQCAAKAIADgMBAAEACyBWKAIwID1BJGwiPkGYmgFqKAIARw0MIF0oAjBBBEcNDSABKAIwIkIgASgCNCJTSw0OIFMgASgCOCJZSw0PIFkgASgCPCJNSw0QQcz/AyA9dkEBcUUNESBdKAIADRIgAiADIAh+IgZ+pyI/IAAoAggiPWpBAWsgPW0iPSAAKAIEIkBsIkMgPSBDaiI9ID8gPSA/SBsiW04NACBdKAI8IVIgXSgCOCFOIF0oAjQhTCBWKAI8IUkgVigCOCFRIFYoAjQhSiA+QaCaAWooAgAhSyABKAIAIj9BJGxBpJoBaigCACFHIAAoAhAiPiBAIASnIl5BEGpsIgBBAnRqIVAgXkEDcSFYIF5BfHEhPSBeQQJ0IUYgQiBebCFIQbGAHCA/dkEBcSFFID4gACBeakECdGohQSBDrCECIF5BCEkhRANAIF0oAsABIVogASgCwAEhQyBWKALAASBRIAIgAiAGfyIFxCAGfn0iBCAIfyIDpyI/bCBJIAWnIj5saiBKIAQgAyAIfn2nIgBsamogUCBeIEsRBQAgPyBZbCA+IE1saiAAIFNsaiHhAQJAIF5BAEwNACBaIAAgTGwiQCA/IE5sIj8gPiBSbCI+ampqIVdBACGAAUEAIQACQCBEDQAgRiBaaiA+IEBqID9qaiBQSyBBIFdLcQ0AA0AgUCAAQQJ0Ij9qIj4gPyBXav0AAgAgPv0AAgD95AH9CwIAIABBBGoiACA9Rw0ACyA9IgAgXkYNAQsgAEF/cyBeaiHgASBYBEADQCBQIABBAnQiP2oiPiA/IFdqKgIAID4qAgCSOAIAIABBAWohACCAAUEBaiKAASBYRw0ACwsg4AFBA0kNAANAIFAgAEECdCJAaiI+IEAgV2oqAgAgPioCAJI4AgAgUCBAQQRqIj9qIj4gPyBXaioCACA+KgIAkjgCACBQIEBBCGoiP2oiPiA/IFdqKgIAID4qAgCSOAIAIFAgQEEMaiI/aiI+ID8gV2oqAgAgPioCAJI4AgAgAEEEaiIAIF5HDQALCyDhASBDaiEAAkAgRUUEQCBQIAAgXiBHEQUADAELIAAgUCBI/AoAAAsgWyACQgF8IgKnRw0ACwsgVEGAA2okAAwTCyBUQcDOADYCOCBUQY81NgI0IFRBxyY2AjBBqMICKAIAIgBBpeMAIFRBMGoQMAxaCyBUQYjQADYCKCBUQZw1NgIkIFRBxyY2AiBBqMICKAIAIgBBpeMAIFRBIGoQMAxZCyBUQeHQADYCGCBUQZ01NgIUIFRBxyY2AhBBqMICKAIAIgBBpeMAIFRBEGoQMAxYCyBUQf7NADYCmAEgVEGlNjYClAEgVEHHJjYCkAFBqMICKAIAIgBBpeMAIFRBkAFqEDAMVwsgVEHpODYCiAEgVEG0NjYChAEgVEHHJjYCgAFBqMICKAIAIgBBpeMAIFRBgAFqEDAMVgsgVEHu0QA2AnggVEG2NjYCdCBUQccmNgJwQajCAigCACIAQaXjACBUQfAAahAwDFULIFRBwtIANgJoIFRBtzY2AmQgVEHHJjYCYEGowgIoAgAiAEGl4wAgVEHgAGoQMAxUCyBUQf7NADYC+AEgVEHYNTYC9AEgVEHHJjYC8AFBqMICKAIAIgBBpeMAIFRB8AFqEDAMUwsgVEHu0QA2AugBIFRB7TU2AuQBIFRBxyY2AuABQajCAigCACIAQaXjACBUQeABahAwDFILIFRBwtIANgLIASBUQfA1NgLEASBUQccmNgLAAUGowgIoAgAiAEGl4wAgVEHAAWoQMAxRCyBUQf7NADYC+AIgVEHbNjYC9AIgVEHHJjYC8AJBqMICKAIAIgBBpeMAIFRB8AJqEDAMUAsgVEHp0wA2AugCIFRB7jY2AuQCIFRBxyY2AuACQajCAigCACIAQaXjACBUQeACahAwDE8LIFRBtNAANgLYAiBUQe82NgLUAiBUQccmNgLQAkGowgIoAgAiAEGl4wAgVEHQAmoQMAxOCyBUQaQ9NgKIAiBUQfI2NgKEAiBUQccmNgKAAkGowgIoAgAiAEGl4wAgVEGAAmoQMAxNCyBUQfI6NgKYAiBUQfM2NgKUAiBUQccmNgKQAkGowgIoAgAiAEGl4wAgVEGQAmoQMAxMCyBUQd05NgKoAiBUQfQ2NgKkAiBUQccmNgKgAkGowgIoAgAiAEGl4wAgVEGgAmoQMAxLCyBUQcvTADYCuAIgVEH2NjYCtAIgVEHHJjYCsAJBqMICKAIAIgBBpeMAIFRBsAJqEDAMSgsgVEH7OzYCyAIgVEH3NjYCxAIgVEHHJjYCwAJBqMICKAIAIgBBpeMAIFRBwAJqEDAMSQsgVEH+IDYCCCBUQck3NgIEIFRBxyY2AgBBqMICKAIAIgBBpeMAIFQQMAxICww/CyABKAKMASFOIAEoApABIUwjAEGQA2siTSQAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAIE4oAgAiPUEGa0EJSQ0AAkACQCA9DgQAAQICGwsgTikDECIEIAEpAxBSDQMgTikDGCIIIAEpAxhSDQMgTikDICIDIAEpAyBSDQMgTikDKCICIAEpAyhSDQMgTCkDEEIBUg0EIEwpAxhCAVINBCBMKQMgQgFSDQQgTCkDKEIBUg0EAkAgACgCAA4DAwADAAsgASgCMEEERw0FIE4oAjBBBEcNBiACIAMgCH4iBn6nIj8gACgCCCI9akEBayA9bSI9IAAoAgRsIj4gPSA+aiIAID8gACA/SBsiAE4NAiAEpyJbQQBMDQIgASgCPCFRIAEoAjghSiABKAI0IUsgTigCPCFHIE4oAjghRiBOKAI0IUggTCgCwAEhRSBOKALAASFOIAEoAsABIUwgW0EDcSFJIFtBfHEhASAArCEFID6sIQIgW0EMSSFBA0AgTiBHIAIgBn8iA6ciRGwiQ2ogRiACIAPEIAZ+fSIEIAh/IgOnIj1sIkJqIEggBCADIAh+faciAGwiQGohUiAAIEtsIj8gPSBKbCI+IEwgRCBRbCI9ampqIUQgRSoCACGSAkEAIV1BACEAAkACQCBBDQAgPyBMaiA9aiA+aiBAIE5qIENqIEJqa0EQSQ0AIJIC/RMhpQIDQCBEIABBAnQiPWogpQIgPSBSav0AAgD95AH9CwIAIABBBGoiACABRw0ACyABIgAgW0YNAQsgAEF/cyBbaiHiASBJBEADQCBEIABBAnQiPWogkgIgPSBSaioCAJI4AgAgAEEBaiEAIF1BAWoiXSBJRw0ACwsg4gFBA0kNAANAIEQgAEECdCI+aiCSAiA+IFJqKgIAkjgCACBEID5BBGoiPWogkgIgPSBSaioCAJI4AgAgRCA+QQhqIj1qIJICID0gUmoqAgCSOAIAIEQgPkEMaiI9aiCSAiA9IFJqKgIAkjgCACAAQQRqIgAgW0cNAAsLIAJCAXwiAiAFUg0ACwwCCwJAAkACQCBMKAIADgIBAAILIE4pAxAiByABKQMQUg0IIE4pAxgiCSABKQMYUg0IIE4pAyAiAyABKQMgUg0IIE4pAygiAiABKQMoUg0IIEwpAxBCAVINCSBMKQMYQgFSDQkgTCkDIEIBUg0JIEwpAyhCAVINCQJAIAAoAgAOAwQABAALIAEoAgBBAUcNCiABKAIwQQJHDQsgTigCMEECRw0MIAIgAyAJfiIIfqciPyAAKAIIIj1qQQFrID1tIj0gACgCBGwiPiA9ID5qIgAgPyAAID9IGyIATg0DIAdCAFcNAyABKAI8IUYgASgCOCFIIAEoAjQhRSBOKAI8IUEgTigCOCFEIE4oAjQhQyBOKALAASFKIAEoAsABIUsgB0J8gyEDIEwoAsABLwEAQQJ0QfDUBGoqAgAikwL9EyGnAiAArCEGID6sIQQDQCBKIEEgBCAIfyICpyJCbCJAaiBEIAQgAsQgCH59IgUgCX8iAqciAWwiP2ogQyAFIAIgCX59pyIAbCI+aiFHIAAgRWwiPSABIEhsIgEgSyBCIEZsIgBqamohQkIAIQICQAJAIAdCBFQNACA9IEtqIABqIAFqID4gSmogQGogP2prQQhJDQADQCBCIAKnQQF0IgBq/QwAfgAAAH4AAAB+AAAAfgAAIKcCIAAgR2r9BAEAIqUC/RsAQQJ0QfDUBGr9CQIAIKUC/RsBQQJ0QfDUBGoqAgD9IAEgpQL9GwJBAnRB8NQEaioCAP0gAiClAv0bA0ECdEHw1ARqKgIA/SAD/eQBIqYC/eAB/QwAAIB3AACAdwAAgHcAAIB3/eYB/QwAAIAIAACACAAAgAgAAIAI/eYBIKYCQQH9qwEiqAL9DAAAAP8AAAD/AAAA/wAAAP/9Tv0MAAAAcQAAAHEAAABxAAAAcf25AUEB/a0B/QwAAIAHAACABwAAgAcAAIAH/a4B/eQBIqUCQQ39rQH9DAB8AAAAfAAAAHwAAAB8AAD9TiClAv0M/w8AAP8PAAD/DwAA/w8AAP1O/a4BIKgC/QwAAAD/AAAA/wAAAP8AAAD//Tz9UiCmAkEQ/a0B/QwAgAAAAIAAAACAAAAAgAAA/U79UCCmAv0NAAEEBQgJDA0AAQABAAEAAf1bAQAAIAJCBHwiAiADUg0ACyADIgIgB1ENAQsDQCBCIAKnQQF0IgBqQYD8ASCTAiAAIEdqLwEAQQJ0QfDUBGoqAgCSIpICi0MAAIB3lEMAAIAIlEGAgICIByCSArwiPUEBdCIBQYCAgHhxIgAgAEGAgICIB00bQQF2QYCAgDxqvpK8IgBBDXZBgPgBcSAAQf8fcWogAUGAgIB4SxsgPUEQdkGAgAJxcjsBACACQgF8IgIgB1INAAsLIARCAXwiBCAGUg0ACwwDCyBOKQMQIgcgASkDEFINDCBOKQMYIgkgASkDGFINDCBOKQMgIgMgASkDIFINDCBOKQMoIgIgASkDKFINDCBMKQMQQgFSDQ0gTCkDGEIBUg0NIEwpAyBCAVINDSBMKQMoQgFSDQ0CQCAAKAIADgMDAAMACyABKAIAQQFHDQ4gASgCMEECRw0PIE4oAjBBAkcNECACIAMgCX4iCH6nIj8gACgCCCI9akEBayA9bSI9IAAoAgRsIj4gPSA+aiIAID8gACA/SBsiAE4NAiAHQgBXDQIgASgCPCFGIAEoAjghSCABKAI0IUUgTigCPCFBIE4oAjghRCBOKAI0IUMgTigCwAEhSiABKALAASFLIAdCfIMhAyBMKALAASoCACKTAv0TIacCIACsIQYgPqwhBANAIEogQSAEIAh/IgKnIkJsIkBqIEQgBCACxCAIfn0iBSAJfyICpyIBbCI/aiBDIAUgAiAJfn2nIgBsIj5qIUcgACBFbCI9IAEgSGwiASBLIEIgRmwiAGpqaiFCQgAhAgJAAkAgB0IEVA0AID0gS2ogAGogAWogPiBKaiBAaiA/amtBCEkNAANAIEIgAqdBAXQiAGr9DAB+AAAAfgAAAH4AAAB+AAAgpwIgACBHav0EAQAipQL9GwBBAnRB8NQEav0JAgAgpQL9GwFBAnRB8NQEaioCAP0gASClAv0bAkECdEHw1ARqKgIA/SACIKUC/RsDQQJ0QfDUBGoqAgD9IAP95AEipgL94AH9DAAAgHcAAIB3AACAdwAAgHf95gH9DAAAgAgAAIAIAACACAAAgAj95gEgpgJBAf2rASKoAv0MAAAA/wAAAP8AAAD/AAAA//1O/QwAAABxAAAAcQAAAHEAAABx/bkBQQH9rQH9DAAAgAcAAIAHAACABwAAgAf9rgH95AEipQJBDf2tAf0MAHwAAAB8AAAAfAAAAHwAAP1OIKUC/Qz/DwAA/w8AAP8PAAD/DwAA/U79rgEgqAL9DAAAAP8AAAD/AAAA/wAAAP/9PP1SIKYCQRD9rQH9DACAAAAAgAAAAIAAAACAAAD9Tv1QIKYC/Q0AAQQFCAkMDQABAAEAAQAB/VsBAAAgAkIEfCICIANSDQALIAMiAiAHUQ0BCwNAIEIgAqdBAXQiAGpBgPwBIJMCIAAgR2ovAQBBAnRB8NQEaioCAJIikgKLQwAAgHeUQwAAgAiUQYCAgIgHIJICvCI9QQF0IgFBgICAeHEiACAAQYCAgIgHTRtBAXZBgICAPGq+krwiAEENdkGA+AFxIABB/x9xaiABQYCAgHhLGyA9QRB2QYCAAnFyOwEAIAJCAXwiAiAHUg0ACwsgBEIBfCIEIAZSDQALDAILIE1B/iA2AlggTUG+OTYCVCBNQccmNgJQQajCAigCACIAQaXjACBNQdAAahAwDGELIE4pAxAiBCABKQMQUg0PIE4pAxgiCSABKQMYUg0PIE4pAyAiAyABKQMgUg0PIE4pAygiAiABKQMoUg0PIEwpAxBCAVINECBMKQMYQgFSDRAgTCkDIEIBUg0QIEwpAyhCAVINEAJAIAAoAgAOAwEAAQALIE4oAjAgPUEkbCJCQZiaAWooAgBHDREgASgCMCJHIAEoAjQiSksNEiBKIAEoAjgiS0sNEyBLIAEoAjxLDRRBzP8DID12QQFxRQ0VIAEoAgAgPUcNFiBMKAIADRcgAiADIAl+Igh+pyJAIAAoAggiPWpBAWsgPW0iPSAAKAIEIj5sIj8gPSA/aiI9IEAgPSBASBsiPU4NACBOKAI8IUYgTigCOCFIIE4oAjQhRSBCQaSaAWooAgAhQSBCQaCaAWooAgAhRCAAKAIQID4gBKciSUEQamxBAnRqIVEgPawhBiA/rCECIElBAEwEQANAIAEoAsABIT8gTigCwAEgSCACIAIgCH8iBcQgCH59IgQgCX8iA6ciPmwgRiAFpyI9bGogRSAEIAMgCX59pyIAbGpqIFEgSSBEEQUAIFEgPyA+IEtsID0gR2xqIAAgSmxqaiBJIEERBQAgAkIBfCICIAZSDQAMAgsACyBJQXxxIT0gTCgCwAEqAgAikgL9EyGlAiBJQQRJIUMDQCABKALAASFCIE4oAsABIEggAiACIAh/IgXEIAh+fSIEIAl/IgOnIj5sIEYgBaciAGxqIEUgBCADIAl+faciQGxqaiBRIEkgRBEFACA+IEtsIAAgR2xqIT9BACEAAkAgQ0UEQANAIFEgAEECdGoiPiClAiA+/QACAP3kAf0LAgAgAEEEaiIAID1HDQALID0iACBJRg0BCwNAIFEgAEECdGoiPiCSAiA+KgIAkjgCACAAQQFqIgAgSUcNAAsLIFEgQiA/IEAgSmxqaiBJIEERBQAgAkIBfCICIAZSDQALCyBNQZADaiQADBgLIE1B5M4ANgJIIE1B1Tc2AkQgTUHHJjYCQEGowgIoAgAiAEGl4wAgTUFAaxAwDF4LIE1BzdcANgI4IE1B1jc2AjQgTUHHJjYCMEGowgIoAgAiAEGl4wAgTUEwahAwDF0LIE1BiNAANgIoIE1B4zc2AiQgTUHHJjYCIEGowgIoAgAiAEGl4wAgTUEgahAwDFwLIE1B4dAANgIYIE1B5Dc2AhQgTUHHJjYCEEGowgIoAgAiAEGl4wAgTUEQahAwDFsLIE1B5M4ANgKoASBNQbs4NgKkASBNQccmNgKgAUGowgIoAgAiAEGl4wAgTUGgAWoQMAxaCyBNQc3XADYCmAEgTUG8ODYClAEgTUHHJjYCkAFBqMICKAIAIgBBpeMAIE1BkAFqEDAMWQsgTUHpODYCiAEgTUHOODYChAEgTUHHJjYCgAFBqMICKAIAIgBBpeMAIE1BgAFqEDAMWAsgTUHu0QA2AnggTUHQODYCdCBNQccmNgJwQajCAigCACIAQaXjACBNQfAAahAwDFcLIE1BwtIANgJoIE1B0Tg2AmQgTUHHJjYCYEGowgIoAgAiAEGl4wAgTUHgAGoQMAxWCyBNQeTOADYC+AEgTUGJODYC9AEgTUHHJjYC8AFBqMICKAIAIgBBpeMAIE1B8AFqEDAMVQsgTUHN1wA2AugBIE1Bijg2AuQBIE1BxyY2AuABQajCAigCACIAQaXjACBNQeABahAwDFQLIE1B6Tg2AtgBIE1BnDg2AtQBIE1BxyY2AtABQajCAigCACIAQaXjACBNQdABahAwDFMLIE1B7tEANgLIASBNQZ44NgLEASBNQccmNgLAAUGowgIoAgAiAEGl4wAgTUHAAWoQMAxSCyBNQcLSADYCuAEgTUGfODYCtAEgTUHHJjYCsAFBqMICKAIAIgBBpeMAIE1BsAFqEDAMUQsgTUHkzgA2AogDIE1B7Tg2AoQDIE1BxyY2AoADQajCAigCACIAQaXjACBNQYADahAwDFALIE1BzdcANgL4AiBNQe44NgL0AiBNQccmNgLwAkGowgIoAgAiAEGl4wAgTUHwAmoQMAxPCyBNQenTADYC6AIgTUGDOTYC5AIgTUHHJjYC4AJBqMICKAIAIgBBpeMAIE1B4AJqEDAMTgsgTUGkPTYCiAIgTUGGOTYChAIgTUHHJjYCgAJBqMICKAIAIgBBpeMAIE1BgAJqEDAMTQsgTUHyOjYCmAIgTUGHOTYClAIgTUHHJjYCkAJBqMICKAIAIgBBpeMAIE1BkAJqEDAMTAsgTUHdOTYCqAIgTUGIOTYCpAIgTUHHJjYCoAJBqMICKAIAIgBBpeMAIE1BoAJqEDAMSwsgTUHL0wA2ArgCIE1Bijk2ArQCIE1BxyY2ArACQajCAigCACIAQaXjACBNQbACahAwDEoLIE1BkSI2AtgCIE1Bizk2AtQCIE1BxyY2AtACQajCAigCACIAQaXjACBNQdACahAwDEkLIE1B+zs2AsgCIE1BjDk2AsQCIE1BxyY2AsACQajCAigCACIAQaXjACBNQcACahAwDEgLIE1B/iA2AgggTUHROTYCBCBNQccmNgIAQajCAigCACIAQaXjACBNEDAMRwsMPgsgASgCjAEhQSABKAKQASFEIwBB4ABrIlAkAAJAAkACQAJAAkACQCBBKAIARQRAIEEpAxAiByABKQMQUg0BIEEpAxgiDCABKQMYUg0BIEEpAyAiCyABKQMgUg0BIEEpAygiCSABKQMoUg0BIAEoAjAiQyABKAIAIkJBJGwiPUGYmgFqKAIARw0CIAEoAjQiQK0iCCAHIEOtfiIFID1BlJoBaigCACI/rH9SDQIgASgCOCI+rSIGIAggDH5SDQIgASgCPCI9rSIEIAYgC35SDQIgQSgCMEEERw0CIEE1AjQiAyAHQgKGUg0CIEE1AjgiAiADIAx+Ug0CIEE1AjwgAiALflINAiABKAJQIVMgASgCTCFSIAEoAkghTiABKAJEIUwCQCABKAJURQRAIAAoAgAiYQ0BIAEoAsABIEEoAsABIEJBEGtBcU0EfyBAIAynQQFrbCBDIAenbGogPiALp0EBa2xqID0gCadBAWtsagUgC0IBfSAGfiAMQgF9IAh+fCAJQgF9IAR+fCAFID+tf3ynC/wKAAALIAAoAgAhYQsCQAJAIGEOAwEAAQALIFOtIEytIEQpAxgiC0IBfSICQgAgAiALWBt+fCBOrSBEKQMgIgdCAX0iAkIAIAIgB1gbfnwgUq0gRCkDKCIJQgF9IgJCACACIAlYG358IEEoAgAiQkEkbEGYmgFqKAIAIj6tIEQpAxAiCEIBfSICQgAgAiAIWBt+fCEGIEQoAjwhUSBEKAI4IUogRCgCNCFLIAEpAyghBSABKQMQIQQgASkDICEDIAEpAxghAiBEKAIwIeMBIAAoAgghQCAAKAIEIQAgBgJ/IAEoAgAiP0EQa0FxTQRAID9BJGxBmJoBaigCACABKAIwIASnQQFrbGogASgCNCACp0EBa2xqIAEoAjggA6dBAWtsaiABKAI8IAWnQQFrbGoMAQsgATUCNCACQgF9fiAEIAE1AjB+ID9BJGxBlJoBajUCAH98IAE1AjggA0IBfX58IAE1AjwgBUIBfX58pwutWQ0EIEEpAyAhAyBBKQMYIQIgBgJ/IEJBEGtBcU0EQCBBKAIwIEEoAhBBAWtsID5qIEEoAjQgAqdBAWtsaiBBKAI4IAOnQQFrbGogQSgCPCBBKAIoQQFrbGoMAQsgQTUCNCACQgF9fiBBKQMQIEE1AjB+IEJBJGxBlJoBajUCAH98IEE1AjggA0IBfX58IEE1AjwgQSkDKEIBfX58pwutWQ0FIOMBQQRHDQYgACBAIAkgByALfiIGfqciPWpBAWsgQG0iAGwiPiAAID5qIgAgPSAAID1IGyIATg0AIAinIldBAEwNACBEKALAASFJQQAgV2shRyBXQQFxIUYgV0F8cSE9IFMgQSgCwAEiSGohRSBTIAEoAsABIkFqIUQgAKwhBSA+rCEDIFdBEEkhQwNAIEkgUSADIAZ/IgKnIkJsIkBqIEogAyACxCAGfn0iBCALfyICpyIBbCI/aiBLIAQgAiALfn2nIgBsIj5qIVkgACBMbCJNIAEgTmwiWyBIIEIgUmwiQmpqaiBTaiFYIEEgQmogW2ogTWogU2ohWkEAIQACQAJAIEMNACBEIE1qIEJqIFtqIgEgRSBNaiBCaiBbamtBEEkNACABID4gSWogQGogP2prQRBJDQADQCBaIABBAnQiAWogASBYav0AAgAgASBZav0AAgD95AH9CwIAIABBBGoiACA9Rw0ACyA9IgAgV0YNAQsgAEF/cyHkASBGBEAgWiAAQQJ0Ij5qID4gWGoqAgAgPiBZaioCAJI4AgAgAEEBciEACyDkASBHRg0AA0AgWiAAQQJ0IgFqIAEgWGoqAgAgASBZaioCAJI4AgAgWiABQQRqIgFqIAEgWGoqAgAgASBZaioCAJI4AgAgAEECaiIAIFdHDQALCyADQgF8IgMgBVINAAsLIFBB4ABqJAAMBgsgUEH+IDYCWCBQQcA6NgJUIFBBxyY2AlBBqMICKAIAIgBBpeMAIFBB0ABqEDAMSwsgUEHkzgA2AkggUEHdOTYCRCBQQccmNgJAQajCAigCACIAQaXjACBQQUBrEDAMSgsgUEG92AA2AjggUEHeOTYCNCBQQccmNgIwQajCAigCACIAQaXjACBQQTBqEDAMSQsgUEH1ywA2AiggUEGGOjYCJCBQQccmNgIgQajCAigCACIAQaXjACBQQSBqEDAMSAsgUEGd2QA2AhggUEGHOjYCFCBQQccmNgIQQajCAigCACIAQaXjACBQQRBqEDAMRwsgUEG00AA2AgggUEGJOjYCBCBQQccmNgIAQajCAigCACIAQaXjACBQEDAMRgsMPQsgASgCjAEhPiABKAKQASE9IwBBMGsiViQAAkACQAJAID4oAgBFBEACQAJAIAAoAgAOAwEAAQALIAEoAjBBBEcNAiA+KAIwQQRHDQMgPikDKCA+KQMgID4pAxh+fiIDpyEAIAEoAjwhUyABKAI4IVkgASgCNCFYIAEpAyAhAiABKQMYIQkgPSgCPCFaID0oAjghTSA9KAI0IVsgPigCPCFSID4oAjghTiA+KAI0IUwgASkDECEHID0oAjAiSUEERwRAIABBAEwNASAHQgBXDQEgAiAJfiEIIElBAUYgB0ITVnEhSiAHQgGDIQYgB0J8gyEEIANC/////w+DIQUgB6ciACA9KALAASJLakEDaiFHID4oAsABIkYgAEECdCIAaiFIIAEoAsABIkUgAGohQQNAIEsgWiAKIAh/IgKnIlFsIkRqIE0gCiACxCAIfn0iAyAJfyICpyIBbCJDaiBbIAMgAiAJfn2nIgBsIkJqIVAgACBMbCJAIAEgTmwiPyBGIFEgUmwiPmpqaiFXIAAgWGwiPSABIFlsIgEgRSBRIFNsIgBqamohUUIAIQICQAJAIEpFDQAgUSBIID8gQGogPmpqSSBXIEEgASA9aiAAamoiAElxDQAgUSBHIEIgQ2ogRGpqSSAAIFBLcQ0A/QwAAAAAAQAAAAIAAAADAAAAIaYCA0AgUSACp0ECdCIAaiAAIFdq/QACACBQIKYC/RsAav0JAgAgUCCmAv0bAWoqAgD9IAEgUCCmAv0bAmoqAgD9IAIgUCCmAv0bA2oqAgD9IAP95QH9CwIAIKYC/QwEAAAABAAAAAQAAAAEAAAA/a4BIaYCIAJCBHwiAiAEUg0ACyAEIgIgB1ENAQsgAkIBhCEDIAanBEAgUSACpyIBQQJ0IgBqIAAgV2oqAgAgUCABIElsaioCAJM4AgAgAyECCyADIAdRDQADQCBRIAKnIgFBAnQiAGogACBXaioCACBQIAEgSWxqKgIAkzgCACBRIAFBAWoiAUECdCIAaiAAIFdqKgIAIFAgASBJbGoqAgCTOAIAIAJCAnwiAiAHUg0ACwsgCkIBfCIKIAVSDQALDAELIABBAEwNACAHpyJeQQBMDQAgAiAJfiEGID0oAsABIUkgPigCwAEhUSABKALAASFKQQAgXmshRyBeQQFxIUYgXkF8cSEBIANC/////w+DIQVCACECIF5BEEkhSANAIEkgWiACIAZ/IgOnIktsIkVqIE0gAiADxCAGfn0iBCAJfyIDpyI9bCJBaiBbIAQgAyAJfn2nIgBsIkRqIVAgACBMbCJDID0gTmwiQiBRIEsgUmwiQGpqaiFXIAAgWGwiPyA9IFlsIj4gSiBLIFNsIj1qamohS0EAIQACQAJAIEgNACA/IEpqID1qID5qIj0gQyBRaiBAaiBCamtBEEkNACA9IEQgSWogRWogQWprQRBJDQADQCBLIABBAnQiPWogPSBXav0AAgAgPSBQav0AAgD95QH9CwIAIABBBGoiACABRw0ACyABIgAgXkYNAQsgAEF/cyHlASBGBEAgSyAAQQJ0Ij5qID4gV2oqAgAgPiBQaioCAJM4AgAgAEEBciEACyDlASBHRg0AA0AgSyAAQQJ0Ij1qID0gV2oqAgAgPSBQaioCAJM4AgAgSyA9QQRqIj1qID0gV2oqAgAgPSBQaioCAJM4AgAgAEECaiIAIF5HDQALCyACQgF8IgIgBVINAAsLIFZBMGokAAwDCyBWQf4gNgIoIFZBjzs2AiQgVkHHJjYCIEGowgIoAgAiAEGl4wAgVkEgahAwDEcLIFZBiNAANgIYIFZB1zo2AhQgVkHHJjYCEEGowgIoAgAiAEGl4wAgVkEQahAwDEYLIFZB4dAANgIIIFZB2Do2AgQgVkHHJjYCAEGowgIoAgAiAEGl4wAgVhAwDEULDDwLIAEoAowBIT8gASgCkAEhPiMAQdAAayJeJAACQAJAAkACQCA+KAIARQRAID8oAgBFBEAgPikDECIRID8pAxBSDQIgPykDGCIPID4pAxgiC4FCAFINAiA/KQMgIgMgPikDICIHgUIAUg0CID8pAygiAiA+KQMoIgmBQgBSDQIgESABKQMQUg0CIA8gASkDGFINAiADIAEpAyBSDQIgAiABKQMoUg0CAkACQCAAKAIADgMBAAEACyABKAIwQQRHDQQgPygCMEEERw0FIAIgAyAPfiIOfiEMIAEoAjwhWCABKAI4IVogASgCNCFNID4oAjwhWyA+KAI4IVIgPigCNCFOID8oAjwhTCA/KAI4IUkgPygCNCFRIAAoAgghPSAANAIEIQ0gPigCMCJZQQRGBEAgDCANVw0BIBGnIlNBAEwNASA9rCEDID4oAsABIUYgPygCwAEhSyABKALAASFHQQAgU2shSCBTQQFxIUUgU0F8cSEBIFNBEEkhQQNAIEsgTCANIA5/IgWnIkRsIkNqIEkgDSAFIA5+fSICIA9/IgSnIj1sIkJqIFEgAiAEIA9+fSICpyIAbCJAaiFKIAAgTWwiPyA9IFpsIj4gRyBEIFhsIj1qamohRCBGIFsgBSAJgadsaiBSIAQgB4GnbGogTiACIAuBp2xqIVlBACEAAkACQCBBDQAgPyBHaiA9aiA+aiI9IEAgS2ogQ2ogQmprQRBJDQAgPSBZa0EQSQ0AA0AgRCAAQQJ0Ij1qID0gSmr9AAIAID0gWWr9AAIA/eYB/QsCACAAQQRqIgAgAUcNAAsgASIAIFNGDQELIABBf3Mh5gEgRQRAIEQgAEECdCI+aiA+IEpqKgIAID4gWWoqAgCUOAIAIABBAXIhAAsg5gEgSEYNAANAIEQgAEECdCI9aiA9IEpqKgIAID0gWWoqAgCUOAIAIEQgPUEEaiI9aiA9IEpqKgIAID0gWWoqAgCUOAIAIABBAmoiACBTRw0ACwsgAyANfCINIAxTDQALDAELIAwgDVcNACARQgBXDQAgPawhBiBZQQFGIBFCE1ZxIUogEUIBgyEFIBFCfIMhBCARpyIAID4oAsABIktqQQNqIUcgPygCwAEiRiAAQQJ0IgBqIUggASgCwAEiRSAAaiFBA0AgRiBMIA0gDn8iCKciPWwiRGogSSANIAggDn59IgIgD38iA6ciAWwiQ2ogUSACIAMgD359IgKnIgBsIkJqIVMgACBNbCJAIAEgWmwiPyBFID0gWGwiAGpqaiFXIE4gAiALgadsIj4gUiADIAeBp2wiPSBLIFsgCCAJgadsIgFqamohUEIAIQICQAJAIEpFDQAgVyBIIEIgQ2ogRGpqSSBTIEEgPyBAaiAAamoiAElxDQAgVyBHID0gPmogAWpqSSAAIFBLcQ0A/QwAAAAAAQAAAAIAAAADAAAAIaYCA0AgVyACp0ECdCIAaiAAIFNq/QACACBQIKYC/RsAav0JAgAgUCCmAv0bAWoqAgD9IAEgUCCmAv0bAmoqAgD9IAIgUCCmAv0bA2oqAgD9IAP95gH9CwIAIKYC/QwEAAAABAAAAAQAAAAEAAAA/a4BIaYCIAJCBHwiAiAEUg0ACyAEIgIgEVENAQsgAkIBhCEDIAWnBEAgVyACpyIBQQJ0IgBqIAAgU2oqAgAgUCABIFlsaioCAJQ4AgAgAyECCyADIBFRDQADQCBXIAKnIgFBAnQiAGogACBTaioCACBQIAEgWWxqKgIAlDgCACBXIAFBAWoiAUECdCIAaiAAIFNqKgIAIFAgASBZbGoqAgCUOAIAIAJCAnwiAiARUg0ACwsgBiANfCINIAxTDQALCyBeQdAAaiQADAULIF5B/iA2AjggXkH0OzYCNCBeQccmNgIwQajCAigCACIAQaXjACBeQTBqEDAMSAsgXkGM2wA2AkggXkHrOzYCRCBeQccmNgJAQajCAigCACIAQaXjACBeQUBrEDAMRwsgXkHAzgA2AiggXkGbOzYCJCBeQccmNgIgQajCAigCACIAQaXjACBeQSBqEDAMRgsgXkGI0AA2AhggXkGwOzYCFCBeQccmNgIQQajCAigCACIAQaXjACBeQRBqEDAMRQsgXkHh0AA2AgggXkGxOzYCBCBeQccmNgIAQajCAigCACIAQaXjACBeEDAMRAsMOwsgASgCjAEhPiABKAKQASE9IwBBMGsiViQAAkACQAJAID4oAgBFBEACQAJAIAAoAgAOAwEAAQALIAEoAjBBBEcNAiA+KAIwQQRHDQMgPikDKCA+KQMgID4pAxh+fiIDpyEAIAEoAjwhUyABKAI4IVkgASgCNCFYIAEpAyAhAiABKQMYIQkgPSgCPCFaID0oAjghTSA9KAI0IVsgPigCPCFSID4oAjghTiA+KAI0IUwgASkDECEHID0oAjAiSUEERwRAIABBAEwNASAHQgBXDQEgAiAJfiEIIElBAUYgB0ITVnEhSiAHQgGDIQYgB0J8gyEEIANC/////w+DIQUgB6ciACA9KALAASJLakEDaiFHID4oAsABIkYgAEECdCIAaiFIIAEoAsABIkUgAGohQQNAIEsgWiAKIAh/IgKnIlFsIkRqIE0gCiACxCAIfn0iAyAJfyICpyIBbCJDaiBbIAMgAiAJfn2nIgBsIkJqIVAgACBMbCJAIAEgTmwiPyBGIFEgUmwiPmpqaiFXIAAgWGwiPSABIFlsIgEgRSBRIFNsIgBqamohUUIAIQICQAJAIEpFDQAgUSBIID8gQGogPmpqSSBXIEEgASA9aiAAamoiAElxDQAgUSBHIEIgQ2ogRGpqSSAAIFBLcQ0A/QwAAAAAAQAAAAIAAAADAAAAIaYCA0AgUSACp0ECdCIAaiAAIFdq/QACACBQIKYC/RsAav0JAgAgUCCmAv0bAWoqAgD9IAEgUCCmAv0bAmoqAgD9IAIgUCCmAv0bA2oqAgD9IAP95wH9CwIAIKYC/QwEAAAABAAAAAQAAAAEAAAA/a4BIaYCIAJCBHwiAiAEUg0ACyAEIgIgB1ENAQsgAkIBhCEDIAanBEAgUSACpyIBQQJ0IgBqIAAgV2oqAgAgUCABIElsaioCAJU4AgAgAyECCyADIAdRDQADQCBRIAKnIgFBAnQiAGogACBXaioCACBQIAEgSWxqKgIAlTgCACBRIAFBAWoiAUECdCIAaiAAIFdqKgIAIFAgASBJbGoqAgCVOAIAIAJCAnwiAiAHUg0ACwsgCkIBfCIKIAVSDQALDAELIABBAEwNACAHpyJeQQBMDQAgAiAJfiEGID0oAsABIUkgPigCwAEhUSABKALAASFKQQAgXmshRyBeQQFxIUYgXkF8cSEBIANC/////w+DIQVCACECIF5BEEkhSANAIEkgWiACIAZ/IgOnIktsIkVqIE0gAiADxCAGfn0iBCAJfyIDpyI9bCJBaiBbIAQgAyAJfn2nIgBsIkRqIVAgACBMbCJDID0gTmwiQiBRIEsgUmwiQGpqaiFXIAAgWGwiPyA9IFlsIj4gSiBLIFNsIj1qamohS0EAIQACQAJAIEgNACA/IEpqID1qID5qIj0gQyBRaiBAaiBCamtBEEkNACA9IEQgSWogRWogQWprQRBJDQADQCBLIABBAnQiPWogPSBXav0AAgAgPSBQav0AAgD95wH9CwIAIABBBGoiACABRw0ACyABIgAgXkYNAQsgAEF/cyHnASBGBEAgSyAAQQJ0Ij5qID4gV2oqAgAgPiBQaioCAJU4AgAgAEEBciEACyDnASBHRg0AA0AgSyAAQQJ0Ij1qID0gV2oqAgAgPSBQaioCAJU4AgAgSyA9QQRqIj1qID0gV2oqAgAgPSBQaioCAJU4AgAgAEECaiIAIF5HDQALCyACQgF8IgIgBVINAAsLIFZBMGokAAwDCyBWQf4gNgIoIFZBxTw2AiQgVkHHJjYCIEGowgIoAgAiAEGl4wAgVkEgahAwDEULIFZBiNAANgIYIFZBizw2AhQgVkHHJjYCEEGowgIoAgAiAEGl4wAgVkEQahAwDEQLIFZB4dAANgIIIFZBjDw2AgQgVkHHJjYCAEGowgIoAgAiAEGl4wAgVhAwDEMLDDoLIAEoAowBIT0jAEEQayJUJAACQCA9KAIARQRAAkACQCAAKAIADgMBAAEACyA9KQMoID0pAyAgPSkDGH5+pyJBQQBMDQAgPSgCECJIQQBMDQAgPSgCNCFEIAEoAjQhQyA9KALAASFCIAEoAsABIUAgSEEDcSFFIEhBfHEhASBIQQRJIT8DQCBCIEQgXWxqIUcgQCBDIF1saiFGQQAhAAJAAkAgPw0AIEYgR2tBEEkNAANAIEYgAEECdCI9aiA9IEdq/QACACKlAiClAv3mAf0LAgAgAEEEaiIAIAFHDQALIAEiACBIRg0BCyAAQX9zIEhqIegBQQAhYSBFBEADQCBGIABBAnQiPWogPSBHaioCACKSAiCSApQ4AgAgAEEBaiEAIGFBAWoiYSBFRw0ACwsg6AFBA0kNAANAIEYgAEECdCI+aiA+IEdqKgIAIpICIJIClDgCACBGID5BBGoiPWogPSBHaioCACKSAiCSApQ4AgAgRiA+QQhqIj1qID0gR2oqAgAikgIgkgKUOAIAIEYgPkEMaiI9aiA9IEdqKgIAIpICIJIClDgCACAAQQRqIgAgSEcNAAsLIF1BAWoiXSBBRw0ACwsgVEEQaiQADAELIFRB/iA2AgggVEHvPDYCBAw+Cww5CyABKAKMASE9IwBBEGsiVCQAAkAgPSgCAEUEQAJAAkAgACgCAA4DAQABAAsgPSkDKCA9KQMgID0pAxh+fqciQUEATA0AID0oAhAiSEEATA0AID0oAjQhRCABKAI0IUMgPSgCwAEhQiABKALAASFAIEhBA3EhRSBIQXxxIQEgSEEESSE/A0AgQiBEIF1saiFHIEAgQyBdbGohRkEAIQACQAJAID8NACBGIEdrQRBJDQADQCBGIABBAnQiPWogPSBHav0AAgD94wH9CwIAIABBBGoiACABRw0ACyABIgAgSEYNAQsgAEF/cyBIaiHpAUEAIWEgRQRAA0AgRiAAQQJ0Ij1qID0gR2oqAgCROAIAIABBAWohACBhQQFqImEgRUcNAAsLIOkBQQNJDQADQCBGIABBAnQiPmogPiBHaioCAJE4AgAgRiA+QQRqIj1qID0gR2oqAgCROAIAIEYgPkEIaiI9aiA9IEdqKgIAkTgCACBGID5BDGoiPWogPSBHaioCAJE4AgAgAEEEaiIAIEhHDQALCyBdQQFqIl0gQUcNAAsLIFRBEGokAAwBCyBUQf4gNgIIIFRBmT02AgQMPQsMOAsgASgCjAEhPSMAQdAAayJLJAACQAJAAkACQAJAID0oAgBFBEAgACgCBA0BID0pAxAiBSABKQMQUg0CID0pAxgiBCABKQMYUg0CID0pAyAiAyABKQMgUg0CID0pAygiAiABKQMoUg0CAkACQCAAKAIADgMBAAEACyABKAIwQQRHDQQgPSgCMEEERw0FIAMgBH4gAn6nIkFBAEwNACAFpyJIQQBMDQAgPSgCNCFEIAEoAjQhQyA9KALAASFCIAEoAsABIUAgSEEDcSFFIEhBfHEhASBIQQRJIT8DQCBCIEQgXWxqIUcgQCBDIF1saiFGQQAhAAJAAkAgPw0AIEYgR2tBEEkNAANAIEYgAEECdCI9aiA9IEdq/QACACKlAv0fABBX/RMgpQL9HwEQV/0gASClAv0fAhBX/SACIKUC/R8DEFf9IAP9CwIAIABBBGoiACABRw0ACyABIgAgSEYNAQsgAEF/cyBIaiHqAUEAIWEgRQRAA0AgRiAAQQJ0Ij1qID0gR2oqAgAQVzgCACAAQQFqIQAgYUEBaiJhIEVHDQALCyDqAUEDSQ0AA0AgRiAAQQJ0Ij5qID4gR2oqAgAQVzgCACBGID5BBGoiPWogPSBHaioCABBXOAIAIEYgPkEIaiI9aiA9IEdqKgIAEFc4AgAgRiA+QQxqIj1qID0gR2oqAgAQVzgCACAAQQRqIgAgSEcNAAsLIF1BAWoiXSBBRw0ACwsgS0HQAGokAAwFCyBLQf4gNgJIIEtBwz02AkQgS0HHJjYCQEGowgIoAgAiAEGl4wAgS0FAaxAwDEQLIEtBo8AANgI4IEtBpD02AjQgS0HHJjYCMEGowgIoAgAiAEGl4wAgS0EwahAwDEMLIEtB5M4ANgIoIEtBpT02AiQgS0HHJjYCIEGowgIoAgAiAEGl4wAgS0EgahAwDEILIEtBjc8ANgIYIEtBrj02AhQgS0HHJjYCEEGowgIoAgAiAEGl4wAgS0EQahAwDEELIEtBqc8ANgIIIEtBrz02AgQgS0HHJjYCAEGowgIoAgAiAEGl4wAgSxAwDEALDDcLIAEoAowBIT0jAEEQayJJJAACQAJAAkACQAJAID0oAgAOAgABAwsCQCAAKAIADgMCAAIACwJAID0pAygiCEIAVw0AID0pAyAiBkIAVw0AID0pAxgiBUIAVw0AID0oAhAiAEEATA0AID0oAjwhQSA9KAI4IUQgPSgCNCFDID0oAsABIUIgAEF8cSFAIABBA3EhRSAAQQRJIT8DQCBCIEEgBKdsaiE+QgAhAgNAID4gRCACp2xqIT1CACEDA0AgPSBDIAOnbGohRkQAAAAAAAAAACHFAkEAIU9BACEAQQAhVCA/RQRAA0AgxQIgRiAAQQJ0IkhqKgIAu6AgRiBIQQRyaioCALugIEYgSEEIcmoqAgC7oCBGIEhBDHJqKgIAu6AhxQIgAEEEaiEAIFRBBGoiVCBARw0ACwsgRQRAA0AgxQIgRiAAQQJ0aioCALugIcUCIABBAWohACBPQQFqIk8gRUcNAAsLIMYCIMUCoCHGAiADQgF8IgMgBVINAAsgAkIBfCICIAZSDQALIARCAXwiBCAIUg0ACyDGArYhkgILIAEoAsABIJICOAIADAELAkAgACgCAA4DAQABAAsCQCA9KQMoIghCAFcNACA9KQMgIgZCAFcNACA9KQMYIgVCAFcNACA9KAIQIgBBAEwNACA9KAI8IUEgPSgCOCFEID0oAjQhQyA9KALAASFCIABBfHEhQCAAQQNxIUUgAEEESSE/A0AgQiBBIASnbGohPkIAIQIDQCA+IEQgAqdsaiE9QgAhAwNAID0gQyADp2xqIUZDAAAAACGSAkEAIU9BACEAQQAhVCA/RQRAA0AgkgIgRiAAQQF0IkhqLwEAQQJ0QfDUBGoqAgCSIEYgSEECcmovAQBBAnRB8NQEaioCAJIgRiBIQQRyai8BAEECdEHw1ARqKgIAkiBGIEhBBnJqLwEAQQJ0QfDUBGoqAgCSIZICIABBBGohACBUQQRqIlQgQEcNAAsLIEUEQANAIJICIEYgAEEBdGovAQBBAnRB8NQEaioCAJIhkgIgAEEBaiEAIE9BAWoiTyBFRw0ACwsglAIgkgKSIZQCIANCAXwiAyAFUg0ACyACQgF8IgIgBlINAAsgBEIBfCIEIAhSDQALCyABKALAAUGA/AEglAKLQwAAgHeUQwAAgAiUQYCAgIgHIJQCvCI9QQF0IgFBgICAeHEiACAAQYCAgIgHTRtBAXZBgICAPGq+krwiAEENdkGA+AFxIABB/x9xaiABQYCAgHhLGyA9QRB2QYCAAnFyOwEACyBJQRBqJAAMAQsgSUH+IDYCCCBJQZo+NgIEDDwLDDYLIAEoAowBIT0jAEGAAWsiTiQAAkACQAJAAkACQAJAAkACQCA9KAIARQRAIAAoAgQNAQJAAkAgACgCAA4DAQABAAsgPSgCMEEERw0DIAEoAjBBBEcNBCABKQMQQgFSDQUgPSkDGCIHIAEpAxhSDQYgPSkDICIJIAEpAyBSDQcgPSkDKCIIIAEpAyhSDQggCEIAVw0AIAlCAFcNACAHQgBXDQAgASgCPCFKIAEoAjghSyABKAI0IUwgASgCwAEhRyA9KQMQpyIAQQBMBEAgTEEBRiAHQgNWcSEBIAdCA4MhBiAHQnyDIQMDQCBHIEogDadsaiEAQgAhHgNAIAAgSyAep2xqIT5CACEFQgAhAgJAIAEEQP0MAAAAAAEAAAACAAAAAwAAACGmAgNAID4gpgL9GwBqQQA2AgAgPiCmAv0bAWpBADYCACA+IKYC/RsCakEANgIAID4gpgL9GwNqQQA2AgAgpgL9DAQAAAAEAAAABAAAAAQAAAD9rgEhpgIgAkIEfCICIANSDQALIAMiAiAHUQ0BCyAHIAJCf4V8IS8gBkIAUgRAA0AgPiBMIAKnbGpBADYCACACQgF8IQIgBUIBfCIFIAZSDQALCyAvQgNUDQADQCA+IEwgAqciPWxqQQA2AgAgPiBMID1BAWpsakEANgIAID4gTCA9QQJqbGpBADYCACA+IEwgPUEDamxqQQA2AgAgAkIEfCICIAdSDQALCyAeQgF8Ih4gCVINAAsgDUIBfCINIAhSDQALDAELID0oAjwhSCA9KAI4IUUgPSgCNCFBID0oAsABIUQgAEF8cSFDIABBA3EhRiAAQQRJIUIDQCBHIEogA6ciAGxqIUAgRCAAIEhsaiE/QgAhBQNAIEAgSyAFpyIAbGohPiA/IAAgRWxqIT1CACECA0AgPSBBIAKnIgFsaiFJRAAAAAAAAAAAIcUCQQAhYkEAIQBBACFcIEJFBEADQCDFAiBJIABBAnQiUWoqAgC7oCBJIFFBBHJqKgIAu6AgSSBRQQhyaioCALugIEkgUUEMcmoqAgC7oCHFAiAAQQRqIQAgXEEEaiJcIENHDQALCyBGBEADQCDFAiBJIABBAnRqKgIAu6AhxQIgAEEBaiEAIGJBAWoiYiBGRw0ACwsgPiABIExsaiDFArY4AgAgAkIBfCICIAdSDQALIAVCAXwiBSAJUg0ACyADQgF8IgMgCFINAAsLIE5BgAFqJAAMCAsgTkH+IDYCeCBOQc0+NgJ0IE5BxyY2AnBBqMICKAIAIgBBpeMAIE5B8ABqEDAMRQsgTkGjwAA2AmggTkGlPjYCZCBOQccmNgJgQajCAigCACIAQaXjACBOQeAAahAwDEQLIE5Bqc8ANgJYIE5Bqz42AlQgTkHHJjYCUEGowgIoAgAiAEGl4wAgTkHQAGoQMAxDCyBOQY3PADYCSCBOQaw+NgJEIE5BxyY2AkBBqMICKAIAIgBBpeMAIE5BQGsQMAxCCyBOQfs+NgI4IE5BsD42AjQgTkHHJjYCMEGowgIoAgAiAEGl4wAgTkEwahAwDEELIE5B5z02AiggTkGxPjYCJCBOQccmNgIgQajCAigCACIAQaXjACBOQSBqEDAMQAsgTkHgPDYCGCBOQbI+NgIUIE5BxyY2AhBBqMICKAIAIgBBpeMAIE5BEGoQMAw/CyBOQY06NgIIIE5Bsz42AgQgTkHHJjYCAEGowgIoAgAiAEGl4wAgThAwDD4LDDULIAEoAowBIT0jAEEQayJPJAACQCA9KAIARQRAAkACQCAAKAIADgMBAAEACyA9KQMoIglCAFcNACA9KQMgIghCAFcNACA9KQMYIgdCAFcNACABKAI8IUogASgCOCFLIAEoAjQhTCA9KQMQIgK0IZICIAEoAsABIUcgAqciAEEATARAQwAAAAAgkgKVIZICIExBAUYgB0IDVnEhASAHQgODIQYgB0J8gyEDA0AgRyBKIA2nbGohAEIAIQoDQCAAIEsgCqdsaiE+QgAhBUIAIQICQCABBED9DAAAAAABAAAAAgAAAAMAAAAhpgIDQCA+IKYC/RsAaiCSAjgCACA+IKYC/RsBaiCSAjgCACA+IKYC/RsCaiCSAjgCACA+IKYC/RsDaiCSAjgCACCmAv0MBAAAAAQAAAAEAAAABAAAAP2uASGmAiACQgR8IgIgA1INAAsgAyICIAdRDQELIAcgAkJ/hXwhMCAGQgBSBEADQCA+IEwgAqdsaiCSAjgCACACQgF8IQIgBUIBfCIFIAZSDQALCyAwQgNUDQADQCA+IEwgAqciPWxqIJICOAIAID4gTCA9QQFqbGogkgI4AgAgPiBMID1BAmpsaiCSAjgCACA+IEwgPUEDamxqIJICOAIAIAJCBHwiAiAHUg0ACwsgCkIBfCIKIAhSDQALIA1CAXwiDSAJUg0ACwwBCyA9KAI8IUggPSgCOCFFID0oAjQhQSA9KALAASFEIABBfHEhQyAAQQNxIUYgAEEESSFCA0AgRCBIIAOnIgBsaiFAIEcgACBKbGohP0IAIQUDQCBAIEUgBaciAGxqIT4gPyAAIEtsaiE9QgAhAgNAID4gQSACpyIBbGohSUQAAAAAAAAAACHFAkEAIWJBACEAQQAhXCBCRQRAA0AgxQIgSSAAQQJ0IlFqKgIAu6AgSSBRQQRyaioCALugIEkgUUEIcmoqAgC7oCBJIFFBDHJqKgIAu6AhxQIgAEEEaiEAIFxBBGoiXCBDRw0ACwsgRgRAA0AgxQIgSSAAQQJ0aioCALugIcUCIABBAWohACBiQQFqImIgRkcNAAsLID0gASBMbGogxQK2IJIClTgCACACQgF8IgIgB1INAAsgBUIBfCIFIAhSDQALIANCAXwiAyAJUg0ACwsgT0EQaiQADAELIE9B/iA2AgggT0GEPzYCBAw7Cww0CyABKAKMASE9IwBBEGsiTyQAAkAgPSgCAEUEQAJAAkAgACgCAA4DAQABAAsgPSkDGCIGQgBXDQAgASgCMCFIIAEoAsABIUYgPSgCECIAQQBKBEAgPSgCNCFEID0oAsABIUMgAEF8cSFCIABBA3EhQSAAQQRJIUADQCBDIEQgAqciP2xqIUVDAACA/yGSAkEAIWFBACEAQQAhVEEAIWQgQEUEQANAIABBA3IiPiAAQQJyIj0gAEEBciIBIAAgVCCSAiBFIABBAnRqKgIAIpMCIJICIJMCXhsikgIgkwJbGyCSAiBFIAFBAnRqKgIAIpMCIJICIJMCXhsikgIgkwJbGyCSAiBFID1BAnRqKgIAIpMCIJICIJMCXhsikgIgkwJbGyCSAiBFID5BAnRqKgIAIpMCIJICIJMCXhsikgIgkwJbGyFUIABBBGohACBkQQRqImQgQkcNAAsLIEEEQANAIAAgVCCSAiBFIABBAnRqKgIAIpMCIJICIJMCXhsikgIgkwJbGyFUIABBAWohACBhQQFqImEgQUcNAAsLIEYgPyBIbGogVDYCACACQgF8IgIgBlINAAsMAQsCQCAGQgRUDQAgSEEBRw0AIAZCfIMhAv0MAAAAAAEAAAACAAAAAwAAACGmAgNAIEYgpgL9GwBqQQA2AgAgRiCmAv0bAWpBADYCACBGIKYC/RsCakEANgIAIEYgpgL9GwNqQQA2AgAgpgL9DAQAAAAEAAAABAAAAAQAAAD9rgEhpgIgBEIEfCIEIAJSDQALIAIgBlENAQsgBiACQn+FfCExIAZCA4MiA0IAUgRAA0AgRiBIIAKnbGpBADYCACACQgF8IQIgBUIBfCIFIANSDQALCyAxQgNUDQADQCBGIEggAqciAGxqQQA2AgAgRiBIIABBAWpsakEANgIAIEYgSCAAQQJqbGpBADYCACBGIEggAEEDamxqQQA2AgAgAkIEfCICIAZSDQALCyBPQRBqJAAMAQsgT0H+IDYCCCBPQbI/NgIEDDoLDDMLIAEoAowBIT4jAEGQAWsiZSQAAkACQAJAAkACQAJAAkACQAJAAkACQAJAID4oAgAOAgEABAsgACgCBA0EIAEpAxAiAiACID4pAxAiGn8iBSAaflINBSABKQMYIgIgAiA+KQMYIiR/IgQgJH5SDQUgASkDICICIAIgPikDICIlfyIDICV+Ug0FIAEpAygiAiACID4pAygiI38iAiAjflINBQJAIAAoAgAOAwIAAgALIAEoAjBBAkcNBiA+KAIwQQJGBEAgAqciWUEATA0CIAWnIlhBAEwNAiAkQgBXDQIgBKciWkEATA0CICVCAFcNAiAjQgBXDQIgA6ciTUEATA0CIBpCAFcNAiAapyIAQQF0IVsgGkIDgyEfIBpCeIMhAyAAQQF0IVIgASgCNCJQICSnIk5srSEbIAEoAjgiVyAlpyJMbK0hFyABKAI8IlMgI6ciSWytIRwgPigCNCJRrSEYID4oAjgiSq0hFSA+KAI8IkutIRIgPigCwAEiR60hECBQrSETIFetIRYgU60hESABKALAASJGrSEPA0AgSSBhbCFIIBwgIn4gD3whDkIAIQUDQCAFIBJ+IBB8IQwgDiAFIBF+fCELIEcgSyAFpyIAbGohRSBGIAAgSGogU2xqIUFBACEBQgAhHQNAIAEgTGwhRCALIBcgHX58IQdCACENA0AgDCANIBV+fCEJIAcgDSAWfnwhCCBFIEogDaciAGxqIUMgQSAAIERqIFdsaiFCQQAhT0IAISADQCBOIE9sIUAgCCAbICB+fCEGQgAhCgNAIEMgUSAKpyIAbGohXSBCIAAgQGogUGxqIT8gCSAKIBh+fKchPiAGIAogE358pyE9QQAhVANAID8gVCBbbGohVkIAIRlCACECAkACQCAaQghUDQAgUiBUbCA9aiA+a0EQSQ0AA0AgViACp0EBdCIAaiAAIF1q/QABAP0LAQAgAkIIfCICIANSDQALIAMiAiAaUQ0BCyAaIAJCf4V8ITIgH0IAUgRAA0AgViACp0EBdCIAaiAAIF1qLwEAOwEAIAJCAXwhAiAZQgF8IhkgH1INAAsLIDJCA1QNAANAIFYgAqdBAXQiXmogXSBeai8BADsBACBWIF5BAmoiAGogACBdai8BADsBACBWIF5BBGoiAGogACBdai8BADsBACBWIF5BBmoiAGogACBdai8BADsBACACQgR8IgIgGlINAAsLIFRBAWoiVCBYRw0ACyAKQgF8IgogJFINAAsgIEIBfCEgIE9BAWoiTyBaRw0ACyANQgF8Ig0gJVINAAsgHUIBfCEdIAFBAWoiASBNRw0ACyAFQgF8IgUgI1INAAsgIkIBfCEiIGFBAWoiYSBZRw0ACwwCCyBlQcLSADYCGCBlQfk/NgIUIGVBxyY2AhBBqMICKAIAIgBBpeMAIGVBEGoQMAxFCyAAKAIEDQYgASkDECICIAIgPikDECIGfyIFIAZ+Ug0HIAEpAxgiAiACID4pAxgiI38iBCAjflINByABKQMgIgIgAiA+KQMgIh9/IgMgH35SDQcgASkDKCICIAIgPikDKCIZfyICIBl+Ug0HAkAgACgCAA4DAQABAAsgASgCMEEERw0IID4oAjBBBEcNASACpyJQQQBMDQAgBaciV0EATA0AICNCAFcNACAEpyJTQQBMDQAgH0IAVw0AIBlCAFcNACADpyJZQQBMDQAgBqcicEEATA0AIHBBAnQhWCBwQQNxIVQgcEF8cSE9IAEoAjQiXSAjpyJabK0hGyABKAI4IlYgH6ciTWytIRcgASgCPCJeIBmnIltsrSEcID4oAjQiUq0hGCA+KAI4Ik6tIRUgPigCPCJMrSESID4oAsABIkmtIRAgXa0hEyBWrSEWIF6tIREgASgCwAEiUa0hD0IAIQUgcEEESSFKA0AgWyBkbCFLIAUgHH4gD3whDkIAIQMDQCADIBJ+IBB8IQwgDiADIBF+fCELIEkgTCADpyIAbGohRyBRIAAgS2ogXmxqIUZBACFiQgAhDQNAIE0gYmwhSCALIA0gF358IQdCACEEA0AgDCAEIBV+fCEJIAcgBCAWfnwhCCBHIE4gBKciAGxqIUUgRiAAIEhqIFZsaiFBQQAhXEIAIQoDQCBaIFxsIUQgCCAKIBt+fCEGQgAhAgNAIEUgUiACpyIAbGohdyBBIAAgRGogXWxqIUMgCSACIBh+fKchQiAGIAIgE358pyFAQQAhAQNAIEMgASBYbCI+aiFhQQAhAAJAAkAgSg0AID4gQGogQmtBEEkNAANAIGEgAEECdCI+aiA+IHdq/QACAP0LAgAgAEEEaiIAID1HDQALID0iACBwRg0BCyAAQX9zIHBqIesBQQAhTyBUBEADQCBhIABBAnQiPmogPiB3aioCADgCACAAQQFqIQAgT0EBaiJPIFRHDQALCyDrAUEDSQ0AA0AgYSAAQQJ0Ij9qID8gd2oqAgA4AgAgYSA/QQRqIj5qID4gd2oqAgA4AgAgYSA/QQhqIj5qID4gd2oqAgA4AgAgYSA/QQxqIj5qID4gd2oqAgA4AgAgAEEEaiIAIHBHDQALCyABQQFqIgEgV0cNAAsgAkIBfCICICNSDQALIApCAXwhCiBcQQFqIlwgU0cNAAsgBEIBfCIEIB9SDQALIA1CAXwhDSBiQQFqImIgWUcNAAsgA0IBfCIDIBlSDQALIAVCAXwhBSBkQQFqImQgUEcNAAsLIGVBkAFqJAAMCAsgZUHh0AA2AlggZUHOPzYCVCBlQccmNgJQQajCAigCACIAQaXjACBlQdAAahAwDEILIGVB/iA2AgggZUGhwAA2AgQgZUHHJjYCAEGowgIoAgAiAEGl4wAgZRAwDEELIGVBo8AANgJIIGVB6D82AkQgZUHHJjYCQEGowgIoAgAiAEGl4wAgZUFAaxAwDEALIGVB480ANgI4IGVB6T82AjQgZUHHJjYCMEGowgIoAgAiAEGl4wAgZUEwahAwDD8LIGVB7tEANgIoIGVB+D82AiQgZUHHJjYCIEGowgIoAgAiAEGl4wAgZUEgahAwDD4LIGVBo8AANgKIASBlQb0/NgKEASBlQccmNgKAAUGowgIoAgAiAEGl4wAgZUGAAWoQMAw9CyBlQePNADYCeCBlQb4/NgJ0IGVBxyY2AnBBqMICKAIAIgBBpeMAIGVB8ABqEDAMPAsgZUGI0AA2AmggZUHNPzYCZCBlQccmNgJgQajCAigCACIAQaXjACBlQeAAahAwDDsLDDILIAEoAowBIUIjAEHQAGsiYyQAAkACQAJAAkACQCBCKAIARQRAIAAoAgQNASBCKQMQIgIgAiABKQMQIgd/IgggB35SDQIgQikDGCICIAIgASkDGCImfyIGICZ+Ug0CIEIpAyAiAiACIAEpAyAiHX8iBSAdflINAiBCKQMoIgIgAiABKQMoIhp/IgIgGn5SDQICQAJAIAAoAgAOAwEAAQALIAEoAjBBBEcNBCBCKAIwQQRHDQUgASgCPCF3IAEoAjghYSABKAI0IWwgQigCPCFUIEIoAjghXSBCKAI0IVYgAqchUwJAAkACQAJAIAEoAgAiAA4TAAEBAQEBAQEBAQEBAQEBAQEBAAELIGytIgMgB0IChiAAQSRsQZSaAWo0AgB/Ug0AIGGtIgIgAyAmflINACB3rSACIB1+UQ0BCyAaQgBXDQEgJkIAVw0BIB1CAFcNASAHpyIAQQBMDQEgASgCwAEhQCAmQnyDIQMgJkIDgyEJIABBAnQhPwNAIHcgBKdsIQBCACEKA0AgYSAKp2wgAGohPkIAIR5CACECQgAhIiAmQgRaBEADQCBAID4gbCACpyI9bGpqQQAgP/wLACBAID4gbCA9QQFybGpqQQAgP/wLACBAID4gbCA9QQJybGpqQQAgP/wLACBAID4gbCA9QQNybGpqQQAgP/wLACACQgR8IQIgIkIEfCIiIANSDQALCyAJQgBSBEADQCBAID4gbCACp2xqakEAID/8CwAgAkIBfCECIB5CAXwiHiAJUg0ACwsgCkIBfCIKIB1SDQALIARCAXwiBCAaUg0ACwwBCyAHICZ+IB1+IBp+pyIAQQBMDQAgASgCwAFBACAAQQJ0/AsACyBTQQBMDQAgCKciWEEATA0AICZCAFcNACAGpyJaQQBMDQAgHUIAVw0AIBpCAFcNACAFpyJNQQBMDQAgB6cieEEATA0AIHhBAnQhWyBCKALAASFeIAEoAsABIVAgeEEDcSFZIHhBfHEhASAHQgKGIiBC/P///w+DISQgViAmpyJSbK0hJSBdIB2nIk5srSEjIFQgGqciTGytIR8gVq0hGSBdrSEbIFStIRcgbK0hHCBhrSEYIHetIRVCACEKIHhBBEkhSQNAIEwgaGwhUSAkIAogH34iEnwhEEIAIRQDQCAQIBQgF34iAnwhEyACIBJ8IRYgICAUIBV+IhF8IQ8gUCB3IBSnIgBsaiFKIF4gACBRaiBUbGohS0EAIVdCACEhA0AgTiBXbCFHIBMgISAjfiICfCEOIAIgFnwhDEIAIQQDQCAOIAQgG34iAnwhCyACIAx8IQcgDyAEIBh+IgJ8IQkgAiARfCEIIEogYSAEpyIAbGohRiBLIAAgR2ogXWxqIUhBACFPQgAhHgNAIE8gUmwhRSALIB4gJX4iAnwhBiACIAd8IQVCACECA0AgRiBsIAKnIgBsaiFlIEggACBFaiBWbGohQSBQIAkgAiAcfiIDfKdqIUQgUCADIAh8p2ohQyAGIAIgGX4iA3ynIUIgAyAFfKchQEEAIWIDQCBBIFsgYmwiPWohcEEAIQACQAJAIEkNACBeID0gQGpqIERJIF4gPSBCamogQ0txDQADQCBlIABBAnQiPmoiPSA+IHBq/QACACA9/QACAP3kAf0LAgAgAEEEaiIAIAFHDQALIAEiACB4Rg0BCyAAQX9zIHhqIewBQQAhXCBZBEADQCBlIABBAnQiPmoiPSA+IHBqKgIAID0qAgCSOAIAIABBAWohACBcQQFqIlwgWUcNAAsLIOwBQQNJDQADQCBlIABBAnQiP2oiPSA/IHBqKgIAID0qAgCSOAIAIGUgP0EEaiI+aiI9ID4gcGoqAgAgPSoCAJI4AgAgZSA/QQhqIj5qIj0gPiBwaioCACA9KgIAkjgCACBlID9BDGoiPmoiPSA+IHBqKgIAID0qAgCSOAIAIABBBGoiACB4Rw0ACwsgYkEBaiJiIFhHDQALIAJCAXwiAiAmUg0ACyAeQgF8IR4gT0EBaiJPIFpHDQALIARCAXwiBCAdUg0ACyAhQgF8ISEgV0EBaiJXIE1HDQALIBRCAXwiFCAaUg0ACyAKQgF8IQogaEEBaiJoIFNHDQALCyBjQdAAaiQADAULIGNB/iA2AkggY0HswAA2AkQgY0HHJjYCQEGowgIoAgAiAEGl4wAgY0FAaxAwDD4LIGNBo8AANgI4IGNBrMAANgI0IGNBxyY2AjBBqMICKAIAIgBBpeMAIGNBMGoQMAw9CyBjQd7aADYCKCBjQa3AADYCJCBjQccmNgIgQajCAigCACIAQaXjACBjQSBqEDAMPAsgY0GI0AA2AhggY0G8wAA2AhQgY0HHJjYCEEGowgIoAgAiAEGl4wAgY0EQahAwDDsLIGNB4dAANgIIIGNBvcAANgIEIGNBxyY2AgBBqMICKAIAIgBBpeMAIGMQMAw6CwwxCyABKAKMASFeIAEoApABIVMjAEFAaiJWJAACQAJAAkAgXigCAEUEQAJAAkACQCAAKAIADgMBAAEACyBeKAIwQQRHDQMgASgCMEEERw0EIFMoAjBBBEcNASABKQMoIgdCAFcNACABKQMQIg5CAFcNACABKQMgIgkgACgCBCIArCIFVw0AIAEpAxgiC0IAVw0AIAEoAjwhTiABKAI0IVggUygCPCFMIFMoAjQhSSBeKAI8IVEgXigCNCFKIA5CA4MhDCAOQnyDIQMgASgCOCJZIABsIUsgXigCOCJaIABsIUcgUygCOCJNIAAgXikDICIIpyJGa2whSANAIFEgIaciAGwiRSBHaiFBIAAgTmwiWyBLaiFSIAAgTGwiRCBIaiFDQQAhXSAFIQQDQCBZIF1sIQAgBKchPgJAIAQgCFMEQCABKALAASI9IAAgUmpqIUIgXigCwAEiACBBIFogXWxqaiFAID0gPiBZbGogW2ohPyAAID4gWmxqIEVqIT5CACEKA0AgPyBYIAqnIgBsIj1qIVAgPiAAIEpsIgBqIVdCACECAkACQCAOQgRUDQAgPSBCaiAAIEBqa0EQSQ0AA0AgUCACp0ECdCIAaiAAIFdq/QACAP0LAgAgAkIEfCICIANSDQALIAMiAiAOUQ0BCyAOIAJCf4V8ITNCACEUIAxCAFIEQANAIFAgAqdBAnQiAGogACBXaioCADgCACACQgF8IQIgFEIBfCIUIAxSDQALCyAzQgNUDQADQCBQIAKnQQJ0Ij1qID0gV2oqAgA4AgAgUCA9QQRqIgBqIAAgV2oqAgA4AgAgUCA9QQhqIgBqIAAgV2oqAgA4AgAgUCA9QQxqIgBqIAAgV2oqAgA4AgAgAkIEfCICIA5SDQALCyAKQgF8IgogC1INAAsMAQsgASgCwAEiPSAAIFJqaiFCIFMoAsABIgAgQyBNIF1samohQCA9ID4gWWxqIFtqIT8gACA+IEZrIE1saiBEaiE+QgAhCgNAID8gWCAKpyIAbCI9aiFQID4gACBJbCIAaiFXQgAhAgJAAkAgDkIEVA0AID0gQmogACBAamtBEEkNAANAIFAgAqdBAnQiAGogACBXav0AAgD9CwIAIAJCBHwiAiADUg0ACyADIgIgDlENAQsgDiACQn+FfCE0QgAhFCAMQgBSBEADQCBQIAKnQQJ0IgBqIAAgV2oqAgA4AgAgAkIBfCECIBRCAXwiFCAMUg0ACwsgNEIDVA0AA0AgUCACp0ECdCI9aiA9IFdqKgIAOAIAIFAgPUEEaiIAaiAAIFdqKgIAOAIAIFAgPUEIaiIAaiAAIFdqKgIAOAIAIFAgPUEMaiIAaiAAIFdqKgIAOAIAIAJCBHwiAiAOUg0ACwsgCkIBfCIKIAtSDQALCyBdQQFqIV0gBEIBfCIEIAlSDQALICFCAXwiISAHUg0ACwsgVkFAayQADAQLIFZBtNAANgIIIFZBhsEANgIEIFZBxyY2AgBBqMICKAIAIgBBpeMAIFYQMAw8CyBWQf4gNgI4IFZBrsEANgI0IFZBxyY2AjBBqMICKAIAIgBBpeMAIFZBMGoQMAw7CyBWQanPADYCKCBWQf3AADYCJCBWQccmNgIgQajCAigCACIAQaXjACBWQSBqEDAMOgsgVkGI0AA2AhggVkGEwQA2AhQgVkHHJjYCEEGowgIoAgAiAEGl4wAgVkEQahAwDDkLDDALIAEoAowBIUAgASgCkAEhPyMAQeAAayJJJAACQAJAAkACQAJAAkAgQCgCAEUEQCA/KAIwID8oAgBBJGxBmJoBaigCAEcNASA/NQI4IgIgPykDGCIJID8oAjQiSq1+Ug0BID81AjwgAiA/KQMgIgh+Ug0BIEAoAjBBBEcNAiBANQI4IgIgQCkDGCIGIEAoAjQiS61+Ug0CIEA1AjwgAiBAKQMgIgV+Ug0CIAEoAjAgASgCAEEkbEGYmgFqKAIARw0DIAE1AjgiBCABKQMYIgMgASgCNCJHrX5SDQMgATUCPCAEIAEpAyAiAn5SDQMgAiAFUg0EIAMgBlINBCBAKQMQIgMgASkDEFINBCBAKQMoIgIgASkDKFINBCAFIAhSDQUgBiAJUg0FIAMgPykDEFINBSACID8pAyhSDQUCQAJAIAAoAgAOAwEAAQALIAggCX4gAn6nIj4gACgCCCI9akEBayA9bSI9IAAoAgRsIgAgACA9aiI9ID4gPSA+SBsiRk4NACADpyJIQQBMDQAgPygCwAEhRSBAKALAASFBIAEoAsABIUQDQCBFIAAgSmxqIUMgQSAAIEtsaiFCIEQgACBHbGohQEEAIQEDQEGA/AEgQiABQQJ0IlFqKgIAIpICi0MAAIB3lEMAAIAIlEGAgICIByCSArwiP0EBdCI+QYCAgHhxIj0gPUGAgICIB00bQQF2QYCAgDxqvpK8Ij1BDXZBgPgBcSA9Qf8fcWogPkGAgIB4SxsgP0EQdkGAgAJxckECdEHw1ARqKgIAIpMCjBBFIZICIEAgUWogQyBRaioCAEMAAIA/IJICQwAAgD+SlSKSApQgkwJDAACAPyCSApOUQwAAgD+SlDgCACABQQFqIgEgSEcNAAsgAEEBaiIAIEZHDQALCyBJQeAAaiQADAYLIElB/iA2AlggSUHvxQA2AlQgSUHHJjYCUEGowgIoAgAiAEGl4wAgSUHQAGoQMAw9CyBJQbLUADYCSCBJQbvFADYCRCBJQccmNgJAQajCAigCACIAQaXjACBJQUBrEDAMPAsgSUG42gA2AjggSUG8xQA2AjQgSUHHJjYCMEGowgIoAgAiAEGl4wAgSUEwahAwDDsLIElBn80ANgIoIElBvcUANgIkIElBxyY2AiBBqMICKAIAIgBBpeMAIElBIGoQMAw6CyBJQeTOADYCGCBJQb7FADYCFCBJQccmNgIQQajCAigCACIAQaXjACBJQRBqEDAMOQsgSUHY1AA2AgggSUG/xQA2AgQgSUHHJjYCAEGowgIoAgAiAEGl4wAgSRAwDDgLDC8LIAEoAowBIVgjAEEwayJZJAACQCBYKAIARQRAAkAgWCkDECIPIAEpAxBSDQAgWCkDGCIOIAEpAxhSDQAgWCkDICIMIAEpAyBSDQAgWCkDKCILIAEpAyhSDQACQAJAAkAgACgCAA4DAQABAAsgWCgCMEEERw0BIAtCAFcNACAMQgBXDQAgDiAANAIEIgNXDQAgASgCPCFSIAEoAjghTiABKAI0IUwgWCgCPCFJIFgoAjghUSBYKAI0IUogASoCRCGSAiAANAIIIQkgD7khxwIgD6ciTUFwcSI+IE1BD3EiSyBNQQNxIkdrIkZqIT0gD0J+gyEIIA9CAYMhBiAPQnyDIQUgD0IDgyEHID5BAWsiSEEEdkEBaiIAQf7///8BcSFFIABBAXEhQQNAIFIgCqciAGwhRCAAIElsIUNCACEUA0AgTiAUpyIAbCFCIAAgUWwhQCADIQIDQCBYKALAASBKIAKnIj9saiBAaiBDaiFaRAAAAAAAAAAAIcUCRAAAAAAAAAAAIcYCAkAgD0IAVyIADQBCACENQgAhBEIAISAgD0IDVgRAA0AgxgIgWiAEp0ECdCJbaioCALugIFogW0EEcmoqAgC7oCBaIFtBCHJqKgIAu6AgWiBbQQxyaioCALugIcYCIARCBHwhBCAgQgR8IiAgBVINAAsLIAdQDQADQCDGAiBaIASnQQJ0aioCALugIcYCIARCAXwhBCANQgF8Ig0gB1INAAsLIAEoAsABID8gTGxqIEJqIERqIVsCQCAADQAgxgIgxwKjtiGVAkIAIQRCACENIA9CAVIEQANAIFsgBKdBAnQiAGogACBaaioCACCVApMilAI4AgAgWyAAQQRyIgBqIAAgWmoqAgAglQKTIpMCOAIAIMUCIJQCIJQClLugIJMCIJMClLugIcUCIARCAnwhBCANQgJ8Ig0gCFINAAsLIAZQDQAgWyAEp0ECdCIAaiAAIFpqKgIAIJUCkyKTAjgCACDFAiCTAiCTApS7oCHFAgtDAACAPyCSAiDFAiDHAqO2kpGVIZMCAkAgPkEATA0AIJMC/RMhpQJBACFkQQAhYiBIQQ9HBEADQCBbIGRBAnQiAGoiPyClAiA//QAAAP3mAf0LAAAgPyClAiA//QAAEP3mAf0LABAgPyClAiA//QAAIP3mAf0LACAgPyClAiA//QAAMP3mAf0LADAgWyAAQcAAcmoiACClAiAA/QAAAP3mAf0LAAAgACClAiAA/QAAEP3mAf0LABAgACClAiAA/QAAIP3mAf0LACAgACClAiAA/QAAMP3mAf0LADAgZEEgaiFkIGJBAmoiYiBFRw0ACwsgQUUNACBbIGRBAnRqIgAgpQIgAP0AAAD95gH9CwAAIAAgpQIgAP0AABD95gH9CwAQIAAgpQIgAP0AACD95gH9CwAgIAAgpQIgAP0AADD95gH9CwAwCwJAID4gTU4NACA+IQAgS0EETwRAIJMC/RMhpQJBACEAA0AgWyAAID5qQQJ0aiI/IKUCID/9AAIA/eYB/QsCACAAQQRqIgAgRkcNAAsgPSEAIEdFDQELA0AgWyAAQQJ0aiI/IJMCID8qAgCUOAIAIABBAWoiACBNRw0ACwsgAiAJfCICIA5TDQALIBRCAXwiFCAMUg0ACyAKQgF8IgogC1INAAsLIFlBMGokAAwDCyBZQanPADYCCCBZQYDGADYCBCBZQccmNgIAQajCAigCACIAQaXjACBZEDAMOQsgWUHkzgA2AhggWUH6xQA2AhQgWUHHJjYCEEGowgIoAgAiAEGl4wAgWUEQahAwDDgLIFlB/iA2AiggWUG0xgA2AiQgWUHHJjYCIEGowgIoAgAiAEGl4wAgWUEgahAwDDcLDC4LIAEoAowBIVkjAEEwayJTJAACQCBZKAIARQRAAkAgWSkDECIMIAEpAxBSDQAgWSkDGCILIAEpAxhSDQAgWSkDICIHIAEpAyBSDQAgWSkDKCIJIAEpAyhSDQACQAJAAkAgACgCAA4DAQABAAsgWSgCMEEERw0BIAlCAFcNACAHQgBXDQAgCyAANAIEIgNXDQAgASgCPCFbIAEoAjghUiABKAI0IU4gWSgCPCFMIFkoAjghSSBZKAI0IVEgASoCRCGTAiAMpyJaQQJ0IUogADQCCCEGIAy5IccCIFpBcHEiPiBaQQ9xIksgWkEDcSJHayJGaiE9IAxCfIMhBCAMQgODIQggPkEBayJIQQR2QQFqIgBB/v///wFxIUUgAEEBcSFBA0AgWyANpyIAbCFEIAAgTGwhQ0IAIQoDQCBSIAqnIgBsIUIgACBJbCFAIAMhAgNAIFkoAsABIFEgAqciAGxqIEBqIENqIVgCQCAMQgBXBEBEAAAAAAAAAAAhxQIMAQtEAAAAAAAAAAAhxQJCACEdQgAhBUIAISAgDEIDVgRAA0AgxQIgWCAFp0ECdCI/aioCACKSAiCSApS7oCBYID9BBHJqKgIAIpICIJIClLugIFggP0EIcmoqAgAikgIgkgKUu6AgWCA/QQxyaioCACKSAiCSApS7oCHFAiAFQgR8IQUgIEIEfCIgIARSDQALCyAIUA0AA0AgxQIgWCAFp0ECdGoqAgAikgIgkgKUu6AhxQIgBUIBfCEFIB1CAXwiHSAIUg0ACwsgASgCwAEgACBObGogQmogRGoiTSBYIEr8CgAAQwAAgD8gkwIgxQIgxwKjtpKRlSGSAgJAID5BAEwNACCSAv0TIaUCQQAhZEEAIWIgSEEPRwRAA0AgTSBkQQJ0IgBqIj8gpQIgP/0AAAD95gH9CwAAID8gpQIgP/0AABD95gH9CwAQID8gpQIgP/0AACD95gH9CwAgID8gpQIgP/0AADD95gH9CwAwIE0gAEHAAHJqIgAgpQIgAP0AAAD95gH9CwAAIAAgpQIgAP0AABD95gH9CwAQIAAgpQIgAP0AACD95gH9CwAgIAAgpQIgAP0AADD95gH9CwAwIGRBIGohZCBiQQJqImIgRUcNAAsLIEFFDQAgTSBkQQJ0aiIAIKUCIAD9AAAA/eYB/QsAACAAIKUCIAD9AAAQ/eYB/QsAECAAIKUCIAD9AAAg/eYB/QsAICAAIKUCIAD9AAAw/eYB/QsAMAsCQCA+IFpODQAgPiEAIEtBBE8EQCCSAv0TIaUCQQAhAANAIE0gACA+akECdGoiPyClAiA//QACAP3mAf0LAgAgAEEEaiIAIEZHDQALID0hACBHRQ0BCwNAIE0gAEECdGoiPyCSAiA/KgIAlDgCACAAQQFqIgAgWkcNAAsLIAIgBnwiAiALUw0ACyAKQgF8IgogB1INAAsgDUIBfCINIAlSDQALCyBTQTBqJAAMAwsgU0GpzwA2AgggU0HFxgA2AgQgU0HHJjYCAEGowgIoAgAiAEGl4wAgUxAwDDgLIFNB5M4ANgIYIFNBv8YANgIUIFNBxyY2AhBBqMICKAIAIgBBpeMAIFNBEGoQMAw3CyBTQf4gNgIoIFNB9sYANgIkIFNBxyY2AiBBqMICKAIAIgBBpeMAIFNBIGoQMAw2CwwtCyABKAKMASF5IAEoApABIYEBIAEhPyMAQTBrInUkAAJAIHkoAgBFBEACQCB5KQMQIh8gASkDEFINACB5KQMYIhkgASkDGFINACB5KQMgIhsgASkDIFINACB5KQMoIhcgASkDKFINACAfIIEBKQMQUg0AIBkggQEpAxhSDQAgGyCBASkDIFINACAXIIEBKQMoUg0AAkACQAJAIAAoAgAOAwEAAQALIHkoAjBBBEcNASAXQgBXDQAgG0IAVw0AIBkgACgCBCJErCIDVw0AID8qAkQhlQIgH7QhlAIgACgCCCJDrCEcIB+nIm1BcHEiPiBtQQ9xIkIgbUEDcSJ2ayJjaiEBIG1BAnQiACCBASgCNCJsIERsaq0hGCA/KAI0InggRGwiQCAAaq0hFSBtQXxxIT0gH0J+gyESIB9CAYMhECB5KAI0Ik8gQ2whXiBDIHhsIVAgQyBsbCFXID5BAWsiZUEEdkEBaiIAQf7///8BcSFwIABBAXEhdyBEIE9srSETIECtIRYgeSgCOCJTrSERIHkoAjwiWa0hDyA/KAI4IlitIQ4gPygCPCJarSEMIIEBKAI4Ik2tIQsggQEoAjwiW60hByBtQQhJIWEgQkEESSFUA0AgWiAFpyIAbCFSIAAgW2whTiAAIFlsIUwgBSAHfiAYfCEJIAUgDH4iAiAVfCEIIAUgD34gE3whBiACIBZ8IQRCACENA0AgWCANpyIAbCFJIAAgTWwhUSAAIFNsIUogCSALIA1+fKchSyAIIA0gDn4iAnynIUcgBiANIBF+fKchRiACIAR8pyFIQQAhgAEgAyECA0AggQEoAsABIkUgbCACpyJCbGogUWogTmoheiB5KALAASJAIEIgT2xqIEpqIExqIUQCQCAfQgBXBEBEAAAAAAAAAAAhxQJEAAAAAAAAAAAhxgIMAQtEAAAAAAAAAAAhxgJCACEKRAAAAAAAAAAAIcUCQgAhIiAfQgFSBEADQCDGAiBEIAqnQQJ0IgBqKgIAIpMCIAAgemoqAgCUu6AgRCAAQQRyIgBqKgIAIpICIAAgemoqAgCUu6AhxgIgxQIgkwIgkwKUu6AgkgIgkgKUu6AhxQIgCkICfCEKICJCAnwiIiASUg0ACwsgEFANACDGAiBEIAqnQQJ0IgBqKgIAIpICIAAgemoqAgCUu6AhxgIgxQIgkgIgkgKUu6AhxQILIFAggAFsIV0glQIglAKUIMUCtiKSApIhkwIgPygCwAEiViBCIHhsaiBJaiBSaiFrAkAgbUEATCJDDQBBACFpQQAhAAJAIGENACBIIF1qIFZqIF4ggAFsIEZqIEBqa0EQSQ0AA0AgayAAQQJ0IkBqIEAgRGr9AAIA/QsCACAAQQRqIgAgPUcNAAsgPSIAIG1GDQELIABBf3MgbWoh7QEgdgRAA0AgayAAQQJ0IkBqIEAgRGoqAgA4AgAgAEEBaiEAIGlBAWoiaSB2Rw0ACwsg7QFBA0kNAANAIGsgAEECdCJCaiBCIERqKgIAOAIAIGsgQkEEaiJAaiBAIERqKgIAOAIAIGsgQkEIaiJAaiBAIERqKgIAOAIAIGsgQkEMaiJAaiBAIERqKgIAOAIAIABBBGoiACBtRw0ACwsgkgIglAKVIZICIMYCtowgkwKVIZMCAkAgPkEATCJBDQAgkwL9EyGlAkEAIVxBACFpIGVBD0cEQANAIGsgXEECdCIAaiJAIKUCIED9AAAA/eYB/QsAACBAIKUCIED9AAAQ/eYB/QsAECBAIKUCIED9AAAg/eYB/QsAICBAIKUCIED9AAAw/eYB/QsAMCBrIABBwAByaiIAIKUCIAD9AAAA/eYB/QsAACAAIKUCIAD9AAAQ/eYB/QsAECAAIKUCIAD9AAAg/eYB/QsAICAAIKUCIAD9AAAw/eYB/QsAMCBcQSBqIVwgaUECaiJpIHBHDQALCyB3RQ0AIGsgXEECdGoiACClAiAA/QAAAP3mAf0LAAAgACClAiAA/QAAEP3mAf0LABAgACClAiAA/QAAIP3mAf0LACAgACClAiAA/QAAMP3mAf0LADALIJUCIJICkiGkAgJAID4gbU4iRA0AID4hACBURQRAIJMC/RMhpQJBACEAA0AgayAAID5qQQJ0aiJAIKUCIED9AAIA/eYB/QsCACAAQQRqIgAgY0cNAAsgASEAIHZFDQELA0AgayAAQQJ0aiJAIJMCIEAqAgCUOAIAIABBAWoiACBtRw0ACwsgpAKRIZICAkAgQw0AQQAhXEEAIQACQCBhDQAgeiBWIEcgXWpqSSBFIFcggAFsIEtqaiBrS3ENAANAIGsgAEECdCJCaiJAIEIgemr9AAIAIED9AAIA/eQB/QsCACAAQQRqIgAgPUcNAAsgPSIAIG1GDQELIABBf3MgbWoh7gEgdgRAA0AgayAAQQJ0IkJqIkAgQiB6aioCACBAKgIAkjgCACAAQQFqIQAgXEEBaiJcIHZHDQALCyDuAUEDSQ0AA0AgayAAQQJ0IkNqIkAgQyB6aioCACBAKgIAkjgCACBrIENBBGoiQmoiQCBCIHpqKgIAIEAqAgCSOAIAIGsgQ0EIaiJCaiJAIEIgemoqAgAgQCoCAJI4AgAgayBDQQxqIkJqIkAgQiB6aioCACBAKgIAkjgCACAAQQRqIgAgbUcNAAsLQwAAgD8gkgKVIZICAkAgQQ0AIJIC/RMhpQJBACFiQQAhXCBlQQ9HBEADQCBrIGJBAnQiAGoiQCClAiBA/QAAAP3mAf0LAAAgQCClAiBA/QAAEP3mAf0LABAgQCClAiBA/QAAIP3mAf0LACAgQCClAiBA/QAAMP3mAf0LADAgayAAQcAAcmoiACClAiAA/QAAAP3mAf0LAAAgACClAiAA/QAAEP3mAf0LABAgACClAiAA/QAAIP3mAf0LACAgACClAiAA/QAAMP3mAf0LADAgYkEgaiFiIFxBAmoiXCBwRw0ACwsgd0UNACBrIGJBAnRqIgAgpQIgAP0AAAD95gH9CwAAIAAgpQIgAP0AABD95gH9CwAQIAAgpQIgAP0AACD95gH9CwAgIAAgpQIgAP0AADD95gH9CwAwCwJAIEQNACA+IQAgVEUEQCCSAv0TIaUCQQAhAANAIGsgACA+akECdGoiQCClAiBA/QACAP3mAf0LAgAgAEEEaiIAIGNHDQALIAEhACB2RQ0BCwNAIGsgAEECdGoiQCCSAiBAKgIAlDgCACAAQQFqIgAgbUcNAAsLIIABQQFqIYABIAIgHHwiAiAZUw0ACyANQgF8Ig0gG1INAAsgBUIBfCIFIBdSDQALCyB1QTBqJAAMAwsgdUGpzwA2AgggdUGGxwA2AgQgdUHHJjYCAEGowgIoAgAiAEGl4wAgdRAwDDcLIHVB4tcANgIYIHVBgMcANgIUIHVBxyY2AhBBqMICKAIAIgBBpeMAIHVBEGoQMAw2CyB1Qf4gNgIoIHVBpMgANgIkIHVBxyY2AiBBqMICKAIAIgBBpeMAIHVBIGoQMAw1CwwsCyABKAKMASFZIAEhPiMAQTBrIlMkAAJAIFkoAgBFBEACQCBZKQMQIhAgASkDEFINACBZKQMYIhMgASkDGFINACBZKQMgIgIgASkDIFINACBZKQMoIhEgASkDKFINAAJAAkACQCAAKAIADgMBAAEACyBZKAIwQQRHDQEgAqciTiA+KAJEIgFqQQFrIAFtIUwgACgCBCI/IAFODQAgEUIAVw0AIBNCAFcNACA+KAI8IUkgPigCOCFaID4oAjQhTSBZKAI8IUMgWSgCOCFRIFkoAjQhSiAANAIIIQ4gECATfiEMIAGsIQsgTKwhByAQpyJYQXBxIj0gWEEPcSJLIFhBA3EiR2siRmohASAQQn6DIQkgEEIBgyEIIBBCfIMhBiAQQgODIQ8gPUEBayJIQQR2QQFqIgBB/v///wFxIUUgAEEBcSFBID+sISEDQCBMIAcgIX4iAqdqIgAgTiAAIE5IG6wiFiACVQRAQwAAgD9EAAAAAAAAAAAgDCAWIAJ9frkixwKjtkO9N4Y1kpGVIpMC/RMhqAJCACEiA0AgIqchQAJ7IBBCAFUEQCBZKALAASBAIENsaiFERAAAAAAAAAAAIcUCIAIhBANAIEQgUSAEp2xqIQBCACEUA0AgACBKIBSnbGohQkIAIQVCACEDIBBCBFoEQANAIMUCIEIgBadBAnQiP2oqAgC7oCBCID9BBHJqKgIAu6AgQiA/QQhyaioCALugIEIgP0EMcmoqAgC7oCHFAiAFQgR8IQUgA0IEfCIDIAZSDQALC0IAIQMgD0IAUgRAA0AgxQIgQiAFp0ECdGoqAgC7oCHFAiAFQgF8IQUgA0IBfCIDIA9SDQALCyAUQgF8IhQgE1INAAsgBEIBfCIEIBZTDQALIEAgSWwiVyA+KALAAWohQiDFAiDHAqO2IZUCRAAAAAAAAAAAIcUCIAIhBANAIEIgWiAEpyIAbGohQCBEIAAgUWxqIT9CACEUA0AgQCBNIBSnIgBsaiFbID8gACBKbGohUkIAIQVCACEDIBBCAVIEQANAIFsgBadBAnQiAGogACBSaioCACCVApMilAI4AgAgWyAAQQRyIgBqIAAgUmoqAgAglQKTIpICOAIAIMUCIJQCIJQClLugIJICIJIClLugIcUCIAVCAnwhBSADQgJ8IgMgCVINAAsLIAinBEAgWyAFp0ECdCIAaiAAIFJqKgIAIJUCkyKSAjgCACDFAiCSAiCSApS7oCHFAgsgFEIBfCIUIBNSDQALIARCAXwiBCAWUw0AC0MAAIA/IMUCIMcCo7ZDvTeGNZKRlSKSAv0TDAELIEAgSWwhVyCTAiGSAiCoAgshpwICQAJAAkAgPUEASgRAIAIhAyA9IFhODQEgkgL9EyGlAgNAIFogA6dsIUBCACEFA0AgPigCwAEgTSAFp2xqIEBqIFdqIUJBACFPQQAhYiBIQQ9HBEADQCBCIE9BAnQiAGoiPyCnAiA//QAAAP3mAf0LAAAgPyCnAiA//QAAEP3mAf0LABAgPyCnAiA//QAAIP3mAf0LACAgPyCnAiA//QAAMP3mAf0LADAgQiAAQcAAcmoiACCnAiAA/QAAAP3mAf0LAAAgACCnAiAA/QAAEP3mAf0LABAgACCnAiAA/QAAIP3mAf0LACAgACCnAiAA/QAAMP3mAf0LADAgT0EgaiFPIGJBAmoiYiBFRw0ACwsgQQRAIEIgT0ECdGoiACCnAiAA/QAAAP3mAf0LAAAgACCnAiAA/QAAEP3mAf0LABAgACCnAiAA/QAAIP3mAf0LACAgACCnAiAA/QAAMP3mAf0LADALQQAhTyA9IQACQCBLQQRPBEADQCBCID0gT2pBAnRqIgAgpQIgAP0AAgD95gH9CwIAIE9BBGoiTyBGRw0ACyABIQAgR0UNAQsDQCBCIABBAnRqIj8gkgIgPyoCAJQ4AgAgAEEBaiIAIFhHDQALCyAFQgF8IgUgE1INAAsgA0IBfCIDIBZTDQALDAMLID0gWEgNAQwCCwNAIFogA6dsIT9CACEFA0AgPigCwAEgTSAFp2xqID9qIFdqIUBBACFPQQAhYiBIQQ9HBEADQCBAIE9BAnQiAGoiQiCnAiBC/QAAAP3mAf0LAAAgQiCnAiBC/QAAEP3mAf0LABAgQiCnAiBC/QAAIP3mAf0LACAgQiCnAiBC/QAAMP3mAf0LADAgQCAAQcAAcmoiACCnAiAA/QAAAP3mAf0LAAAgACCnAiAA/QAAEP3mAf0LABAgACCnAiAA/QAAIP3mAf0LACAgACCnAiAA/QAAMP3mAf0LADAgT0EgaiFPIGJBAmoiYiBFRw0ACwsgQQRAIEAgT0ECdGoiACCnAiAA/QAAAP3mAf0LAAAgACCnAiAA/QAAEP3mAf0LABAgACCnAiAA/QAAIP3mAf0LACAgACCnAiAA/QAAMP3mAf0LADALIAVCAXwiBSATUg0ACyAWIANCAXwiA1UNAAsMAQsgPigCwAEgV2ohQiCSAv0TIaUCIAIhAwNAIEIgWiADp2xqIUBCACEFA0AgQCBNIAWnbGohREEAIU8gPSEAAkAgS0EETwRAA0AgRCA9IE9qQQJ0aiIAIKUCIAD9AAIA/eYB/QsCACBPQQRqIk8gRkcNAAsgASEAIEdFDQELA0AgRCAAQQJ0aiI/IJICID8qAgCUOAIAIABBAWoiACBYRw0ACwsgBUIBfCIFIBNSDQALIANCAXwiAyAWUw0ACwsgIkIBfCIiIBFSDQALCyAOICF8IiEgC1MNAAsLIFNBMGokAAwDCyBTQanPADYCCCBTQbXIADYCBCBTQccmNgIAQajCAigCACIAQaXjACBTEDAMNgsgU0HkzgA2AhggU0GvyAA2AhQgU0HHJjYCEEGowgIoAgAiAEGl4wAgU0EQahAwDDULIFNB/iA2AiggU0H+yAA2AiQgU0HHJjYCIEGowgIoAgAiAEGl4wAgU0EgahAwDDQLDCsLIAEoAowBIU4gASgCkAEhUiMAQeABayJbJAAgASgCPCFGIAEoAjghUSABKAI0IUogASkDKCELIAEpAyAhByABKQMYIQkgUigCPCFLIFIoAjghRyBSKAI0IUwgUikDKCEWIFIpAyAhEyBONQI8IRcgTjUCOCEcIE4oAjQhSCBOKQMoIQggTikDICEGIE4pAxghESBSKQMYIRogTigCACFCIAA0AgghDiAANAIEIQwgASgCMCFAIAEpAxAhBSBSKQMQIQ8gTigCMCE/IE4pAxAhBAJAIFIoAjAiRCBSKAIAIkNBJGwiPkGYmgFqKAIAIj1HDQAgTK0iAyAPIEStfiA+QZSaAWo0AgB/Ug0AIEetIgIgAyAaflINACBLrSACIBN+USFXCwJAIAUgEVEEQCAJIBpRBEAgByATUQRAIAsgFlEEQCBCQSRsIj5BmJoBaigCACA/RgRAID0gREYEQCBAQQRGBEAgSkEDSwRAIEogUU0EQCBGIFFPBEAgPkGwmgFqKAIAIUkgFiAIfyEYIBMgBn8hFQJAAkAgACgCAA4DAAEMAQsgQyBJRg0LIA8gSUEkbCIBQZiaAWo1AgB+IAFBlJoBajQCAH8hNSAWQgBXDQsgE0IAVw0LIBpCAFcNCyABQaSaAWooAgAhQiA1pyFAIA+nIT8gGkJ+gyEGIBpCAYMhAyAAKAIQIQADQCBLIAqnbCE+QgAhBANAIEcgBKdsIT1CACEFQgAhAiAaQgFSBEADQCBSKALAASA+aiA9aiBMIAWnIgFsaiAAID8gQhEFACBSKALAASA+aiA9aiBMIAFBAXJsaiAAIEBqIgAgPyBCEQUAIAVCAnwhBSAAIEBqIQAgAkICfCICIAZSDQALCyADpwRAIFIoAsABID5qID1qIEwgBadsaiAAID8gQhEFACAAIEBqIQALIARCAXwiBCATUg0ACyAKQgF8IgogFlINAAsMCwsgEyAafiIlIBZ+IghCASAOIAggEVMiPRsiAnxCAX0gAn8hBQJAIBEgDkIBID0bIgZ8QgF9IAZ/IgIgDCAGIAwgBn8iA359fiIJIAIgCXwiAiARIAIgEVMbIiNTBEAgAyAFfiIDIAMgBXwiAiAIIAIgCFMbIh9TDQELEAMQ1wEMCwsgPkGsmgFqKAIAIUUgUkHAAWogAEEQaiBDIElGGygCACFBIA8gSUEkbCIAQZiaAWo1AgB+IABBlJoBajQCAH9C/////w+DIRIgBKchRCBGrSEQIFGtIRMgSq0hFiBLrSERIEetIQ8gTK0hDgNAIAkhAiADQhB8IgggHyAIIB9TIkMbIgwgA1UEQANAIAJCEHwiBiAjIAYgI1MiQhsiGSACfadBAnQhQCACpyE/IAMhBANAIAQgJSAEICV/IiB+fSIFIAUgGn8iJCAafn0hGyAgIBh/IQsgJCAVfyEHAn4CQCBXDQAgUigCACBJRw0AIA8gJH4gESAgfnwgDiAbfnwMAQsgBCASfgshBSABKALAASATICR+IBAgIH58IBYgG358p2oh7wEgAiAZUwRAIE4oAsABIAcgHH4gCyAXfnynaiE9IEEgBadqIQAgAiEFA0AgRCBbQaABaiAFIAJ9p0ECdGogPSBIIAWnbGogACBFEQYAIAVCAXwiBSAZUw0ACwsg7wEgP0ECdGogW0GgAWogQPwKAAAgBEIBfCIEIAxTDQALIAYhAiBCDQALCyAIIQMgQw0ACwwKCyBbQd05NgIYIFtBxskANgIUIFtBxyY2AhBBqMICKAIAIgBBpeMAIFtBEGoQMAw8CyBbQfI6NgIIIFtBxckANgIEIFtBxyY2AgBBqMICKAIAIgBBpeMAIFsQMAw7CyBbQaQ9NgIoIFtBxMkANgIkIFtBxyY2AiBBqMICKAIAIgBBpeMAIFtBIGoQMAw6CyBbQYjQADYCOCBbQcPJADYCNCBbQccmNgIwQajCAigCACIAQaXjACBbQTBqEDAMOQsgW0Go0wA2AkggW0HAyQA2AkQgW0HHJjYCQEGowgIoAgAiAEGl4wAgW0FAaxAwDDgLIFtB6dMANgJYIFtBv8kANgJUIFtBxyY2AlBBqMICKAIAIgBBpeMAIFtB0ABqEDAMNwsgW0H0OTYCaCBbQbzJADYCZCBbQccmNgJgQajCAigCACIAQaXjACBbQeAAahAwDDYLIFtBxzw2AnggW0G7yQA2AnQgW0HHJjYCcEGowgIoAgAiAEGl4wAgW0HwAGoQMAw1CyBbQds9NgKIASBbQbrJADYChAEgW0HHJjYCgAFBqMICKAIAIgBBpeMAIFtBgAFqEDAMNAsgW0HzPTYCmAEgW0G5yQA2ApQBIFtBxyY2ApABQajCAigCACIAQaXjACBbQZABahAwDDMLIFtB4AFqJAAMKgsgASgCjAEhfCABKAKQASGDASABIT4jAEGgCGsiVSQAAkACQCB8KAIAIj1BDksNAAJAAkACQAJAAkACQAJAAkACQAJAAkACQEEBID10Qcz7AXFFBEAgPUUNASA9QQFHDQ0gVUH+IDYCmAEgVUGEzQA2ApQBIFVBxyY2ApABQajCAigCACIAQaXjACBVQZABahAwDEALIHwpAyAiAyCDASkDIFINCCCDASkDKCICIHwpAyhSDQcgPikDICADUg0GID4pAyggAlINBSB8KAIwID1BJGxBmJoBaigCAEcNBCA+KAIwQQRHDQMgfCkDECIFID4pAxBSDQIggwEpAxAiGCA+KQMYUg0BAkAgACgCAA4DCgAMAAsgAiADIBh+IhV+IgMgADQCCCICfEIBfSACfyICIAAoAgQiAax+IgQgAiAEfCICIAMgAiADUxsiE1kNCyB8KQMYIhJCAFcNCyA+NQI8IQ4gPjUCOCEMID41AjQhCyCDATUCPCEHIIMBNQI4IQkggwE1AjQhCCB8NQI8IRYgfDUCOCERIHw1AjQhECA9QSRsQaCaAWooAgAhSCCDATUCMCEGIAAoAhAgASAFpyJHQRBqbEECdGohRiBHQXBxIgFBAEoEQCABIEdBD3EiACBHQQNxIkFrIkRqIT0gAEEESSFDA0AgBCAEIBV/Ig8gFX59IgIgGH8iAyAJfiAHIA9+fCACIAMgGH59IgIgBn58IQUgAyAMfiAOIA9+fCACIAt+fKchQiADIBF+IA8gFn58IQNCACECA0AggwEoAsABIfEBID4oAsABIfABIHwoAsABIAMgAiAQfnynaiBGIEcgSBEFACDwASBCaiFFIPEBIAUgAiAIfnynaioCACKSAv0TIaUCQQAhAANAIEUgAEECdCI/aiJAIKUCID8gRmoiP/0AAAD95gEgQP0AAAD95AH9CwAAIEAgpQIgP/0AABD95gEgQP0AABD95AH9CwAQIEAgpQIgP/0AACD95gEgQP0AACD95AH9CwAgIEAgpQIgP/0AADD95gEgQP0AADD95AH9CwAwIABBEGoiACABSA0ACwJAIAEgR04NACABIQAgQ0UEQEEAIQADQCBFIAAgAWpBAnQiQGoiPyBAIEZq/QACACClAv3mASA//QACAP3kAf0LAgAgAEEEaiIAIERHDQALID0hACBBRQ0BCwNAIEUgAEECdCJAaiI/IEAgRmoqAgAgkgKUID8qAgCSOAIAIABBAWoiACBHRw0ACwsgAkIBfCICIBJSDQALIARCAXwiBCATUg0ACwwMCyABIEdOBEAgEkJ+gyEGIBJCAYMhBQNAIAQgBCAVfyICIBV+fSAYfyARfiACIBZ+fCEIQgAhAkIAIQMgEkIBUgRAA0AgfCgCwAEgAiAQfiAIfKdqIEYgRyBIEQUAIHwoAsABIAJCAYQgEH4gCHynaiBGIEcgSBEFACACQgJ8IQIgA0ICfCIDIAZSDQALCyAFpwRAIHwoAsABIAIgEH4gCHynaiBGIEcgSBEFAAsgBEIBfCIEIBNSDQALDAwLIAEgR0EPcSIAIEdBA3EiQWsiRGohPSAAQQRJIUMDQCAEIAQgFX8iDyAVfn0iAiAYfyIDIAl+IAcgD358IAIgAyAYfn0iAiAGfnwhBSADIAx+IA4gD358IAIgC358pyFCIAMgEX4gDyAWfnwhA0IAIQIDQCCDASgCwAEh8wEgPigCwAEh8gEgfCgCwAEgAiAQfiADfKdqIEYgRyBIEQUAIPIBIEJqIUUg8wEgBSACIAh+fKdqKgIAIZICIAEhAAJAIENFBEAgkgL9EyGlAkEAIQADQCBFIAAgAWpBAnQiQGoiPyBAIEZq/QACACClAv3mASA//QACAP3kAf0LAgAgAEEEaiIAIERHDQALID0hACBBRQ0BCwNAIEUgAEECdCJAaiI/IEAgRmoqAgAgkgKUID8qAgCSOAIAIABBAWoiACBHRw0ACwsgAkIBfCICIBJSDQALIARCAXwiBCATUg0ACwwLCyB8KQMgIgMggwEpAyBRBEAggwEpAygiAiB8KQMoUQRAIAMgPikDIFEEQCACID4pAyhRBEAgfCgCMEEERgRAID4oAjBBBEYEQCB8KQMQIgUgPikDEFEEQCCDASkDECIkID4pAxhRBEACQAJAIAAoAgAOAwABFAELIAMgJH4gBX4gAn6nIgBBAEoNEgwTCyACIAMgJH4iI34iAyAANAIIIgJ8QgF9IAJ/IgIgADQCBH4iBCACIAR8IgIgAyACIANTGyIfWQ0SIHwpAxgiGUIAVw0SID41AjwhGyA+NQI4IRcgPjUCNCEcIIMBNQI8IRgggwE1AjghFSB8NQI8IRIgfDUCOCEQIIMBNQIwIRMggwEoAjQickEfbCHIASB8KAI0InNBH2whyQEgckEebCHKASBzQR5sIcsBIHJBHWwhzAEgc0EdbCHNASByQRxsIc4BIHNBHGwhzwEgckEbbCHQASBzQRtsIdEBIHJBGmwh0gEgc0EabCHTASByQRlsIdQBIHNBGWwh1QEgckEYbCHWASBzQRhsIdcBIHJBF2wh2AEgc0EXbCHZASByQRZsIdoBIHNBFmwh2wEgckEVbCHcASBzQRVsIWYgckEUbCFoIHNBFGwhaiByQRNsIW4gc0ETbCF9IHJBEmwhhQEgc0ESbCGGASByQRFsIYcBIHNBEWwhiAEgckEEdCGJASBzQQR0IYoBIHJBD2whjAEgc0EPbCGNASByQQ5sIY4BIHNBDmwhjwEgckENbCGRASBzQQ1sIWQgckEMbCGSASBzQQxsIWAgckELbCFxIHNBC2wheyByQQpsIX8gc0EKbCFfIHJBCWwhYiBzQQlsIXQgckEDdCFcIHNBA3QhfiByQQdsIYIBIHNBB2whayByQQZsIW0gc0EGbCFpIHJBBWwhdSBzQQVsIXkgckECdCF6IHNBAnQhgQEgckEDbCF2IHNBA2whYyByQQF0IWwgc0EBdCF4IHKtIRYgc60hESAFpyKQAUFwcSI9IJABQQ9xIqIBIJABQQNxIqMBayKkAWohAQNAQgAhAyAEQhB8IgggHyAIIB9TIk8bIg4gBFUEQANAIANCIHwiBiAZIAYgGVMiZRsiDyAPQiCBIgx9IQkgBCEFA0AgBSAFICN/IhogI359IgIgAiAkfyIgICR+fSElIAMgCVMEQCAQICB+IBIgGn58IQsgFSAgfiAYIBp+fCATICV+fCEHIBcgIH4gGiAbfnwgHCAlfnynIXAgAyECA0AgPigCwAEh9AEggwEoAsABIQAgVSB8KALAASALIAIgEX58p2oibzYCoAcgVSBvIHNqIqUBNgKkByBVIG8geGoipgE2AqgHIFUgYyBvaiKnATYCrAcgVSBvIIEBaiKoATYCsAcgVSBvIHlqIqkBNgK0ByBVIGkgb2oiqgE2ArgHIFUgayBvaiKrATYCvAcgVSBvIH5qIqwBNgLAByBVIAAgByACIBZ+fKdqIgA2AqAGIFUgACByajYCpAYgVSAAIGxqNgKoBiBVIAAgdmo2AqwGIFUgACB6ajYCsAYgVSAAIHVqNgK0BiBVIAAgbWo2ArgGIFUgACCCAWo2ArwGIFUgACBcajYCwAYgVSAAIGJqNgLEBiBVIG8gdGoirQE2AsQHIFUgXyBvaiKuATYCyAcgVSAAIH9qNgLIBiBVIG8ge2oirwE2AswHIFUgACBxajYCzAYgVSBgIG9qIrABNgLQByBVIAAgkgFqNgLQBiBVIGQgb2oisQE2AtQHIFUgACCRAWo2AtQGIFUgbyCPAWoisgE2AtgHIFUgACCOAWo2AtgGIFUgbyCNAWoiswE2AtwHIFUgACCMAWo2AtwGIFUgbyCKAWoitAE2AuAHIFUgACCJAWo2AuAGIFUgbyCIAWoitQE2AuQHIFUgACCHAWo2AuQGIFUgbyCGAWoidzYC6AcgVSAAIIUBajYC6AYgVSBvIH1qImE2AuwHIFUgACBuajYC7AYgVSBqIG9qIlQ2AvAHIFUgACBoajYC8AYgVSBmIG9qIl02AvQHIFUgACDcAWo2AvQGIFUgbyDbAWoiVjYC+AcgVSAAINoBajYC+AYgVSBvINkBaiJeNgL8ByBVIAAg2AFqNgL8BiBVIG8g1wFqIlA2AoAIIFUgACDWAWo2AoAHIFUgbyDVAWoiVzYChAggVSAAINQBajYChAcgVSBvINMBaiJTNgKICCBVIAAg0gFqNgKIByBVIG8g0QFqIlk2AowIIFUgACDQAWo2AowHIFUgbyDPAWoiWDYCkAggVSAAIM4BajYCkAcgVSBvIM0BaiJaNgKUCCBVIAAgzAFqNgKUByBVIG8gywFqIk02ApgIIFUgACDKAWo2ApgHIFUgbyDJAWoiWzYCnAggVSAAIMgBajYCnAdBACEAA0AgVUGgAmoiQiAAQQR0aiBVQaAGaiJAIABBAnRqKAIA/QkCAP0LBAAgQiAAQQFyIj9BBHRqID9BAnQgQGooAgD9CQIA/QsEACAAQQJqIgBBIEcNAAsg9AEgcGohkwEgPUEASgRAILUBQRBqIVIgtAFBEGohTiCzAUEQaiFMILIBQRBqIUkgsQFBEGohUSCwAUEQaiFKIK8BQRBqIUsgrgFBEGohRyCtAUEQaiFGIKwBQRBqIUggqwFBEGohRSCqAUEQaiFBIKkBQRBqIUQgqAFBEGohQyCnAUEQaiFCIKYBQRBqIUAgpQFBEGohPyBvQRBqIQBBACGAASBV/QAEkAYhrAIgVf0ABIAGIa0CIFX9AATwBSGuAiBV/QAE4AUhrwIgVf0ABNAFIbACIFX9AATABSGxAiBV/QAEsAUhsgIgVf0ABKAFIbMCIFX9AASQBSG0AiBV/QAEgAUhtQIgVf0ABPAEIbYCIFX9AATgBCG3AiBV/QAE0AQhuAIgVf0ABMAEIbkCIFX9AASwBCG6AiBV/QAEoAQhuwIgVf0ABJAEIbwCIFX9AASABCG9AiBV/QAE8AMhvgIgVf0ABOADIb8CIFX9AATQAyHAAiBV/QAEwAMhwQIgVf0ABLADIcICIFX9AASgAyHDAiBV/QAEkAMhxAIgVf0ABIADIasCIFX9AATwAiGqAiBV/QAE4AIhqQIgVf0ABNACIaYCIFX9AATAAiGnAiBV/QAEsAIhqAIgVf0ABKACIaUCA0AgkwEggAFBAnQiZ2oiiwEgrAIgWyBnaiKUAf0AAAD95gEgrQIgTSBnaiKVAf0AAAD95gEgrgIgWiBnaiKWAf0AAAD95gEgrwIgWCBnaiKXAf0AAAD95gEgsAIgWSBnaiKYAf0AAAD95gEgsQIgUyBnaiKZAf0AAAD95gEgsgIgVyBnaiKaAf0AAAD95gEgswIgUCBnaiKbAf0AAAD95gEgtAIgXiBnaiKcAf0AAAD95gEgtQIgViBnaiKdAf0AAAD95gEgtgIgXSBnaiKeAf0AAAD95gEgtwIgVCBnaiKfAf0AAAD95gEguAIgYSBnaiKgAf0AAAD95gEguQIgZyB3aiKhAf0AAAD95gEgugIgZyC1AWoitgH9AAAA/eYBILsCIGcgtAFqIrcB/QAAAP3mASC8AiBnILMBaiK4Af0AAAD95gEgvQIgZyCyAWoiuQH9AAAA/eYBIL4CIGcgsQFqIroB/QAAAP3mASC/AiBnILABaiK7Af0AAAD95gEgwAIgZyCvAWoivAH9AAAA/eYBIMECIGcgrgFqIr0B/QAAAP3mASDCAiBnIK0BaiK+Af0AAAD95gEgwwIgZyCsAWoivwH9AAAA/eYBIMQCIGcgqwFqIsAB/QAAAP3mASCrAiBnIKoBaiLBAf0AAAD95gEgqgIgZyCpAWoiwgH9AAAA/eYBIKkCIGcgqAFqIsMB/QAAAP3mASCmAiBnIKcBaiLEAf0AAAD95gEgpwIgZyCmAWoixQH9AAAA/eYBIKgCIGcgpQFqIsYB/QAAAP3mASCLAf0AAAAgpQIgZyBvaiLHAf0AAAD95gH95AH95AH95AH95AH95AH95AH95AH95AH95AH95AH95AH95AH95AH95AH95AH95AH95AH95AH95AH95AH95AH95AH95AH95AH95AH95AH95AH95AH95AH95AH95AH95AH9CwAAIIsBIKwCIJQB/QAAEP3mASCtAiCVAf0AABD95gEgrgIglgH9AAAQ/eYBIK8CIJcB/QAAEP3mASCwAiCYAf0AABD95gEgsQIgmQH9AAAQ/eYBILICIJoB/QAAEP3mASCzAiCbAf0AABD95gEgtAIgnAH9AAAQ/eYBILUCIJ0B/QAAEP3mASC2AiCeAf0AABD95gEgtwIgnwH9AAAQ/eYBILgCIKAB/QAAEP3mASC5AiChAf0AABD95gEgugIgUiBnav0AAAD95gEguwIgTiBnav0AAAD95gEgvAIgTCBnav0AAAD95gEgvQIgSSBnav0AAAD95gEgvgIgUSBnav0AAAD95gEgvwIgSiBnav0AAAD95gEgwAIgSyBnav0AAAD95gEgwQIgRyBnav0AAAD95gEgwgIgRiBnav0AAAD95gEgwwIgSCBnav0AAAD95gEgxAIgRSBnav0AAAD95gEgqwIgQSBnav0AAAD95gEgqgIgRCBnav0AAAD95gEgqQIgQyBnav0AAAD95gEgpgIgQiBnav0AAAD95gEgpwIgQCBnav0AAAD95gEgqAIgPyBnav0AAAD95gEgiwH9AAAQIKUCIAAgZ2r9AAAA/eYB/eQB/eQB/eQB/eQB/eQB/eQB/eQB/eQB/eQB/eQB/eQB/eQB/eQB/eQB/eQB/eQB/eQB/eQB/eQB/eQB/eQB/eQB/eQB/eQB/eQB/eQB/eQB/eQB/eQB/eQB/eQB/eQB/QsAECCLASCsAiCUAf0AACD95gEgrQIglQH9AAAg/eYBIK4CIJYB/QAAIP3mASCvAiCXAf0AACD95gEgsAIgmAH9AAAg/eYBILECIJkB/QAAIP3mASCyAiCaAf0AACD95gEgswIgmwH9AAAg/eYBILQCIJwB/QAAIP3mASC1AiCdAf0AACD95gEgtgIgngH9AAAg/eYBILcCIJ8B/QAAIP3mASC4AiCgAf0AACD95gEguQIgoQH9AAAg/eYBILoCILYB/QAAIP3mASC7AiC3Af0AACD95gEgvAIguAH9AAAg/eYBIL0CILkB/QAAIP3mASC+AiC6Af0AACD95gEgvwIguwH9AAAg/eYBIMACILwB/QAAIP3mASDBAiC9Af0AACD95gEgwgIgvgH9AAAg/eYBIMMCIL8B/QAAIP3mASDEAiDAAf0AACD95gEgqwIgwQH9AAAg/eYBIKoCIMIB/QAAIP3mASCpAiDDAf0AACD95gEgpgIgxAH9AAAg/eYBIKcCIMUB/QAAIP3mASCoAiDGAf0AACD95gEgiwH9AAAgIKUCIMcB/QAAIP3mAf3kAf3kAf3kAf3kAf3kAf3kAf3kAf3kAf3kAf3kAf3kAf3kAf3kAf3kAf3kAf3kAf3kAf3kAf3kAf3kAf3kAf3kAf3kAf3kAf3kAf3kAf3kAf3kAf3kAf3kAf3kAf3kAf0LACAgiwEgrAIglAH9AAAw/eYBIK0CIJUB/QAAMP3mASCuAiCWAf0AADD95gEgrwIglwH9AAAw/eYBILACIJgB/QAAMP3mASCxAiCZAf0AADD95gEgsgIgmgH9AAAw/eYBILMCIJsB/QAAMP3mASC0AiCcAf0AADD95gEgtQIgnQH9AAAw/eYBILYCIJ4B/QAAMP3mASC3AiCfAf0AADD95gEguAIgoAH9AAAw/eYBILkCIKEB/QAAMP3mASC6AiC2Af0AADD95gEguwIgtwH9AAAw/eYBILwCILgB/QAAMP3mASC9AiC5Af0AADD95gEgvgIgugH9AAAw/eYBIL8CILsB/QAAMP3mASDAAiC8Af0AADD95gEgwQIgvQH9AAAw/eYBIMICIL4B/QAAMP3mASDDAiC/Af0AADD95gEgxAIgwAH9AAAw/eYBIKsCIMEB/QAAMP3mASCqAiDCAf0AADD95gEgqQIgwwH9AAAw/eYBIKYCIMQB/QAAMP3mASCnAiDFAf0AADD95gEgqAIgxgH9AAAw/eYBIIsB/QAAMCClAiDHAf0AADD95gH95AH95AH95AH95AH95AH95AH95AH95AH95AH95AH95AH95AH95AH95AH95AH95AH95AH95AH95AH95AH95AH95AH95AH95AH95AH95AH95AH95AH95AH95AH95AH95AH9CwAwIIABQRBqIoABID1IDQALC0EAIVQgPSCQAUgEQANAIFRBAnQiACBVQaAHamooAgAhQiBVQaAGaiAAaigCACoCACGSAiA9IQACQCCiAUEETwRAIJIC/RMhpQJBACEAA0AgkwEgACA9akECdCJAaiI/IEAgQmr9AAIAIKUC/eYBID/9AAIA/eQB/QsCACAAQQRqIgAgpAFHDQALIAEhACCjAUUNAQsDQCCTASAAQQJ0IkBqIj8gQCBCaioCACCSApQgPyoCAJI4AgAgAEEBaiIAIJABRw0ACwsgVEEBaiJUQSBHDQALCyACQiB8IgIgCVMNAAsLIAxCAFUEQCAQICB+IBIgGn58IQsgFSAgfiAYIBp+fCATICV+fCEHIBcgIH4gGiAbfnwgHCAlfnynIUIgCSECA0AgPigCwAEgQmohRCB8KALAASALIAIgEX58p2ohQyCDASgCwAEgByACIBZ+fKdqKgIAIZICID1BAEoEQCCSAv0TIaUCQQAhAANAIEQgAEECdCI/aiJAIKUCID8gQ2oiP/0AAAD95gEgQP0AAAD95AH9CwAAIEAgpQIgP/0AABD95gEgQP0AABD95AH9CwAQIEAgpQIgP/0AACD95gEgQP0AACD95AH9CwAgIEAgpQIgP/0AADD95gEgQP0AADD95AH9CwAwIABBEGoiACA9SA0ACwsCQCA9IJABTg0AID0hACCiAUEETwRAIJIC/RMhpQJBACEAA0AgRCAAID1qQQJ0IkBqIj8gQCBDav0AAgAgpQL95gEgP/0AAgD95AH9CwIAIABBBGoiACCkAUcNAAsgASEAIKMBRQ0BCwNAIEQgAEECdCJAaiI/IEAgQ2oqAgAgkgKUID8qAgCSOAIAIABBAWoiACCQAUcNAAsLIAJCAXwiAiAPUw0ACwsgBUIBfCIFIA5TDQALIAYhAyBlDQALCyAIIQQgTw0ACwwSCyBVQeM/NgKoASBVQZXLADYCpAEgVUHHJjYCoAFBqMICKAIAIgBBpeMAIFVBoAFqEDAMRQsgVUHvPzYCuAEgVUGUywA2ArQBIFVBxyY2ArABQajCAigCACIAQaXjACBVQbABahAwDEQLIFVBiNAANgLIASBVQY/LADYCxAEgVUHHJjYCwAFBqMICKAIAIgBBpeMAIFVBwAFqEDAMQwsgVUHh0AA2AtgBIFVBjMsANgLUASBVQccmNgLQAUGowgIoAgAiAEGl4wAgVUHQAWoQMAxCCyBVQfQ5NgLoASBVQYnLADYC5AEgVUHHJjYC4AFBqMICKAIAIgBBpeMAIFVB4AFqEDAMQQsgVUHHPDYC+AEgVUGIywA2AvQBIFVBxyY2AvABQajCAigCACIAQaXjACBVQfABahAwDEALIFVBgDo2AogCIFVBh8sANgKEAiBVQccmNgKAAkGowgIoAgAiAEGl4wAgVUGAAmoQMAw/CyBVQdM8NgKYAiBVQYbLADYClAIgVUHHJjYCkAJBqMICKAIAIgBBpeMAIFVBkAJqEDAMPgsgVUHjPzYCGCBVQaDMADYCFCBVQccmNgIQQajCAigCACIAQaXjACBVQRBqEDAMPQsgVUHvPzYCKCBVQZ/MADYCJCBVQccmNgIgQajCAigCACIAQaXjACBVQSBqEDAMPAsgVUGI0AA2AjggVUGazAA2AjQgVUHHJjYCMEGowgIoAgAiAEGl4wAgVUEwahAwDDsLIFVB6dMANgJIIFVBl8wANgJEIFVBxyY2AkBBqMICKAIAIgBBpeMAIFVBQGsQMAw6CyBVQfQ5NgJYIFVBlMwANgJUIFVBxyY2AlBBqMICKAIAIgBBpeMAIFVB0ABqEDAMOQsgVUHHPDYCaCBVQZPMADYCZCBVQccmNgJgQajCAigCACIAQaXjACBVQeAAahAwDDgLIFVBgDo2AnggVUGSzAA2AnQgVUHHJjYCcEGowgIoAgAiAEGl4wAgVUHwAGoQMAw3CyBVQdM8NgKIASBVQZHMADYChAEgVUHHJjYCgAFBqMICKAIAIgBBpeMAIFVBgAFqEDAMNgsgAyAYfiAFfiACfqciAEEATA0BCyA+KALAAUEAIABBAnT8CwALIFVBoAhqJAAMAQsgVUH+IDYCCCBVQY3NADYCBCBVQccmNgIAQajCAigCACIAQaXjACBVEDAMMgsMKQsgASgCjAEhSSABKAKQASE/IAEhPiMAQdAAayJMJAACQAJAIEkoAgBFBEACQCBJKAIwQQRHDQAgSSgCNCJHrSIDIEkpAxAiCUIChlINACBJNQI4IgIgAyBJKQMYIgh+Ug0AIEk1AjwgAiBJKQMgIgZ+Ug0AAkAgASgCMCI9IAEoAgBBJGwiAUGYmgFqKAIARw0AID4oAjQiSq0iAiA+KQMQIgUgPa1+IAFBlJoBajQCAH9SDQAgPjUCOCIEIAIgPikDGCIDflINACA+NQI8IAQgPikDICICflINAAJAIAUgCVINACADIAhSDQAgAiAGUg0AIEkpAygiAiA+KQMoUg0AAkAgPykDEEIBUg0AID8pAxhCAVINACA/KQMgQgFSDQAgPykDKEIBUg0AAkAgACgCAA4DBwAHAAsgBiAIfiACfqciPSAAKAIIIgFqQQFrIAFtIgEgACgCBGwiTyABaiIAID0gACA9SBsiSyBPTA0GIAmnIlFBAnQhRiA/KALAASoCACKSAv0TIaUCIFFBcHEiAUEATA0FIAEgUUEPcSJFIFFBA3EiQWsiRGohPSABQQFrIkNBBHZBAWoiAEH+////AXEhQiAAQQFxIUADQCBKIE9sIUggPigCwAEiPyBJKALAASIARwR/ID8gSGogACBHIE9saiBG/AoAACA+KALAAQUgPwsgSGohSEEAIWFBACFpIENBD0cEQANAIEggYUECdCIAaiI/IKUCID/9AAAA/eYB/QsAACA/IKUCID/9AAAQ/eYB/QsAECA/IKUCID/9AAAg/eYB/QsAICA/IKUCID/9AAAw/eYB/QsAMCBIIABBwAByaiIAIKUCIAD9AAAA/eYB/QsAACAAIKUCIAD9AAAQ/eYB/QsAECAAIKUCIAD9AAAg/eYB/QsAICAAIKUCIAD9AAAw/eYB/QsAMCBhQSBqIWEgaUECaiJpIEJHDQALCyBABEAgSCBhQQJ0aiIAIKUCIAD9AAAA/eYB/QsAACAAIKUCIAD9AAAQ/eYB/QsAECAAIKUCIAD9AAAg/eYB/QsAICAAIKUCIAD9AAAw/eYB/QsAMAsCQCABIFFODQBBACFhIAEhACBFQQRPBEADQCBIIAEgYWpBAnRqIgAgpQIgAP0AAgD95gH9CwIAIGFBBGoiYSBERw0ACyA9IQAgQUUNAQsDQCBIIABBAnRqIj8gkgIgPyoCAJQ4AgAgAEEBaiIAIFFHDQALCyBPQQFqIk8gS0cNAAsMBgsgTEHN1wA2AgggTEGczQA2AgQgTEHHJjYCAEGowgIoAgAiYUGl4wAgTBAwDDcLIExB5M4ANgIYIExBm80ANgIUIExBxyY2AhBBqMICKAIAImFBpeMAIExBEGoQMAw2CyBMQZrLADYCKCBMQZrNADYCJCBMQccmNgIgQajCAigCACJhQaXjACBMQSBqEDAMNQsgTEHY2AA2AjggTEGZzQA2AjQgTEHHJjYCMEGowgIoAgAiYUGl4wAgTEEwahAwDDQLIExB/iA2AkggTEHLzQA2AkQgTEHHJjYCQEGowgIoAgAiYUGl4wAgTEFAaxAwDDMLIEkoAsABIQAgPigCwAEhYiABIFFIBEAgUUEPcSE/IAAgYkcEQCABID8gUUEDcSJDayJCaiE9ID9BBEkhQANAIEogT2whPyBJKALAASIAIGJHBEAgPyBiaiAAIEcgT2xqIEb8CgAAID4oAsABIWILID8gYmohREEAIWEgASEAAkAgQEUEQANAIEQgASBhakECdGoiACClAiAA/QACAP3mAf0LAgAgYUEEaiJhIEJHDQALID0hACBDRQ0BCwNAIEQgAEECdGoiPyCSAiA/KgIAlDgCACAAQQFqIgAgUUcNAAsLIE9BAWoiTyBLRw0ACwwCCyABID8gUUEDcSJCayJAaiE9ID9BBEkhPwNAIGIgSiBPbGohQ0EAIWEgASEAAkAgP0UEQANAIEMgASBhakECdGoiACClAiAA/QACAP3mAf0LAgAgYUEEaiJhIEBHDQALID0hACBCRQ0BCwNAIEMgAEECdGoiPiCSAiA+KgIAlDgCACAAQQFqIgAgUUcNAAsLIE9BAWoiTyBLRw0ACwwBCyAAIGJGDQAgT0EBaiH1ASBLIE9rQQFxBEAgPigCwAEiASBJKALAASIARwRAIAEgSiBPbGogACBHIE9saiBG/AoAAAsgT0EBaiFPCyD1ASBLRg0AA0AgPigCwAEiASBJKALAASIARwRAIAEgSiBPbGogACBHIE9saiBG/AoAAAsgPigCwAEiPSBJKALAASIBRwRAID0gT0EBaiIAIEpsaiABIAAgR2xqIEb8CgAACyBPQQJqIk8gS0cNAAsLIExB0ABqJAAMKAsgASgCjAEhQSABKAKQASFEIwBB0ABrIlgkAAJAAkACQAJAAkAgQSgCAEUEQCBBKQMQIgcgASkDEFINASBBKQMYIgwgASkDGFINASBBKQMgIgsgASkDIFINASBBKQMoIgkgASkDKFINASABKAIwIkMgASgCACJCQSRsIj1BmJoBaigCAEcNAiABKAI0IkCtIgggByBDrX4iBSA9QZSaAWooAgAiP6x/Ug0CIAEoAjgiPq0iBiAIIAx+Ug0CIAEoAjwiPa0iBCAGIAt+Ug0CIEEoAjBBBEcNAiBBNQI0IgMgB0IChlINAiBBNQI4IgIgAyAMflINAiBBNQI8IAIgC35SDQIgASgCUCFSIAEoAkwhTiABKAJIIUwgASgCRCFJAkAgASgCVEUEQCAAKAIAIl0NASABKALAASBBKALAASBCQRBrQXFNBH8gQCAMp0EBa2wgQyAHp2xqID4gC6dBAWtsaiA9IAmnQQFrbGoFIAtCAX0gBn4gDEIBfSAIfnwgCUIBfSAEfnwgBSA/rX98pwv8CgAACyAAKAIAIV0LAkACQCBdDgMBAAEACyBJIEQpAxgiB0IBfSICQgAgAiAHWBunbCBSaiBMIEQpAyAiBkIBfSICQgAgAiAGWBunbGogTiBEKQMoIglCAX0iAkIAIAIgCVgbp2xqIEEoAgBBJGxBmJoBaigCACBEKQMQIghCAX0iAkIAIAIgCFgbp2xqIT4gRCgCPCFLIEQoAjghRyBEKAI0IUYgASkDKCEFIAEpAxAhBCABKQMgIQMgASkDGCECIEQoAjAh9gEgACgCCCFAIAAoAgQhAAJ/IAEoAgAiP0EQa0FxTQRAID9BJGxBmJoBaigCACABKAIwIASnQQFrbGogASgCNCACp0EBa2xqIAEoAjggA6dBAWtsaiABKAI8IAWnQQFrbGoMAQsgATUCNCACQgF9fiAEIAE1AjB+ID9BJGxBlJoBajUCAH98IAE1AjggA0IBfX58IAE1AjwgBUIBfX58pwsgPkkNBCD2AUEERw0FIAAgQCAJIAYgB34iBn6nIj1qQQFrIEBtIgBsIj4gACA+aiIAID0gACA9SBsiAE4NACAIpyJaQQBMDQAgRCgCwAEhUSBaQQNxIUogWkF8cSE9IFIgASgCwAEiSGohRSAArCEFID6sIQMgWkEQSSFBA0AgUSBLIAMgBn8iAqciPmwiRGogRyADIALEIAZ+fSIEIAd/IgKnIgFsIkNqIEYgBCACIAd+faciAGwiQmohTSAAIElsIkAgASBMbCI/IEggPiBObCI+ampqIFJqIVtBACEBQQAhAAJAAkAgQQ0AIEAgRWogPmogP2ogQiBRaiBEaiBDamtBEEkNAANAIFsgAEECdCI+aiA+IE1q/QACAP0LAgAgAEEEaiIAID1HDQALID0iACBaRg0BCyAAQX9zIFpqIfcBIEoEQANAIFsgAEECdCI+aiA+IE1qKgIAOAIAIABBAWohACABQQFqIgEgSkcNAAsLIPcBQQNJDQADQCBbIABBAnQiPmogPiBNaioCADgCACBbID5BBGoiAWogASBNaioCADgCACBbID5BCGoiAWogASBNaioCADgCACBbID5BDGoiAWogASBNaioCADgCACAAQQRqIgAgWkcNAAsLIANCAXwiAyAFUg0ACwsgWEHQAGokAAwFCyBYQf4gNgJIIFhBsc4ANgJEIFhBxyY2AkBBqMICKAIAIgFBpeMAIFhBQGsQMAw2CyBYQeTOADYCOCBYQdfNADYCNCBYQccmNgIwQajCAigCACIBQaXjACBYQTBqEDAMNQsgWEG92AA2AiggWEHYzQA2AiQgWEHHJjYCIEGowgIoAgAiAUGl4wAgWEEgahAwDDQLIFhBsssANgIIIFhBgM4ANgIEIFhBxyY2AgBBqMICKAIAIgFBpeMAIFgQMAwzCyBYQbTQADYCGCBYQYLOADYCFCBYQccmNgIQQajCAigCACIBQaXjACBYQRBqEDAMMgsMJwsgACABKAKMASABEPYCDCYLIAAgASgCjAEgARD2AgwlCyABKAKMASFGIAEoApABIUAjAEEQayJLJAACQAJAAkACQAJAAkAgRigCACI9QQZrQQlJDQAgPQ4EAgEAAAQLAkAgACgCAA4DAwADAAsgQCkDKCBAKQMgIEApAxggQCkDEH5+fqciP0EATA0CID1BJGxBoJoBaigCACE+IEYoAhAhPUEAIQADQCBGKALAASBGKAI0IEAoAsABIABBAnRqKAIAbGogASgCwAEgASgCNCAAbGogPSA+EQUAIABBAWoiACA/Rw0ACwwCCwJAIAAoAgAOAwIAAgALIEApAyggQCkDICBAKQMYIEApAxB+fn6nIkVBAEwNASBGKAIQIgBBAEwNASBAKALAASFBIABBfHEhRCAAQQNxIUggASgCNCFDIEYoAjQhQiABKALAASFAIEYoAsABIT8gAEEESSE+A0AgQCBDIE9saiFHID8gQSBPQQJ0aigCACBCbGohRkEAIQBBACE9ID5FBEADQCBHIABBAnRqIEYgAEEBdGovAQBBAnRB8NQEaioCADgCACBHIABBAXIiAUECdGogRiABQQF0ai8BAEECdEHw1ARqKgIAOAIAIEcgAEECciIBQQJ0aiBGIAFBAXRqLwEAQQJ0QfDUBGoqAgA4AgAgRyAAQQNyIgFBAnRqIEYgAUEBdGovAQBBAnRB8NQEaioCADgCACAAQQRqIQAgPUEEaiI9IERHDQALC0EAIT0gSARAA0AgRyAAQQJ0aiBGIABBAXRqLwEAQQJ0QfDUBGoqAgA4AgAgAEEBaiEAID1BAWoiPSBIRw0ACwsgT0EBaiJPIEVHDQALDAELAkAgACgCAA4DAQABAAsgQCkDKCBAKQMgIEApAxggQCkDEH5+fqciSEEATA0AIEYoAhAiR0EATA0AIEYoAjQhRSABKAI0IUEgRigCwAEhRCABKALAASFDIEAoAsABIUIgR0EDcSFGIEdBfHEhASBHQQhJIUADQCBDIEEgYWxqIVEgRCBCIGFBAnRqKAIAIEVsaiFKQQAhAAJAAkAgQA0AIFEgSmtBEEkNAANAIFEgAEECdCI9aiA9IEpq/QACAP0LAgAgAEEEaiIAIAFHDQALIAEiACBHRg0BCyAAQX9zIEdqIfgBQQAhPSBGBEADQCBRIABBAnQiPmogPiBKaioCADgCACAAQQFqIQAgPUEBaiI9IEZHDQALCyD4AUEDSQ0AA0AgUSAAQQJ0Ij5qID4gSmoqAgA4AgAgUSA+QQRqIj1qID0gSmoqAgA4AgAgUSA+QQhqIj1qID0gSmoqAgA4AgAgUSA+QQxqIj1qID0gSmoqAgA4AgAgAEEEaiIAIEdHDQALCyBhQQFqImEgSEcNAAsLIEtBEGokAAwBCyBLQf4gNgIIIEtB5s8ANgIEIEtBxyY2AgBBqMICKAIAIgBBpeMAIEsQMAwtCwwkCyABKAKMASFHIAEoApABIUEjAEGQAWsiTCQAAkACQAJAAkACQAJAAkACQAJAAkACQAJAIEcoAgAOAgEABAsgACgCBA0EIAEoAjAiRCABKAIAIkNBJGwiPUGYmgFqKAIARw0FIAEoAjQiQq0iCSABKQMQIgQgRK1+IgMgPUGUmgFqKAIAIkCsf1INBSABKAI4Ij+tIgggASkDGCIGIAl+Ug0FIAEoAjwiPq0iAiABKQMgIgUgCH5SDQUCQCAAKAIAIj0EfyA9BSABKALAAUEAAn8gQ0EQa0FxTQRAIAanQQFrIEJsIEQgBKdsaiAFp0EBayA/bGogASgCKEEBayA+bGoMAQsgBUIBfSAIfiAGQgF9IAl+fCADIECtf3wgASkDKEIBfSACfnynC/wLACAAKAIACw4DAgACAAsgASkDECBHKQMQIgLEUg0GIEcoAjBBAkYEQCBBKQMoIEEpAyAgQSkDGCBBKQMQfn5+pyJIQQBMDQIgAqciS0EATA0CIEEoAsABIUUgS0F+cSFBIEtBAXEhRCBHKAI0IUMgASgCNCFCIAEoAsABIUAgRygCwAEhP0EAIQEDQCA/IAEgQ2xqIUcgQCBFIAFBAnRqKAIAIEJsaiFGQQAhAEEAIV0gS0EBRwRAA0AgRiAAQQJ0aiI9IEcgAEEBdGovAQBBAnRB8NQEaioCACA9KgIAkjgCACBGIABBAXIiPkECdGoiPSBHID5BAXRqLwEAQQJ0QfDUBGoqAgAgPSoCAJI4AgAgAEECaiEAIF1BAmoiXSBBRw0ACwsgRARAIEYgAEECdGoiPSBHIABBAXRqLwEAQQJ0QfDUBGoqAgAgPSoCAJI4AgALIAFBAWoiASBIRw0ACwwCCyBMQffQADYCGCBMQZXQADYCFCBMQccmNgIQQajCAigCACIBQaXjACBMQRBqEDAMOAsgACgCBA0GIAEoAjAiRCABKAIAIkNBJGwiPUGYmgFqKAIARw0HIAEoAjQiQq0iCSABKQMQIgQgRK1+IgMgPUGUmgFqKAIAIkCsf1INByABKAI4Ij+tIgggASkDGCIGIAl+Ug0HIAEoAjwiPq0iAiABKQMgIgUgCH5SDQcCQCAAKAIAIj0EfyA9BSABKALAAUEAAn8gQ0EQa0FxTQRAIAanQQFrIEJsIEQgBKdsaiAFp0EBayA/bGogASgCKEEBayA+bGoMAQsgBUIBfSAIfiAGQgF9IAl+fCADIECtf3wgASkDKEIBfSACfnynC/wLACAAKAIACw4DAQABAAsgASkDECBHKQMQIgLEUg0IIEcoAjBBBEcNASBBKQMoIEEpAyAgQSkDGCBBKQMQfn5+pyJGQQBMDQAgAqciSUEATA0AIEcoAjQhSCBHKALAASFLIAEoAjQhRSBBKALAASFBIElBA3EhRyBJQXxxIT0gASgCwAEiRCBJQQJ0IkNqIUIgSUEISSFAA0AgSyBIIGFsIj5qIVEgRCBBIGFBAnRqKAIAIEVsIgFqIUpBACEAAkACQCBADQAgUSABIEJqSSBLID4gQ2pqIEpLcQ0AA0AgSiAAQQJ0Ij5qIgEgAf0AAgAgPiBRav0AAgD95AH9CwIAIABBBGoiACA9Rw0ACyA9IgAgSUYNAQsgAEF/cyBJaiH5AUEAIV0gRwRAA0AgSiAAQQJ0Ij5qIgEgASoCACA+IFFqKgIAkjgCACAAQQFqIQAgXUEBaiJdIEdHDQALCyD5AUEDSQ0AA0AgSiAAQQJ0Ij9qIgEgASoCACA/IFFqKgIAkjgCACBKID9BBGoiPmoiASABKgIAID4gUWoqAgCSOAIAIEogP0EIaiI+aiIBIAEqAgAgPiBRaioCAJI4AgAgSiA/QQxqIj5qIgEgASoCACA+IFFqKgIAkjgCACAAQQRqIgAgSUcNAAsLIGFBAWoiYSBGRw0ACwsgTEGQAWokAAwICyBMQanPADYCWCBMQbfQADYCVCBMQccmNgJQQajCAigCACIBQaXjACBMQdAAahAwDDULIExB/iA2AgggTEHT0AA2AgQgTEHHJjYCAEGowgIoAgAiAUGl4wAgTBAwDDQLIExBo8AANgJIIExBhNAANgJEIExBxyY2AkBBqMICKAIAIgFBpeMAIExBQGsQMAwzCyBMQZrLADYCOCBMQYXQADYCNCBMQccmNgIwQajCAigCACIBQaXjACBMQTBqEDAMMgsgTEGZJjYCKCBMQZTQADYCJCBMQccmNgIgQajCAigCACIBQaXjACBMQSBqEDAMMQsgTEGjwAA2AogBIExBptAANgKEASBMQccmNgKAAUGowgIoAgAiAUGl4wAgTEGAAWoQMAwwCyBMQZrLADYCeCBMQafQADYCdCBMQccmNgJwQajCAigCACIBQaXjACBMQfAAahAwDC8LIExBmSY2AmggTEG20AA2AmQgTEHHJjYCYEGowgIoAgAiAUGl4wAgTEHgAGoQMAwuCwwjCyABKAKMASE9IwBBkAFrIlIkAAJAAkACQAJAAkACQAJAAkACQCA9KAIARQRAIAAoAgQNAQJAAkAgACgCAA4DAQABAAsgPSkDECIEIAEpAxBSDQMgBCABKQMYUg0EID0pAxhCAVINBSA9KQMgIgkgASkDIFINBiA9KQMoIgggASkDKFINByA9KAIwQQRHDQggASgCMEEERw0JIAhCAFcNACAEQgBXDQAgCUIAVw0AIAEoAjwhSiABKAI4IU4gPSgCPCFLID0oAjghTCA9KALAASFHIAEoAsABIUkgBEIBVgRAIAEoAjQiQUEEaiFEIASnQQJ0QQRrIUYDQCBHIEsgA6ciAGxqIUMgSSAAIEpsIkhqIUIgSEEEaiFAQgAhCgNAIEIgTiAKpyIAbCIBaiI/IEMgACBMbGoiPioCADgCACBJIAEgQGoiPWpBACBG/AsAIAEgSGohAUIBIQIDQCBJIAEgQSACpyJFbCIAampBACBFQQJ0IlH8CwAgACA/aiBRaiA+IFFqKgIAOAIAIAJCAXwiAiAEUwRAIEkgRCBFbCA9ampBACBGIFFr/AsACyACIARSDQALIApCAXwiCiAJUg0ACyADQgF8IgMgCFINAAsMAQsgCUJ8gyEFIAlCA4MhBgNAIEcgSyADpyIAbGohPiBJIAAgSmxqIT1CACECQgAhBCAJQgRaBEADQCA9IE4gAqciAWxqID4gASBMbGoqAgA4AgAgPSBOIAFBAXIiAGxqID4gACBMbGoqAgA4AgAgPSBOIAFBAnIiAGxqID4gACBMbGoqAgA4AgAgPSBOIAFBA3IiAGxqID4gACBMbGoqAgA4AgAgAkIEfCECIARCBHwiBCAFUg0ACwtCACEEIAZCAFIEQANAID0gTiACpyIAbGogPiAAIExsaioCADgCACACQgF8IQIgBEIBfCIEIAZSDQALCyADQgF8IgMgCFINAAsLIFJBkAFqJAAMCQsgUkH+IDYCiAEgUkGf0QA2AoQBIFJBxyY2AoABQajCAigCACIAQaXjACBSQYABahAwDDMLIFJBo8AANgJ4IFJB8NAANgJ0IFJBxyY2AnBBqMICKAIAIgBBpeMAIFJB8ABqEDAMMgsgUkGuPzYCaCBSQfrQADYCZCBSQccmNgJgQajCAigCACIAQaXjACBSQeAAahAwDDELIFJBmD02AlggUkH70AA2AlQgUkHHJjYCUEGowgIoAgAiAEGl4wAgUkHQAGoQMAwwCyBSQfE+NgJIIFJB/NAANgJEIFJBxyY2AkBBqMICKAIAIgBBpeMAIFJBQGsQMAwvCyBSQeY6NgI4IFJB/dAANgI0IFJBxyY2AjBBqMICKAIAIgBBpeMAIFJBMGoQMAwuCyBSQdE5NgIoIFJB/tAANgIkIFJBxyY2AiBBqMICKAIAIgBBpeMAIFJBIGoQMAwtCyBSQeHQADYCGCBSQYDRADYCFCBSQccmNgIQQajCAigCACIAQaXjACBSQRBqEDAMLAsgUkGI0AA2AgggUkGB0QA2AgQgUkHHJjYCAEGowgIoAgAiAEGl4wAgUhAwDCsLDCILIAEoAowBIT4jAEEQayI9JAACQCA+KAIARQRAIAAgPiABQwAAgP8Q6wQgPUEQaiQADAELID1B/iA2AgggPUHj0QA2AgQMKQsMIQsgASgCjAEhPiMAQRBrIj0kAAJAID4oAgBFBEAgACA+IAFDAAAAABDrBCA9QRBqJAAMAQsgPUH+IDYCCCA9QfPRADYCBAwoCwwgCyABKAKMASFOIAEhPSMAQUBqIlIkAAJAIE4oAgBFBEACQCBOKAIwQQRHDQAgTjUCNCIDIE4pAxAiCUIChlINACBONQI4IgIgAyBOKQMYIgh+Ug0AIE41AjwgAiBOKQMgIgZ+Ug0AAkAgASgCMCI+IAEoAgBBJGwiAUGYmgFqKAIARw0AID01AjQiAiA9KQMQIgUgPq1+IAFBlJoBajQCAH9SDQAgPTUCOCIEIAIgPSkDGCIDflINACA9NQI8IAQgPSkDICICflINAAJAIAUgCVINACADIAhSDQAgAiAGUg0AIE4pAygiAiA9KQMoUg0AAkACQCAAKAIADgMBAAEACyAGIAh+IAJ+pyI+IAAoAggiAWpBAWsgAW0iASAAKAIEbCJiIAEgYmoiACA+IAAgPkgbIktODQAgCaciTEFwcSI+IExBD3EiRyBMQQNxIkprIkZqIQEgTEF8cSFIID5BAWsiRUEEdkEBaiIAQf7///8BcSFBIABBAXEhRANAID0oAsABID0oAjQgYmxqIUkCQCBMQQBMBEBEAAAAAAAAAAAhxQIMAQsgTigCwAEgTigCNCBibGohUUMAAID/IZICQQAhV0EAIQBBACGAASBMQQRPBEADQCCSAiBRIABBAnQiP2oqAgAikwIgkgIgkwJeGyKTAiBRID9BBHJqKgIAIpICIJICIJMCXRsikwIgUSA/QQhyaioCACKSAiCSAiCTAl0bIpMCIFEgP0EMcmoqAgAikgIgkgIgkwJdGyGSAiAAQQRqIQAggAFBBGoigAEgSEcNAAsLIEoEQANAIJICIFEgAEECdGoqAgAikwIgkgIgkwJeGyGSAiAAQQFqIQAgV0EBaiJXIEpHDQALC0QAAAAAAAAAACHFAkEAIQADQEMAAAAAIZQCIFEgAEECdCJDaioCACKTAkMAAID/XARAIMUCQYD8ASCTAiCSApMikwKLQwAAgHeUQwAAgAiUQYCAgIgHIJMCvCJCQQF0IkBBgICAeHEiPyA/QYCAgIgHTRtBAXZBgICAPGq+krwiP0ENdkGA+AFxID9B/x9xaiBAQYCAgHhLGyBCQRB2QYCAAnFyQQF0QfDULGovAQBBAnRB8NQEaioCACKUArugIcUCCyBDIElqIJQCOAIAIABBAWoiACBMRw0ACwtEAAAAAAAA8D8gxQKjtiGSAgJAID5BAEwNACCSAv0TIaUCQQAhAEEAIWggRUEPRwRAA0AgSSAAQQJ0Ij9qIkAgpQIgQP0AAAD95gH9CwAAIEAgpQIgQP0AABD95gH9CwAQIEAgpQIgQP0AACD95gH9CwAgIEAgpQIgQP0AADD95gH9CwAwIEkgP0HAAHJqIj8gpQIgP/0AAAD95gH9CwAAID8gpQIgP/0AABD95gH9CwAQID8gpQIgP/0AACD95gH9CwAgID8gpQIgP/0AADD95gH9CwAwIABBIGohACBoQQJqImggQUcNAAsLIERFDQAgSSAAQQJ0aiIAIKUCIAD9AAAA/eYB/QsAACAAIKUCIAD9AAAQ/eYB/QsAECAAIKUCIAD9AAAg/eYB/QsAICAAIKUCIAD9AAAw/eYB/QsAMAsCQCA+IExODQAgPiEAIEdBBE8EQCCSAv0TIaUCQQAhAANAIEkgACA+akECdGoiPyA//QACACClAv3mAf0LAgAgAEEEaiIAIEZHDQALIAEhACBKRQ0BCwNAIEkgAEECdGoiPyA/KgIAIJIClDgCACAAQQFqIgAgTEcNAAsLIGJBAWoiYiBLRw0ACwsgUkFAayQADAQLIFJB5M4ANgIIIFJBgNIANgIEIFJBxyY2AgBBqMICKAIAIgBBpeMAIFIQMAwrCyBSQZrLADYCGCBSQf/RADYCFCBSQccmNgIQQajCAigCACIAQaXjACBSQRBqEDAMKgsgUkHY2AA2AiggUkH+0QA2AiQgUkHHJjYCIEGowgIoAgAiAEGl4wAgUkEgahAwDCkLIFJB/iA2AjggUkHM0gA2AjQgUkHHJjYCMEGowgIoAgAiAEGl4wAgUkEwahAwDCgLDB8LIAEoAowBIUIgASgCkAEhQCMAQeAAayJQJAACQAJAAkACQAJAAkAgQigCAEUEQCBCKAIwQQRHDQEgQigCNCJNrSIDIEIpAxAiDEIChlINASBCNQI4IgIgAyBCKQMYIgt+Ug0BIEI1AjwgAiBCKQMgIgd+Ug0BIEAoAjAiPiBAKAIAQSRsIj1BmJoBaigCAEcNAiBAKAI0IlutIgMgQCkDECIJID6tfiA9QZSaAWo0AgB/Ug0CIEA1AjgiAiBAKQMYIgggA35SDQIgQDUCPCACIEApAyAiBn5SDQIgASgCMCI+IAEoAgBBJGwiPUGYmgFqKAIARw0DIAEoAjQiUq0iAiABKQMQIgUgPq1+ID1BlJoBajQCAH9SDQMgATUCOCIEIAIgASkDGCIDflINAyABNQI8IAQgASkDICICflINAyAFIAxSDQQgAyALUg0EIAIgB1INBCBCKQMoIgIgASkDKFINBCAJIAxSDQUgCCALUg0FIAYgB1INBSBAKQMoIAJSDQUCQAJAIAAoAgAOAwEAAQALIAcgC34gAn6nIj4gACgCCCI9akEBayA9bSI/IAAoAgQiPWwiYiA/IGJqIgAgPiAAID5IGyJKTg0AID0gW2wgP2wiSyAMpyJXQQJ0IgBqIUcgPSBSbCA/bCJRIABqIUYgV0EDcSFaIFdBfHEhACBCKALAASJIID0gTWwgP2xqIUUgUSABKALAASJOaiFBIEAoAsABIUwgV0FwcSI+QQBMIUQgPkF/cyBXakEDSSFDA0AgTCBbIGJsaiFZIEggTSBibGohWP0MAAAAAAAAAAAAAAAAAAAAACKmAiGnAv0MAAAAAAAAAAAAAAAAAAAAACGpAv0MAAAAAAAAAAAAAAAAAAAAACGlAkEAIT0gREUEQANAIKYCIFkgPUECdCIBaiI//QAAMCABIFhqIgH9AAAw/eYB/eQBIaYCIKcCID/9AAAgIAH9AAAg/eYB/eQBIacCIKkCID/9AAAQIAH9AAAQ/eYB/eQBIakCIKUCID/9AAAAIAH9AAAA/eYB/eQBIaUCID1BEGoiPSA+SA0ACyClAiCnAv3kASCpAiCmAv3kAf3kASGmAgsgpgL9HwMgpgL9HwIgpgL9HwAgpgL9HwGSkpIhkgICQCA+IFdODQBBACE9ID4hASBaBEADQCBZIAFBAnQiP2oqAgAgPyBYaioCAJQgkgKSIZICIAFBAWohASA9QQFqIj0gWkcNAAsLIEMNAANAIFkgAUECdCI/QQxqIj1qKgIAID0gWGoqAgCUIFkgP0EIaiI9aioCACA9IFhqKgIAlCBZID9BBGoiPWoqAgAgPSBYaioCAJQgPyBZaioCACA/IFhqKgIAlCCSApKSkpIhkgIgAUEEaiIBIFdHDQALCwJAIFdBAEwNACBSIGhsIUkgTiBSIGJsaiFTQQAhAUEAIT0CQAJAIFdBBEkiQg0AIEEgSWogRSBNIGhsamtBEEkNAANAIFMgPUECdCI/aiA/IFhq/QACAP0LAgAgPUEEaiI9IABHDQALIFcgACI9Rg0BCyA9QX9zIFdqIfoBIFoEQANAIFMgPUECdCI/aiA/IFhqKgIAOAIAID1BAWohPSABQQFqIgEgWkcNAAsLIPoBQQNJDQADQCBTID1BAnQiP2ogPyBYaioCADgCACBTID9BBGoiAWogASBYaioCADgCACBTID9BCGoiAWogASBYaioCADgCACBTID9BDGoiAWogASBYaioCADgCACA9QQRqIj0gV0cNAAsLQQAhAQJAIEJFBEAgkgL9EyGlAgNAIFMgAUECdGoiPSA9/QACACClAv3lAf0LAgAgAUEEaiIBIABHDQALIFcgACIBRg0BCwNAIFMgAUECdGoiPSA9KgIAIJICkzgCACABQQFqIgEgV0cNAAsLQQAhPUEAIQECQCBCDQAgTiBJIFFqaiBMIEcgWyBobCI/ampJIEwgPyBLamogTiBGIElqaklxDQADQCBTIAFBAnQiQGoiPyA//QACACBAIFlq/QACAP3mAf0LAgAgAUEEaiIBIABHDQALIFcgACIBRg0BCyABQX9zIFdqIfsBIFoEQANAIFMgAUECdCJAaiI/ID8qAgAgQCBZaioCAJQ4AgAgAUEBaiEBID1BAWoiPSBaRw0ACwsg+wFBA0kNAANAIFMgAUECdCJAaiI9ID0qAgAgQCBZaioCAJQ4AgAgUyBAQQRqIj9qIj0gPSoCACA/IFlqKgIAlDgCACBTIEBBCGoiP2oiPSA9KgIAID8gWWoqAgCUOAIAIFMgQEEMaiI/aiI9ID0qAgAgPyBZaioCAJQ4AgAgAUEEaiIBIFdHDQALCyBoQQFqIWggYkEBaiJiIEpHDQALCyBQQeAAaiQADAYLIFBB/iA2AlggUEGs0wA2AlQgUEHHJjYCUEGowgIoAgAiPUGl4wAgUEHQAGoQMAwvCyBQQdjYADYCSCBQQdjSADYCRCBQQccmNgJAQajCAigCACI9QaXjACBQQUBrEDAMLgsgUEG01wA2AjggUEHZ0gA2AjQgUEHHJjYCMEGowgIoAgAiPUGl4wAgUEEwahAwDC0LIFBBmssANgIoIFBB2tIANgIkIFBBxyY2AiBBqMICKAIAIj1BpeMAIFBBIGoQMAwsCyBQQeTOADYCGCBQQdvSADYCFCBQQccmNgIQQajCAigCACI9QaXjACBQQRBqEDAMKwsgUEHEzQA2AgggUEHc0gA2AgQgUEHHJjYCAEGowgIoAgAiPUGl4wAgUBAwDCoLDB4LIAEoAowBIV4gASgCkAEhQyMAQfAAayJWJAACQAJAAkACQAJAIF4oAgAOAgIAAQsCQCAAKAIADgMEAAQACyABKAIwQQJGBEAgASkDECIMIAEoAkgiUKwiCVkEQCBQQQFxRQRAIAEoAjwhVyABKAI4IVMgASgCNCFZIF4oAjwhWCBeKAI4IVogXigCNCFNIAEqAmwhlgIgASoCZCGTAiABKgJgIZ0CIAEqAlwhoAIgASoCWCGVAiABKAJQIT4gASgCTCFAIF4oAjAhWyAAKAIEIT0gASkDKCILIAEpAyAiByABKQMYIg5+fqciPyAAKAIIIgBqQQFrIABtIQAgASgCVLIilAIgASoCaCKSAiCSApJD2w9JQJSVEFchlwIglQIQVyGYAiBDKALAASFSIJUCQwAAAMAgULIimQKVEIsBIaECIAtCAFcNBiCUAiCWAiCWApJD2w9JQJSVEFchkgIgUEECbSFOQwAAgD8goAKVEFchlgIgB0IAVw0GIA5CAFcNBiAAID1sIkwgAGoiACA/IAAgP0gbIUkgQEEEcQRAIAxCBFMNByAMQgR/IQYgPkECa6whCCAOpyFLQQAhACBOQQZsIUoDQCBXIAWnIj1sIUcgPSBYbCFGQgAhAwNAIFIgA6ciPUECdGo0AgAiAiAIIAIgCFMbtCGVAiACIAh9IgJCACACQgBVG7QhkwIgACBLaiFIID0gU2whRSA9IFpsIUFCACEEAn8DQCAAQQFqIT0gACBMTgRAID0gACBJTg0CGiABKALAASBHaiBFaiBZIASnIgBsaiFEIF4oAsABIEZqIEFqIAAgTWxqIUNCACECIJUCIZQCIJMCIZICA0AgQyBbIAKnIgBsaiI+IE5BAXQiQmovAQBBAnRB8NQEaioCACGcAiCUAhBqIZoCID4vAQBBAnRB8NQEaioCACGYAiCUAhBcIZcCID4gUEEBdCJAai8BAEECdEHw1ARqKgIAIZsCID4gSmovAQBBAnRB8NQEaioCACGZAiBEIABBAXRqIlFBgPwBIJgCIJcClCCaAiCcApSTIpYCi0MAAIB3lEMAAIAIlEGAgICIByCWArwiP0EBdCI+QYCAgHhxIgAgAEGAgICIB00bQQF2QYCAgDxqvpK8IgBBDXZBgPgBcSAAQf8fcWogPkGAgIB4SxsgP0EQdkGAgAJxcjsBACBCIFFqQYD8ASCYAiCaApQglwIgnAKUkiKWAotDAACAd5RDAACACJRBgICAiAcglgK8Ij9BAXQiPkGAgIB4cSIAIABBgICAiAdNG0EBdkGAgIA8ar6SvCIAQQ12QYD4AXEgAEH/H3FqID5BgICAeEsbID9BEHZBgIACcXI7AQAgkgIQaiGYAiBAIFFqQYD8ASCbAiCSAhBcIpcClCCYAiCZApSTIpYCi0MAAIB3lEMAAIAIlEGAgICIByCWArwiP0EBdCI+QYCAgHhxIgAgAEGAgICIB00bQQF2QYCAgDxqvpK8IgBBDXZBgPgBcSAAQf8fcWogPkGAgIB4SxsgP0EQdkGAgAJxcjsBACBKIFFqQYD8ASCbAiCYApQglwIgmQKUkiKWAotDAACAd5RDAACACJRBgICAiAcglgK8Ij9BAXQiPkGAgIB4cSIAIABBgICAiAdNG0EBdkGAgIA8ar6SvCIAQQ12QYD4AXEgAEH/H3FqID5BgICAeEsbID9BEHZBgIACcXI7AQAgoQIgkgKUIZICIKECIJQClCGUAiACQgF8IgIgBlINAAsLID0hACAEQgF8IgQgDlINAAsgSAshACADQgF8IgMgB1INAAsgBUIBfCIFIAtSDQALDAcLQ28SgzogUEEBa7IilQIgkgIgmQKUIJgCIJgCkiKUApWNIpICIJICIJUCXhtDAAAAACCXAiCZApQglAKVjiKSAiCSAkMAAAAAXRsingKTIpICIJICQ28SgzpdGyGfAiCTAiCWAkPNzMw9lEMAAIA/kpQhnAIgQEECcQ0FIAxCAFcNBiAOpyFHQQAhAANAIFcgA6ciPWwhRiA9IFhsIUhCACEEA0AgACBHaiFFIFMgBKciPWwhQSA9IFpsIUQgUiA9QQJ0aigCALIhlQJCACEFAn8DQCAAQQFqIT0gACBMTgRAID0gACBJTg0CGiABKALAASBGaiBBaiBZIAWnIgBsaiFDIF4oAsABIEhqIERqIAAgTWxqIUJCACECIJUCIZICA0AgoAIgkgKUIZQCIAKnIT4gnQJDAAAAAFsEfSCTAgUglAJDAACAPyCdAkMAAAAAQwAAgD9DAAAAACA+QQF1siCeApMgnwKVIpQCIJQCQwAAAABdGyKUApMglAJDAACAP14blCKUApOUIJICIJQClJIhlAIgnAILIZYCIJQCEFwhmQIgQiA+IFtsaiIALwECQQJ0QfDUBGoqAgAhmwIglAIQaiGUAiBDID5BAXRqIkBBgPwBIAAvAQBBAnRB8NQEaioCACKYAiCUAiCWApQilwKUIJsCIJkCIJYClCKWApSSIpQCi0MAAIB3lEMAAIAIlEGAgICIByCUArwiP0EBdCI+QYCAgHhxIgAgAEGAgICIB00bQQF2QYCAgDxqvpK8IgBBDXZBgPgBcSAAQf8fcWogPkGAgIB4SxsgP0EQdkGAgAJxcjsBAiBAQYD8ASCYAiCWApQglwIgmwKUkyKUAotDAACAd5RDAACACJRBgICAiAcglAK8Ij9BAXQiPkGAgIB4cSIAIABBgICAiAdNG0EBdkGAgIA8ar6SvCIAQQ12QYD4AXEgAEH/H3FqID5BgICAeEsbID9BEHZBgIACcXI7AQAgoQIgkgKUIZICIAJCAnwiAiAMUw0ACwsgPSEAIAVCAXwiBSAOUg0ACyBFCyEAIARCAXwiBCAHUg0ACyADQgF8IgMgC1INAAsMBgsgVkGvwQA2AiggVkGB1wA2AiQgVkHHJjYCIEGowgIoAgAiAEGl4wAgVkEgahAwDCsLIFZBuj82AhggVkGA1wA2AhQgVkHHJjYCEEGowgIoAgAiAEGl4wAgVkEQahAwDCoLIFZB7tEANgI4IFZB+dYANgI0IFZBxyY2AjBBqMICKAIAIgBBpeMAIFZBMGoQMAwpCyBWQf4gNgIIIFZB/tcANgIEIFZBxyY2AgBBqMICKAIAIgBBpeMAIFYQMAwoCwJAIAAoAgAOAwIAAgALAkACQCBeKAIwQQRGBEAgASkDECIMIAEoAkgiU6wiC1kEQCBTQQFxRQRAIAEoAjwhWiABKAI4IU0gASgCNCFbIF4oAjwhUiBeKAI4IU4gXigCNCFMIAEtAHQhPyABKgJwIZ4CIAEqAmwhlQIgASoCZCGWAiABKgJgIZ0CIAEqAlwhogIgASoCWCGUAiABKAJQIT4gASgCTCFCIAEoAjAhWSAAKAIEIT0gASkDKCIHIAEpAyAiCSABKQMYIg5+fqciQCAAKAIIIgBqQQFrIABtIQAgASgCVLIikwIgASoCaCKSAiCSApJD2w9JQJSVEFchlwIglAIQVyGYAiBDKALAASFJIJQCQwAAAMAgU7IimQKVEIsBIaMCIAdCAFcNBiCTAiCVAiCVApJD2w9JQJSVEFchkgIgDEIEfyEGIFNBAm0hWEMAAIA/IKIClRBXIZUCIAlCAFcNBiAOQgBXDQYgACA9bCJRIABqIgAgQCAAIEBIGyFKIEJBBHENA0NvEoM6IFNBAWuyIpQCIJICIJkClCCYAiCYApIikwKVjSKSAiCSAiCUAl4bQwAAAAAglwIgmQKUIJMClY4ikgIgkgJDAAAAAF0bIp8CkyKSAiCSAkNvEoM6XRshnAIglgIglQJDzczMPZRDAACAP5KUIaACIEJBAnFFDQQgU0EATA0GQwAAgL8gmQKVIZsCIA6nIUVBACEAA0AgWiAEpyI9bCFBID0gUmwhREIAIQUDQCAAIEVqIT0gTSAFpyI+bCFDID4gTmwhQiCiAiBJID5BAnRqKAIAspQhkwJCACEKAkADQCAAIj5BAWohAAJAID4gUUgNACA+IEpODQIgDCALfyIIQgBXDQAgASgCwAEgQWogQ2ogWyAKpyI+bGohRiBeKALAASBEaiBCaiA+IExsaiFIQgAhAyCTAiKSAiGUAiCdAkMAAAAAWwRAA0AgAyALfiEGQgAhAgNAIKICIJIClCKZAhBcIZQCIEYgWSACQgGIIAZ8pyI+bGoiQCBIID5BAnRqIj8qAgAimAIglgIglAKUIpcClCA/IFhBAnQiPmoqAgAilQIglgIgmQIQapQilAKUkzgCACA+IEBqIJgCIJQClCCXAiCVApSSOAIAIKMCIJIClCGSAiACQgJ8IgIgC1MNAAsgCCADQgF8IgNSDQAMAgsACwNAIAMgC34hBiADtIwhmQJCACECA0AgogIglAKUQwAAgD8gnQJDAAAAAEMAAIA/QwAAAAACfiCbAiACtJQgmQKSIpICi0MAAABfXQRAIJICrgwBC0KAgICAgICAgIB/C6dBAm2yIJ8CkyCcApUikgIgkgJDAAAAAF0bIpICkyCSAkMAAIA/XhuUIpICk5QglAIgkgKUkiKSAhBqIZgCIEggAkIBiCAGfKciPkECdGoiQCBYQQJ0Ij9qKgIAIZoCIJICEFwhkgIgRiA+IFlsaiI+IEAqAgAilwIgoAIgkgKUIpUClCCaAiCgAiCYApQikgKUkzgCACA+ID9qIJcCIJIClCCaAiCVApSSOAIAIKMCIJQClCGUAiACQgJ8IgIgC1MNAAsgA0IBfCIDIAhSDQALCyAKQgF8IgogDlINAAsgPSEACyAFQgF8IgUgCVINAAsgBEIBfCIEIAdSDQALDAYLIFZBr8EANgJYIFZB7NUANgJUIFZBxyY2AlBBqMICKAIAIgBBpeMAIFZB0ABqEDAMKwsgVkG6PzYCSCBWQevVADYCRCBWQccmNgJAQajCAigCACIAQaXjACBWQUBrEDAMKgsgVkHh0AA2AmggVkHk1QA2AmQgVkHHJjYCYEGowgIoAgAiAEGl4wAgVkHgAGoQMAwpCyAMQgRTDQIgPkECa6whCCAOpyFGQQAhACBYQQxsIUcDQCBaIAWnIj1sIUggPSBSbCFFQgAhAwNAIEkgA6ciPUECdGo0AgAiAiAIIAIgCFMbtCGVAkIAIQQgAiAIfSICQgAgAkIAVRu0IZMCIAAgRmohQSA9IE1sIUQgPSBObCFDAn8DQCAAQQFqIT0gACBRTgRAID0gACBKTg0CGiABKALAASBIaiBEaiBbIASnIgBsaiFCIF4oAsABIEVqIENqIAAgTGxqIUBCACECIJUCIZQCIJMCIZICA0AgQCACpyI/QQJ0aiJLIFNBAnQiPmoqAgAhmgIgRyBLaioCACGbAiBLIFhBAnQiAGoqAgAhmQIglAIQaiGYAiBCID8gWWxqIj8gSyoCACKXAiCUAhBcIpYClCCYAiCZApSTOAIAIAAgP2oglwIgmAKUIJYCIJkClJI4AgAgkgIQaiGXAiA+ID9qIJoCIJICEFwilgKUIJcCIJsClJM4AgAgPyBHaiCaAiCXApQglgIgmwKUkjgCACCjAiCSApQhkgIgowIglAKUIZQCIAJCAXwiAiAGUg0ACwsgPSEAIARCAXwiBCAOUg0ACyBBCyEAIANCAXwiAyAJUg0ACyAFQgF8IgUgB1INAAsMAgsgDEIAVw0BID9BAXEhRiAMtCKSAkMzM7M/lCGZAiAOpyFIQQAhACCSAkPNzMw+lCGYAgNAIFogA6ciPWwhRSA9IFJsIUFCACEEA0AgACBIaiFEIE0gBKciPWwhQyA9IE5sIUIgSSA9QQJ0aigCALIikwIgngKVIZcCQgAhBQJ/A0AgAEEBaiE9IAAgUU4EQCA9IAAgSk4NAhogASgCwAEgRWogQ2ogWyAFpyIAbGohQCBeKALAASBBaiBCaiAAIExsaiE/QgAhAiCTAiGSAgNAIKICIJIClCGUAiCdAkMAAAAAWwR9IJYCBSCUAkMAAIA/IJ0CQwAAAABDAACAP0MAAAAAIAKnQQF1siCfApMgnAKVIpQCIJQCQwAAAABdGyKUApMglAJDAACAP14blCKUApOUIJICIJQClJIhlAIgoAILIZUCIJQCEGoglQKUIZoCIJQCEFwglQKUIZsCIJ4CQwAAAABbBH1DAACAPwUgmAIgArSSIJkClSCXAhCLAQshlAIgQCBZIAKnIgBsaiI+IJoCID8gAEECdGoiACoCACKVApRDAACAPyCUApUglAIgRhsioQKUIKECIJsCIAAqAgQilAKUlJI4AgQgPiCbAiCVApQgoQKUIKECIJoCIJQClJSTOAIAIKMCIJIClCGSAiACQgJ8IgIgDFMNAAsLID0hACAFQgF8IgUgDlINAAsgRAshACAEQgF8IgQgCVINAAsgA0IBfCIDIAdSDQALDAELIFBBAEwNAEMAAIC/IJkClSGaAiAOpyFLQQAhAANAIFcgBKciPWwhRyA9IFhsIUZCACEFA0AgACBLaiE9IFMgBaciPmwhSCA+IFpsIUUgoAIgUiA+QQJ0aigCALKUIZUCQgAhCgJAA0AgACI+QQFqIQACQCA+IExIDQAgPiBJTg0CIAwgCX8iCEIAVw0AIAEoAsABIEdqIEhqIFkgCqciPmxqIUEgXigCwAEgRmogRWogPiBNbGohREIAIQMglQIhkgIDQCADIAl+IQYgA7SMIZsCQgAhAgNAIKACIJIClCGUAiCdAkMAAAAAWwR9IJMCBSCUAkMAAIA/IJ0CQwAAAABDAACAP0MAAAAAAn4gmgIgArSUIJsCkiKUAotDAAAAX10EQCCUAq4MAQtCgICAgICAgICAfwunQQJtsiCeApMgnwKVIpQCIJQCQwAAAABdGyKUApMglAJDAACAP14blCKUApOUIJICIJQClJIhlAIgnAILIZYCIJQCEFwhlwIgQSACQgGIIAZ8pyI+QQF0aiJDQYD8ASBEID4gW2xqIj4vAQBBAnRB8NQEaioCACKZAiCXAiCWApQimAKUID4gTkEBdCJCai8BAEECdEHw1ARqKgIAIpcCIJQCEGoglgKUIpYClJMilAKLQwAAgHeUQwAAgAiUQYCAgIgHIJQCvCJAQQF0Ij9BgICAeHEiPiA+QYCAgIgHTRtBAXZBgICAPGq+krwiPkENdkGA+AFxID5B/x9xaiA/QYCAgHhLGyBAQRB2QYCAAnFyOwEAIEIgQ2pBgPwBIJkCIJYClCCYAiCXApSSIpQCi0MAAIB3lEMAAIAIlEGAgICIByCUArwiQEEBdCI/QYCAgHhxIj4gPkGAgICIB00bQQF2QYCAgDxqvpK8Ij5BDXZBgPgBcSA+Qf8fcWogP0GAgIB4SxsgQEEQdkGAgAJxcjsBACChAiCSApQhkgIgAkICfCICIAlTDQALIANCAXwiAyAIUg0ACwsgCkIBfCIKIA5SDQALID0hAAsgBUIBfCIFIAdSDQALIARCAXwiBCALUg0ACwsgVkHwAGokAAwdCyABKAKMASFTIAEoApABIUAjAEEQayJUJAACQAJAAkACQAJAIFMoAgAOAgIAAQsCQCAAKAIADgMEAAQACyABKQMoIgwgASkDICILIAEpAxgiDn5+pyI/IAAoAggiPWpBAWsgPW0hPiAAKAIEIQAgASgCPCFZIAEoAjghWCABKAI0IVogUygCPCFNIFMoAjghWyBTKAI0IVIgQCgCwAEhTiABKAIwIUwgUygCMCFJIAEpAxAhB0MAQBxGQwAAAMAgASgCSCJAspUQiwEhmQIgDEIAVw0DIEBBAm0hPSALQgBXDQMgDkIAVw0DID4gACA+bCJRaiIAID8gACA/SBshSiABKAJMQQJxDQIgB0IAVw0DIA6nIUdBACEAA0AgWSAFpyI9bCFGID0gTWwhSEIAIQQDQCAAIEdqIUUgWCAEpyI9bCFBID0gW2whRCBOID1BAnRqKAIAsiGTAkIAIQMCfwNAIABBAWohPSAAIFFOBEAgPSAAIEpODQIaIAEoAsABIEZqIEFqIFogA6ciAGxqIUMgUygCwAEgSGogRGogACBSbGohQkIAIQIgkwIhkgIDQCBCIEkgAqciPmxqIgAvAQBBAnRB8NQEaioCACGYAiCSAhBqIZcCIEMgPiBMbGoiQEGA/AEgAC8BAkECdEHw1ARqKgIAIpYCIJICEFwilQKUIJgCIJcClJMilAKLQwAAgHeUQwAAgAiUQYCAgIgHIJQCvCI/QQF0Ij5BgICAeHEiACAAQYCAgIgHTRtBAXZBgICAPGq+krwiAEENdkGA+AFxIABB/x9xaiA+QYCAgHhLGyA/QRB2QYCAAnFyOwECIEBBgPwBIJgCIJUClCCXAiCWApSSIpQCi0MAAIB3lEMAAIAIlEGAgICIByCUArwiP0EBdCI+QYCAgHhxIgAgAEGAgICIB00bQQF2QYCAgDxqvpK8IgBBDXZBgPgBcSAAQf8fcWogPkGAgIB4SxsgP0EQdkGAgAJxcjsBACCZAiCSApQhkgIgAkICfCICIAdTDQALCyA9IQAgA0IBfCIDIA5SDQALIEULIQAgBEIBfCIEIAtSDQALIAVCAXwiBSAMUg0ACwwDCyBUQf4gNgIIIFRB59kANgIEDCMLAkAgACgCAA4DAgACAAsgASkDKCILIAEpAyAiByABKQMYIg5+fqciPyAAKAIIIj1qQQFrID1tIT4gACgCBCEAIAEoAjwhWiABKAI4IU0gASgCNCFbIFMoAjwhUiBTKAI4IU4gUygCNCFMIAEqAlghngIgASoCXCGcAiBAKALAASFJIAEoAjAhUSBTKAIwIUogASkDECEMIAEqAlRDAAAAwCABKAJIIkCylRCLASGfAiALQgBXDQEgB0IAVw0BIA5CAFcNASBAQQJtIT0gPiAAID5sIktqIgAgPyAAID9IGyFHAkAgASgCTEECcUUEQCAMQgBXDQMgDqchRkEAIQAgnAJDAAAAAFsNASAMtCKSAkMzM7M/lCGYAiABLQBgQQFxIUggkgJDzczMPpQhlwIDQCBaIAWnIj1sIUUgPSBSbCFBQgAhBANAIAAgRmohRCBNIASnIj1sIUMgPSBObCFCIEkgPUECdGooAgCyIpICIJwClSGWAiCeAiCSApQhkwJCACEDAn8DQCAAQQFqIT0gACBLTgRAID0gACBHTg0CGiABKALAASBFaiBDaiBbIAOnIgBsaiFAIFMoAsABIEFqIEJqIAAgTGxqIT9CACECIJMCIZICA0AglwIgArSSIJgClSCWAhCLASGaAiA/IEogAqciAGxqIj4qAgAhmwIgkgIQaiGZAiBAIAAgUWxqIgAgPioCBCKVAiCSAhBcIpQClEMAAIA/IJoClSCaAiBIGyKaApQgmQIgmwKUIJoClJM4AgQgACCUAiCbApQgmgKUIJkCIJUClCCaApSSOAIAIJ8CIJIClCGSAiACQgJ8IgIgDFMNAAsLID0hACADQgF8IgMgDlINAAsgRAshACAEQgF8IgQgB1INAAsgBUIBfCIFIAtSDQALDAMLIEBBAEwNAiBArCEJIA6nIUhBACEAID1BAnQhRgNAIFogBKciPWwhRSA9IFJsIUFCACEDA0AgACBIaiE9IE0gA6ciPmwhRCA+IE5sIUMgngIgSSA+QQJ0aigCALKUIZMCQgAhDQJAA0AgACI+QQFqIQACQCA+IEtIDQAgPiBHTg0CIAwgCX8iCEIAVw0AIAEoAsABIEVqIERqIFsgDaciPmxqIUIgUygCwAEgQWogQ2ogPiBMbGohQEIAIQUgkwIhkgIDQCAFIAl+IQZCACECA0AgQCBKIAJCAYggBnynIj5saiI/IEZqKgIAIZcCIJICEGohlgIgQiA+IFFsaiI+ID8qAgAilQIgkgIQXCKUApQglgIglwKUkjgCACA+IEZqIJQCIJcClCCVAiCWApSTOAIAIJ8CIJIClCGSAiACQgJ8IgIgCVMNAAsgBUIBfCIFIAhSDQALCyANQgF8Ig0gDlINAAsgPSEACyADQgF8IgMgB1INAAsgBEIBfCIEIAtSDQALDAILA0AgWiAFpyI9bCFFID0gUmwhQUIAIQQDQCAAIEZqIUQgTSAEpyI9bCFDID0gTmwhQiCeAiBJID1BAnRqKAIAspQhkwJCACEDAn8DQCAAQQFqIT0gACBLTgRAID0gACBHTg0CGiABKALAASBFaiBDaiBbIAOnIgBsaiFAIFMoAsABIEFqIEJqIAAgTGxqIT9CACECIJMCIZICA0AgPyBKIAKnIgBsaiI+KgIAIZcCIJICEGohlgIgQCAAIFFsaiIAID4qAgQilQIgkgIQXCKUApQglgIglwKUkzgCBCAAIJQCIJcClCCWAiCVApSSOAIAIJ8CIJIClCGSAiACQgJ8IgIgDFMNAAsLID0hACADQgF8IgMgDlINAAsgRAshACAEQgF8IgQgB1INAAsgBUIBfCIFIAtSDQALDAELIEBBAEwNACBArCEJIA6nIUdBACEAID1BAXQhSwNAIFkgBKciPWwhRiA9IE1sIUhCACEDA0AgACBHaiE9IFggA6ciPmwhRSA+IFtsIUEgTiA+QQJ0aigCALIhkwJCACENAkADQCAAIj5BAWohAAJAID4gUUgNACA+IEpODQIgByAJfyIIQgBXDQAgASgCwAEgRmogRWogWiANpyI+bGohRCBTKALAASBIaiBBaiA+IFJsaiFDQgAhBSCTAiGSAgNAIAUgCX4hBkIAIQIDQCBDIEkgAkIBiCAGfKciP2xqIj4gS2ovAQBBAnRB8NQEaioCACGYAiCSAhBqIZcCIEQgPyBMbGoiQkGA/AEgPi8BAEECdEHw1ARqKgIAIpYCIJICEFwilQKUIJcCIJgClJIilAKLQwAAgHeUQwAAgAiUQYCAgIgHIJQCvCJAQQF0Ij9BgICAeHEiPiA+QYCAgIgHTRtBAXZBgICAPGq+krwiPkENdkGA+AFxID5B/x9xaiA/QYCAgHhLGyBAQRB2QYCAAnFyOwEAIEIgS2pBgPwBIJUCIJgClCCWAiCXApSTIpQCi0MAAIB3lEMAAIAIlEGAgICIByCUArwiQEEBdCI/QYCAgHhxIj4gPkGAgICIB00bQQF2QYCAgDxqvpK8Ij5BDXZBgPgBcSA+Qf8fcWogP0GAgIB4SxsgQEEQdkGAgAJxcjsBACCZAiCSApQhkgIgAkICfCICIAlTDQALIAVCAXwiBSAIUg0ACwsgDUIBfCINIA5SDQALID0hAAsgA0IBfCIDIAtSDQALIARCAXwiBCAMUg0ACwsgVEEQaiQADBwLIAEoAowBIT4jAEHQAGsiUSQAAkACQAJAAkACQAJAID4oAgAiPUETSw0AID0EQCA9QQFHBEBBASA9dEHM/z9xRQ0CIFFB/iA2AkggUUHJ1AA2AkQgUUHHJjYCQEGowgIoAgAiAEGl4wAgUUFAaxAwDCsLAkAgACgCAA4DAgACAAsgPikDKCA+KQMgIgMgPikDGCICfn6nIAKnIkptIUsgPigCMEECRw0CIAEoAkgiACADp0cNAyA+KAI4IUggPigCNCFFID4oAhAhRyABKgJMIpMCQwAAAL+UQQECfyAAtxCnBJwixwKZRAAAAAAAAOBBYwRAIMcCqgwBC0GAgICAeAt0IkayIpIClRD9ASGVAiCTAowgkgKVEP0BIZQCIEdBAEwNASBKQQBMDQEgS0EATA0BIAEoAsABIUEgPigCwAEhREEAIQADQCBBIABBAXQiAWohQyABIERqIUIgALIhkwJBACFJA0AgQyBFIElsIgFqIUAgASBCaiE/QQAhAQNAIEAgASBIbCI9aiH8ASA9ID9qIT0CQCABIEZOBEAglQIgASBGa0EBdEEBcrIQiwEhkgIgAUEBaiEBDAELIJQCIAFBAWoiAbIQiwEhkgILIPwBIJMCIJIClCA9LwEAQQJ0QfDUBGoqAgCSOAIAIAEgS0cNAAsgSUEBaiJJIEpHDQALIABBAWoiACBHRw0ACwwBCwJAIAAoAgAOAwEAAQALID4pAyggPikDICICID4pAxgiCX5+IAl/IQggPigCMEEERw0DIAIgASgCSCIArFINBCA+KAI4IUEgPigCNCFEID4pAxAhBiABKgJMIpMCQwAAAL+UQQECfyAAtxCnBJwixwKZRAAAAAAAAOBBYwRAIMcCqgwBC0GAgICAeAt0IgCyIpIClRD9ASGVAiCTAowgkgKVEP0BIZQCIAZCAFcNACAJQgBXDQAgCEIAVw0AIACsIQQgASgCwAEhQyA+KALAASFCA0AgQyADp0ECdCIAaiFAIAAgQmohPyADtCGTAkIAIQUDQCBAIEQgBadsIgBqIT4gACA/aiE9QgAhAgNAID4gQSACp2wiAGoh/QEgACA9aiEAAkAgAiAEWQRAIJUCIAIgBH1CAYZCAYS0EIsBIZICIAJCAXwhAgwBCyCUAiACQgF8IgK0EIsBIZICCyD9ASCTAiCSApQgACoCAJI4AgAgAiAIUg0ACyAFQgF8IgUgCVINAAsgA0IBfCIDIAZSDQALCyBRQdAAaiQADAQLIFFB7tEANgIYIFFBitQANgIUIFFBxyY2AhBBqMICKAIAIgBBpeMAIFFBEGoQMAwnCyBRQdg6NgIIIFFBjNQANgIEIFFBxyY2AgBBqMICKAIAIgBBpeMAIFEQMAwmCyBRQYjQADYCOCBRQc/TADYCNCBRQccmNgIwQajCAigCACIAQaXjACBRQTBqEDAMJQsgUUHYOjYCKCBRQdDTADYCJCBRQccmNgIgQajCAigCACIAQaXjACBRQSBqEDAMJAsMGwsgASgCjAEhPiMAQTBrIlIkAAJAAkACQAJAID4oAgAiPUETSw0AID0EQEEBID10Qc7/P3FFDQEgUkH+IDYCKCBSQZPVADYCJCBSQccmNgIgQajCAigCACIAQaXjACBSQSBqEDAMJwsCQCAAKAIADgMBAAEACyABKAIwQQRHDQIgPigCMEEERw0BIAAoAgQiVCA+KQMoID4pAyAgPikDGH5+pyJHTg0AID4oAhAiTkEATA0AQQAgTmshRiBOQQFxIUggTkF8cSE9ID4oAjQiUSAAKAIIIkpsIUUgASgCNCJLIEpsIUEgPigCwAEiRCBRIFRsaiFDIAEoAsABIkIgSyBUbGohQCABKgJEIpQC/RMhqAIgASoCSCKTAv0TIaUCIE5BBEkhPwNAIEQgUSBUbGohTCBCIEsgVGxqIUlBACEAAkACQCA/DQAgQCBBIGFsaiBDIEUgYWxqa0EQSQ0AA0AgSSAAQQJ0IgFqIKgCIKUCIAEgTGr9AAIA/eoB/esB/QsCACAAQQRqIgAgPUcNAAsgPSIAIE5GDQELIABBf3Mh/gEgSARAIEkgAEECdCIBaiABIExqKgIAIpICIJMCIJICIJMCXRsikgIglAIgkgIglAJeGzgCACAAQQFyIQALIP4BIEZGDQADQCBJIABBAnQiAWogASBMaioCACKSAiCTAiCSAiCTAl0bIpICIJQCIJICIJQCXhs4AgAgSSABQQRqIgFqIAEgTGoqAgAikgIgkwIgkgIgkwJdGyKSAiCUAiCSAiCUAl4bOAIAIABBAmoiACBORw0ACwsgYUEBaiFhIEogVGoiVCBHSA0ACwsgUkEwaiQADAILIFJB4dAANgIIIFJB7NQANgIEIFJBxyY2AgBBqMICKAIAIgBBpeMAIFIQMAwkCyBSQYjQADYCGCBSQevUADYCFCBSQccmNgIQQajCAigCACIAQaXjACBSQRBqEDAMIwsMGgsgASgCjAEhPSABKAKQASFIIwBBkAFrIlokAAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAID0oAgAOAgEACwsgSCgCAA0CIAEoAgANAyA9KAIwQQJHDQQgSCgCMEEERw0FID0pAyAiEiA9KQMQIhV+IhYgPSkDGCIRfqchQyBIKQMYIRMgSCkDECEQAkACQCAAKAIADgMAAQMBCyBIKAI0IUIgPSgCOCFAID0oAjQhPyAAKAIQQQAgACgCDPwLACAAKAIQIUQCQCASQgBXDQAgEUIAVw0AIBVCAFcNACASQgFSIBVCCFRyIT4gFUIDgyEPIBVCeIMhAyAVQgGGIQ4gP60hDCBArSELID0oAsABIj2tIQcgRK0hCQNAIAQgC34gB3whCCAEQgGGIAl8IQYgPSBAIASnbGohAEIAIQoDQCAAID8gCqdsaiFFIEQgCiAWfqdBAXRqIUFCACEUQgAhBUIAIQICQCA+IAYgCiAOfnynIAggCiAMfnyna0EQSXJFBEADQCBBIAQgBXynQQF0aiBFIAWnQQF0av0AAQD9CwEAIAVCCHwiBSADUg0ACyADIgIgFVENAQsgFSACQn+FfCE2IA9CAFIEQANAIEEgAiASfiAEfKdBAXRqIEUgAqdBAXRqLwEAOwEAIAJCAXwhAiAUQgF8IhQgD1INAAsLIDZCA1QNAANAIEEgAiASfiAEfKdBAXRqIEUgAqdBAXRqLwEAOwEAIEEgAkIBfCIFIBJ+IAR8p0EBdGogRSAFp0EBdGovAQA7AQAgQSACQgJ8IgUgEn4gBHynQQF0aiBFIAWnQQF0ai8BADsBACBBIAJCA3wiBSASfiAEfKdBAXRqIEUgBadBAXRqLwEAOwEAIAJCBHwiAiAVUg0ACwsgCkIBfCIKIBFSDQALIARCAXwiBCASUg0ACwsCQCATQgBXDQAgEEIAVw0AIEQgQ0EBdGohRCBIKALAASFAIBNCAVEgEEIDVnEhPyAQQnyDIQNCACEFA0AgQCBCIAWnbGohQ0IAIQRCACECAkAgPwRAA0AgRCAEIAV8p0EBdGr9DAB+AAAAfgAAAH4AAAB+AAAgQyAEp0ECdGr9AAIAIqcC/eAB/QwAAIB3AACAdwAAgHcAAIB3/eYB/QwAAIAIAACACAAAgAgAAIAI/eYBIKcCQQH9qwEiqAL9DAAAAP8AAAD/AAAA/wAAAP/9Tv0MAAAAcQAAAHEAAABxAAAAcf25AUEB/a0B/QwAAIAHAACABwAAgAcAAIAH/a4B/eQBIqUCQQ39rQH9DAB8AAAAfAAAAHwAAAB8AAD9TiClAv0M/w8AAP8PAAD/DwAA/w8AAP1O/a4BIKgC/QwAAAD/AAAA/wAAAP8AAAD//Tz9UiCnAkEQ/a0B/QwAgAAAAIAAAACAAAAAgAAA/U79UCCnAv0NAAEEBQgJDA0AAQABAAEAAf1bAQAAIARCBHwiBCADUg0ACyADIgIgEFENAQsDQCBEIAIgE34gBXynQQF0akGA/AEgQyACp0ECdGoqAgAikgKLQwAAgHeUQwAAgAiUQYCAgIgHIJICvCI+QQF0Ij1BgICAeHEiACAAQYCAgIgHTRtBAXZBgICAPGq+krwiAEENdkGA+AFxIABB/x9xaiA9QYCAgHhLGyA+QRB2QYCAAnFyOwEAIAJCAXwiAiAQUg0ACwsgBUIBfCIFIBNSDQALCyABKQMgIQMgASkDGCECIAEoAsABQQACfyABKAIAIgBBEGtBcU0EQCAAQSRsQZiaAWooAgAgASgCMCABKAIQQQFrbGogASgCNCACp0EBa2xqIAEoAjggA6dBAWtsaiABKAI8IAEoAihBAWtsagwBCyABNQI0IAJCAX1+IAEpAxAgATUCMH4gAEEkbEGUmgFqNQIAf3wgATUCOCADQgF9fnwgATUCPCABKQMoQgF9fnynC/wLAAwCCyABKQMYpyI+IAAoAggiPWpBAWsgPW0iPSAAKAIEbCJPID0gT2oiPSA+ID0gPkgbIltODQEgEEIAVw0BIBVCAFcNASABKAI0IVIgACgCECJRIENBAXRqIUogASgCRCFOIBOnIUsgASgCwAEhTCASpyJNQXBxIgFBAEoEQCABQQFyIUYgTUEBcSFIIBanIUVBACBNayABQX9zRiFBA0AgTCBPIFJsaiFEIFEgRSBPbEEBdGohQ0IAIQQDQCBKIASnIgAgS2xBAXRqIkcgAUEBdCJCaiFAIAAgTmwhP0IAIQIDQCBDIAKnIj4gTWxBAXRqIUlBACFd/QwAAAAAAAAAAAAAAAAAAAAAIqYCIacC/QwAAAAAAAAAAAAAAAAAAAAAIakC/QwAAAAAAAAAAAAAAAAAAAAAIaUCA0AgpgIgRyBdQQF0IgBqIj0vAR5BAnRB8NQEaiA9LwEcQQJ0QfDUBGogPS8BGkECdEHw1ARqID0vARhBAnRB8NQEav0JAgD9VgIAAf1WAgAC/VYCAAMgACBJaiIALwEeQQJ0QfDUBGogAC8BHEECdEHw1ARqIAAvARpBAnRB8NQEaiAALwEYQQJ0QfDUBGr9CQIA/VYCAAH9VgIAAv1WAgAD/eYB/eQBIaYCIKcCID0vARZBAnRB8NQEaiA9LwEUQQJ0QfDUBGogPS8BEkECdEHw1ARqID0vARBBAnRB8NQEav0JAgD9VgIAAf1WAgAC/VYCAAMgAC8BFkECdEHw1ARqIAAvARRBAnRB8NQEaiAALwESQQJ0QfDUBGogAC8BEEECdEHw1ARq/QkCAP1WAgAB/VYCAAL9VgIAA/3mAf3kASGnAiCpAiA9LwEOQQJ0QfDUBGogPS8BDEECdEHw1ARqID0vAQpBAnRB8NQEaiA9LwEIQQJ0QfDUBGr9CQIA/VYCAAH9VgIAAv1WAgADIAAvAQ5BAnRB8NQEaiAALwEMQQJ0QfDUBGogAC8BCkECdEHw1ARqIAAvAQhBAnRB8NQEav0JAgD9VgIAAf1WAgAC/VYCAAP95gH95AEhqQIgpQIgPS8BBkECdEHw1ARqID0vAQRBAnRB8NQEaiA9LwECQQJ0QfDUBGogPS8BAEECdEHw1ARq/QkCAP1WAgAB/VYCAAL9VgIAAyAALwEGQQJ0QfDUBGogAC8BBEECdEHw1ARqIAAvAQJBAnRB8NQEaiAALwEAQQJ0QfDUBGr9CQIA/VYCAAH9VgIAAv1WAgAD/eYB/eQBIaUCIF1BEGoiXSABSA0ACyClAiCnAv3kASCpAiCmAv3kAf3kASKlAv0fAyClAv0fAiClAv0fACClAv0fAZKSkiGSAiABIE1IBEAgkgK7IcUCIEgEfyDFAiBALwEAQQJ0QfDUBGoqAgAgQiBJai8BAEECdEHw1ARqKgIAlLugIcUCIEYFIAELIQAgQUUEQANAIMUCIEcgAEEBdCI9ai8BAEECdEHw1ARqKgIAID0gSWovAQBBAnRB8NQEaioCAJS7oCBHID1BAmoiPWovAQBBAnRB8NQEaioCACA9IElqLwEAQQJ0QfDUBGoqAgCUu6AhxQIgAEECaiIAIE1HDQALCyDFArYhkgILIEQgPiA/akECdGoiACCSAiAAKgIAkjgCACACQgF8IgIgFVINAAsgBEIBfCIEIBBSDQALIE9BAWoiTyBbRw0ACwwCCyABIE1OBEAgFUJ8gyEDIE6tIQUDQCBMIE8gUmxqIQFCACEUA0AgBSAUfiEGQgAhBEIAIQICQCAVQgRaBEADQCABIAQgBnynQQJ0aiIAIAD9AAIA/QwAAAAAAAAAAAAAAAAAAAAA/eQB/QsCACAEQgR8IgQgA1INAAsgAyICIBVRDQELA0AgASACIAZ8p0ECdGoiACAAKgIAQwAAAACSOAIAIAJCAXwiAiAVUg0ACwsgFEIBfCIUIBBSDQALIE9BAWoiTyBbRw0ACwwCCyABQQFyIT0gTUEBcSFGIBanIUhBACBNayABQX9zRiFFA0AgTCBPIFJsaiFBIFEgSCBPbEEBdGohREIAIQQDQCBKIASnIgAgS2xBAXRqIkcgAUEBdCJDaiFCIAAgTmwhQEIAIQIDQCBEIAKnIj8gTWxBAXRqIUlEAAAAAAAAAAAhxQIgASEAIEYEQCBCLwEAQQJ0QfDUBGoqAgAgQyBJai8BAEECdEHw1ARqKgIAlLtEAAAAAAAAAACgIcUCID0hAAsgRUUEQANAIMUCIEcgAEEBdCI+ai8BAEECdEHw1ARqKgIAID4gSWovAQBBAnRB8NQEaioCAJS7oCBHID5BAmoiPmovAQBBAnRB8NQEaioCACA+IElqLwEAQQJ0QfDUBGoqAgCUu6AhxQIgAEECaiIAIE1HDQALCyBBID8gQGpBAnRqIgAgACoCACDFAraSOAIAIAJCAXwiAiAVUg0ACyAEQgF8IgQgEFINAAsgT0EBaiJPIFtHDQALDAELIEgoAgANBSABKAIADQYgPSgCMEEERw0HIEgoAjBBBEcNCCA9KQMgIhAgPSkDECIVfiIWID0pAxgiEX6nIUMgSCkDGCETIEgpAxAhEgJAAkAgACgCAA4DAAECAQsgSCgCNCE/ID0oAjghQiA9KAI0IUAgACgCEEEAIAAoAgz8CwAgACgCECFEAkAgEEIAVw0AIBFCAFcNACAVQgBXDQAgEEIBUiAVQghUciE+IBVCA4MhDyAVQnyDIQMgFUIChiEOIECtIQwgQq0hCyA9KALAASI9rSEHIEStIQkDQCAEIAt+IAd8IQggBEIChiAJfCEGID0gQiAEp2xqIQBCACEKA0AgACBAIAqnbGohRSBEIAogFn6nQQJ0aiFBQgAhFEIAIQVCACECAkAgPiAGIAogDn58pyAIIAogDH58p2tBEElyRQRAA0AgQSAEIAV8p0ECdGogRSAFp0ECdGr9AAIA/QsCACAFQgR8IgUgA1INAAsgAyICIBVRDQELIBUgAkJ/hXwhNyAPQgBSBEADQCBBIAIgEH4gBHynQQJ0aiBFIAKnQQJ0aioCADgCACACQgF8IQIgFEIBfCIUIA9SDQALCyA3QgNUDQADQCBBIAIgEH4gBHynQQJ0aiBFIAKnQQJ0aioCADgCACBBIAJCAXwiBSAQfiAEfKdBAnRqIEUgBadBAnRqKgIAOAIAIEEgAkICfCIFIBB+IAR8p0ECdGogRSAFp0ECdGoqAgA4AgAgQSACQgN8IgUgEH4gBHynQQJ0aiBFIAWnQQJ0aioCADgCACACQgR8IgIgFVINAAsLIApCAXwiCiARUg0ACyAEQgF8IgQgEFINAAsLAkAgE0IAVw0AIBJCAFcNACBEIENBAnRqIUAgSCgCwAEhPiATQgFSIBJCCFRyIT0gEkIDgyEIIBJCfIMhA0IAIQQDQEIAIQVCACECAkAgPSBDIASnIgBqQQJ0IERqIAAgP2wgPmoiAGtBEElyRQRAA0AgQCAEIAV8p0ECdGogACAFp0ECdGr9AAIA/QsCACAFQgR8IgUgA1INAAsgAyICIBJRDQELIBIgAkJ/hXwhOEIAIQUgCEIAUgRAA0AgQCACIBN+IAR8p0ECdGogACACp0ECdGoqAgA4AgAgAkIBfCECIAVCAXwiBSAIUg0ACwsgOEIDVA0AA0AgQCACIBN+IAR8p0ECdGogACACp0ECdGoqAgA4AgAgQCACQgF8IgUgE34gBHynQQJ0aiAAIAWnQQJ0aioCADgCACBAIAJCAnwiBSATfiAEfKdBAnRqIAAgBadBAnRqKgIAOAIAIEAgAkIDfCIFIBN+IAR8p0ECdGogACAFp0ECdGoqAgA4AgAgAkIEfCICIBJSDQALCyAEQgF8IgQgE1INAAsLIAEpAyAhAyABKQMYIQIgASgCwAFBAAJ/IAEoAgAiAEEQa0FxTQRAIABBJGxBmJoBaigCACABKAIwIAEoAhBBAWtsaiABKAI0IAKnQQFrbGogASgCOCADp0EBa2xqIAEoAjwgASgCKEEBa2xqDAELIAE1AjQgAkIBfX4gASkDECABNQIwfiAAQSRsQZSaAWo1AgB/fCABNQI4IANCAX1+fCABNQI8IAEpAyhCAX1+fKcL/AsADAELIAEpAxinIj4gACgCCCI9akEBayA9bSI9IAAoAgRsIk8gPSBPaiI9ID4gPSA+SBsiSU4NACASQgBXDQAgFUIAVw0AIAEoAjQhUSAAKAIQIkcgQ0ECdGohRiABKAJEIUogE6chSCABKALAASFLIBCnIlJBcHEiAUEASgRAIBanIUUgASBSTgRAA0AgSyBPIFFsaiFDIEcgRSBPbEECdGohQkIAIQQDQCBKIASnIgBsIUAgRiAAIEhsQQJ0aiE/QgAhAgNAIEIgAqciPiBSbEECdGohPUEAIV39DAAAAAAAAAAAAAAAAAAAAAAipgIhpwL9DAAAAAAAAAAAAAAAAAAAAAAhqQL9DAAAAAAAAAAAAAAAAAAAAAAhpQIDQCCmAiA/IF1BAnQiAGoiRP0AADAgACA9aiIA/QAAMP3mAf3kASGmAiCnAiBE/QAAICAA/QAAIP3mAf3kASGnAiCpAiBE/QAAECAA/QAAEP3mAf3kASGpAiClAiBE/QAAACAA/QAAAP3mAf3kASGlAiBdQRBqIl0gAUgNAAsgQyA+IEBqQQJ0aiIAIKUCIKcC/eQBIKkCIKYC/eQB/eQBIqUC/R8DIKUC/R8CIKUC/R8AIKUC/R8BkpKSIAAqAgCSOAIAIAJCAXwiAiAVUg0ACyAEQgF8IgQgElINAAsgT0EBaiJPIElHDQAMAwsACyBSQQNxIUEgAUF/cyBSakEDSSFEA0AgSyBPIFFsaiFDIEcgRSBPbEECdGohQkIAIQQDQCBKIASnIgBsIUAgRiAAIEhsQQJ0aiFOQgAhAgNAIEIgAqciPyBSbEECdGohTEEAIT39DAAAAAAAAAAAAAAAAAAAAAAipgIhpwL9DAAAAAAAAAAAAAAAAAAAAAAhqQL9DAAAAAAAAAAAAAAAAAAAAAAhpQIDQCCmAiBOID1BAnQiAGoiPv0AADAgACBMaiIA/QAAMP3mAf3kASGmAiCnAiA+/QAAICAA/QAAIP3mAf3kASGnAiCpAiA+/QAAECAA/QAAEP3mAf3kASGpAiClAiA+/QAAACAA/QAAAP3mAf3kASGlAiA9QRBqIj0gAUgNAAsgpQIgpwL95AEgqQIgpgL95AH95AEipQL9HwMgpQL9HwIgpQL9HwAgpQL9HwGSkpIhkgJBACE9IAEhACBBBEADQCBOIABBAnQiPmoqAgAgPiBMaioCAJQgkgKSIZICIABBAWohACA9QQFqIj0gQUcNAAsLIERFBEADQCBOIABBAnQiPkEMaiI9aioCACA9IExqKgIAlCBOID5BCGoiPWoqAgAgPSBMaioCAJQgTiA+QQRqIj1qKgIAID0gTGoqAgCUID4gTmoqAgAgPiBMaioCAJQgkgKSkpKSIZICIABBBGoiACBSRw0ACwsgQyA/IEBqQQJ0aiIAIJICIAAqAgCSOAIAIAJCAXwiAiAVUg0ACyAEQgF8IgQgElINAAsgT0EBaiJPIElHDQALDAELIAEgUk4EQCAVQnyDIQMgSq0hBQNAIEsgTyBRbGohAUIAIRQDQCAFIBR+IQZCACEEQgAhAgJAIBVCBFoEQANAIAEgBCAGfKdBAnRqIgAgAP0AAgD9DAAAAAAAAAAAAAAAAAAAAAD95AH9CwIAIARCBHwiBCADUg0ACyADIgIgFVENAQsDQCABIAIgBnynQQJ0aiIAIAAqAgBDAAAAAJI4AgAgAkIBfCICIBVSDQALCyAUQgF8IhQgElINAAsgT0EBaiJPIElHDQALDAELIFJBA3EhQSAWpyFEIAFBf3MgUmpBA0khQwNAIEsgTyBRbGohQiBHIEQgT2xBAnRqIUBCACEEA0AgSiAEpyIAbCE/IEYgACBIbEECdGohTkIAIQIDQCBAIAKnIj4gUmxBAnRqIUxBACFdQwAAAAAhkgIgASEAIEEEQANAIE4gAEECdCI9aioCACA9IExqKgIAlCCSApIhkgIgAEEBaiEAIF1BAWoiXSBBRw0ACwsgQ0UEQANAIE4gAEECdCJFQQxqIj1qKgIAID0gTGoqAgCUIE4gRUEIaiI9aioCACA9IExqKgIAlCBOIEVBBGoiPWoqAgAgPSBMaioCAJQgRSBOaioCACBFIExqKgIAlCCSApKSkpIhkgIgAEEEaiIAIFJHDQALCyBCID4gP2pBAnRqIgAgkgIgACoCAJI4AgAgAkIBfCICIBVSDQALIARCAXwiBCASUg0ACyBPQQFqIk8gSUcNAAsLIFpBkAFqJAAMCQsgWkH7OzYCSCBaQfTZADYCRCBaQccmNgJAQajCAigCACI9QaXjACBaQUBrEDAMLQsgWkHgOzYCOCBaQfXZADYCNCBaQccmNgIwQajCAigCACI9QaXjACBaQTBqEDAMLAsgWkHC0gA2AiggWkGB2gA2AiQgWkHHJjYCIEGowgIoAgAiPUGl4wAgWkEgahAwDCsLIFpBtNAANgIYIFpBgtoANgIUIFpBxyY2AhBBqMICKAIAIj1BpeMAIFpBEGoQMAwqCyBaQfs7NgKIASBaQdLaADYChAEgWkHHJjYCgAFBqMICKAIAIj1BpeMAIFpBgAFqEDAMKQsgWkHgOzYCeCBaQdPaADYCdCBaQccmNgJwQajCAigCACI9QaXjACBaQfAAahAwDCgLIFpB4dAANgJoIFpB39oANgJkIFpBxyY2AmBBqMICKAIAIj1BpeMAIFpB4ABqEDAMJwsgWkG00AA2AlggWkHg2gA2AlQgWkHHJjYCUEGowgIoAgAiPUGl4wAgWkHQAGoQMAwmCyBaQf4gNgIIIFpButsANgIEIFpBxyY2AgBBqMICKAIAIj1BpeMAIFoQMAwlCwwZCyABKAKMASE+IAEoApABIUAjAEHgAGsiSCQAAkACQAJAAkACQAJAID4oAgAiPUEBRwRAID0NASBIQf4gNgJYIEhBoNwANgJUIEhBxyY2AlBBqMICKAIAIgBBpeMAIEhB0ABqEDAMJwsgQCgCAA0BIAEoAgBBAUcNAiA+KAIwQQJHDQMgQCgCMEEERw0EAkACQCAAKAIADgMBAAEACyBAKQMoIEApAyAiAiABKAJcQQFGIj8bIhpCAFcNACABKQMgQgEgPxsiKkIAVw0AIAEpAxgiK0IAVw0AIAIgQCkDGCICID8bIh4gADQCBCIDVw0AID4pAxhCASA/GyIpQgBXDQAgPikDECIoQgBXDQAgQCgCOCI9IEAoAjQgPxshQSBAKAI8ID0gPxshRCACQgEgPxshICABNAJYISQgATQCVCElIAE0AlAhIyABNAJMIR8gATQCSCEZIAE0AkQhGyBAKQMQISYgASgCwAEhRSAoICl+IgIgHn4hFyBAKALAASFDIAIgADQCCCIcfiEYICinQQF0IUIgAiADfkIBhkL+////D4MhFSAoIB4gKX5+IgJCAYZC/v///w+DIRIgAiArfkIBhiICQv7///8PgyEQIAIgKn5C/v///w+DIRMDQCAFICp+IRYgBSATfiAVfCERIEMgRCAFp2xqIUBCACENA0AgESANIBB+fCEPIA0gGX4gI30hDiANIBZ8ICt+IQxCACEKA0AgDyAKIBJ+fCELIAogG34gH30hByBFIBcgCiAMfH6nQQF0aiE/QgAhIiADIQIDQCACICl+IQkgGCAifiEIIEAgQSACp2xqIT5CACEUA0ACQAJAIBQgJH4gDnwiBEIAUw0AIAQgIFkNACAJIBR8ICh+IQYgBCAmfiEEQgAhIQNAQQAhAAJAICEgJX4gB3wiHUIAUw0AIB0gJlkNAEGA/AEgPiAEIB18p0ECdGoqAgAikgKLQwAAgHeUQwAAgAiUQYCAgIgHIJICvCI9QQF0IgFBgICAeHEiACAAQYCAgIgHTRtBAXZBgICAPGq+krwiAEENdkGA+AFxIABB/x9xaiABQYCAgHhLGyA9QRB2QYCAAnFyIQALID8gBiAhfKdBAXRqIAA7AQAgIUIBfCIhIChSDQALDAELIEUgCyAUICh+IAh8QgGGfKdqQQAgQvwLAAsgFEIBfCIUIClSDQALICJCAXwhIiACIBx8IgIgHlMNAAsgCkIBfCIKICtSDQALIA1CAXwiDSAqUg0ACyAFQgF8IgUgGlINAAsLIEhB4ABqJAAMBQsgSEH+IDYCCCBIQaTcADYCBCBIQccmNgIAQajCAigCACIAQaXjACBIEDAMJQsgSEH7OzYCSCBIQcjbADYCRCBIQccmNgJAQajCAigCACIAQaXjACBIQUBrEDAMJAsgSEHpODYCOCBIQcnbADYCNCBIQccmNgIwQajCAigCACIAQaXjACBIQTBqEDAMIwsgSEHC0gA2AiggSEHp2wA2AiQgSEHHJjYCIEGowgIoAgAiAEGl4wAgSEEgahAwDCILIEhBtNAANgIYIEhB6tsANgIUIEhBxyY2AhBBqMICKAIAIgBBpeMAIEhBEGoQMAwhCwwYCyABKAKMASFFIAEoApABIUYgASE+IwBB0ABrIlAkAAJAIEUoAgBBAUYEQCBGKAIARQRAIAEoAgBFBEAgRSgCMEECRgRAIEYoAjBBBEYEQCBFKQMoIhsgRf0AAxAipQL9HQAiGX4iCSClAv0dASIcfiIVIEUpAyAiEn6nIUIgRikDICEXIEb9AAMQIagCAkACQCAAKAIADgMAAQcBCyBGKAI4IUEgRigCNCFEIEUoAjwhQCBFKAI4IT8gACgCEEEAIAAoAgz8CwAgACgCECFDAkAgG0IAVw0AIBJCAFcNACClAv0MAQAAAAAAAAABAAAAAAAAAP3YASKlAv0dASClAv0dAISnQQFxDQAgG0IBUiAZQghUciE9IBlCAYMhECAZQniDIQQgGUIBhkL+////D4MhEyAZIBx+QgGGIRYgP60hESBArSEPIEUoAsABIgGtIQ4gQ60hDANAIAUgD34gDnwhCyAFQgGGIAx8IQcgASBAIAWnbGohAEIAIQoDQCALIAogEX58IQkgByAKIBZ+fCEIIAAgPyAKp2xqIUggQyAKIBV+p0EBdGohRUIAISIDQCAZICJ+IRhCACECQgAhAwJAID0gCCATICJ+IgZ8pyAGIAl8p2tBEElyRQRAA0AgRSACIBh8IgMgBXynQQF0aiBIIAOnQQF0av0AAQD9CwEAIAJCCHwiAiAEUg0ACyAEIgMgGVENAQsgA0IBhCECIBCnBEAgRSADIBh8IgMgG34gBXynQQF0aiBIIAOnQQF0ai8BADsBACACIQMLIAIgGVENAANAIEUgAyAYfCICIBt+IAV8p0EBdGogSCACp0EBdGovAQA7AQAgRSACQgF8IgIgG34gBXynQQF0aiBIIAKnQQF0ai8BADsBACADQgJ8IgMgGVINAAsLICJCAXwiIiAcUg0ACyAKQgF8IgogElINAAsgBUIBfCIFIBtSDQALCwJAIBdCAFcNACCoAv0dASIGQgBXDQAgqAL9HQAiCEIAVw0AIEMgQkEBdGohQyAIIBd+IQUgF6chRyBGKALAASFCIBdCAVEgCEIDVnEhQCAIQnyDIQQDQCBCIEEgDaciRmxqIT9CACEDA0AgPyBEIAOnbGohSCBDIAMgBX6nQQF0aiFFQgAhAgJAIEAEQANAIEUgAqciACBHbCBGakEBdGr9DAB+AAAAfgAAAH4AAAB+AAAgSCAAQQJ0av0AAgAipwL94AH9DAAAgHcAAIB3AACAdwAAgHf95gH9DAAAgAgAAIAIAACACAAAgAj95gEgpwJBAf2rASKoAv0MAAAA/wAAAP8AAAD/AAAA//1O/QwAAABxAAAAcQAAAHEAAABx/bkBQQH9rQH9DAAAgAcAAIAHAACABwAAgAf9rgH95AEipQJBDf2tAf0MAHwAAAB8AAAAfAAAAHwAAP1OIKUC/Qz/DwAA/w8AAP8PAAD/DwAA/U79rgEgqAL9DAAAAP8AAAD/AAAA/wAAAP/9PP1SIKcCQRD9rQH9DACAAAAAgAAAAIAAAACAAAD9Tv1QIKcC/Q0AAQQFCAkMDQABAAEAAQAB/VsBAAAgAkIEfCICIARSDQALIAQiAiAIUQ0BCwNAIEUgAqciACBHbCBGakEBdGpBgPwBIEggAEECdGoqAgAikgKLQwAAgHeUQwAAgAiUQYCAgIgHIJICvCI9QQF0IgFBgICAeHEiACAAQYCAgIgHTRtBAXZBgICAPGq+krwiAEENdkGA+AFxIABB/x9xaiABQYCAgHhLGyA9QRB2QYCAAnFyOwEAIAJCAXwiAiAIUg0ACwsgA0IBfCIDIAZSDQALIA1CAXwiDSAXUg0ACwsgPikDKCEFID4pAxghBCA+KQMQIQMgPikDICECID4oAsABQQACfyA+KAIAIgBBEGtBcU0EQCAAQSRsQZiaAWooAgAgPigCMCADp0EBa2xqID4oAjQgBKdBAWtsaiA+KAI4IAKnQQFrbGogPigCPCAFp0EBa2xqDAELID41AjQgBEIBfX4gAyA+NQIwfiAAQSRsQZSaAWo1AgB/fCA+NQI4IAJCAX1+fCA+NQI8IAVCAX1+fKcL/AsADAYLID4pAyCnIj0gACgCCCIBakEBayABbSIBIAAoAgRsIl0gASBdaiIBID0gASA9SBsiUU4NBSCoAv0MAQAAAAAAAAABAAAAAAAAAP3YASClAv0MAQAAAAAAAAABAAAAAAAAAP3YAf0NAAECAwgJCgsQERITGBkaG/1TDQUgPigCOCFKIAAoAhAiSyBCQQF0aiFbID4pAxCnIVogPigCwAEhRyAbpyJTQXBxIgFBAXIhPSBTQQFxIVIgGUJ8gyEDIAFBf3MgU2ohTiCoAv0dASEHIKgC/R0AIQsgFachRiA+KAJEIlmtIQggAUEASiFIA0AgRyBKIF1saiFYIEsgRiBdbEEBdGohTEIAIRQCQAJAIEhFBEBCACEKIAEgU0gNAQNAIAggCn4hBkIAIRQDQCBZIBSnbCE+QgAhBANAIAQgBnynIFpsID5qIT9CACEFQgAhAgJAIBlCBFoEQANAIFggPyAFp2pBAnRqIgAgAP0AAgD9DAAAAAAAAAAAAAAAAAAAAAD95AH9CwIAIAVCBHwiBSADUg0ACyADIgIgGVENAQsDQCBYID8gAqdqQQJ0aiIAIAAqAgBDAAAAAJI4AgAgAkIBfCICIBlSDQALCyAEQgF8IgQgHFINAAsgFEIBfCIUIAtSDQALIApCAXwiCiAHUg0ACwwCCwNAIAsgFH4hBiBZIBSnbCFFQgAhBANAIFsgBCAGfCAXfqdBAXRqIkkgAUEBdCJBaiFEIFkgBKdsIUNCACEFA0AgRSAFp2ogWmwgQ2ohQiBMIAUgCX6nQQF0aiFAQgAhAgNAIEAgAqciPyBTbEEBdGohTUEAIVf9DAAAAAAAAAAAAAAAAAAAAAAipgIhpwL9DAAAAAAAAAAAAAAAAAAAAAAhqQL9DAAAAAAAAAAAAAAAAAAAAAAhpQIDQCCmAiBJIFdBAXQiAGoiPi8BHkECdEHw1ARqID4vARxBAnRB8NQEaiA+LwEaQQJ0QfDUBGogPi8BGEECdEHw1ARq/QkCAP1WAgAB/VYCAAL9VgIAAyAAIE1qIgAvAR5BAnRB8NQEaiAALwEcQQJ0QfDUBGogAC8BGkECdEHw1ARqIAAvARhBAnRB8NQEav0JAgD9VgIAAf1WAgAC/VYCAAP95gH95AEhpgIgpwIgPi8BFkECdEHw1ARqID4vARRBAnRB8NQEaiA+LwESQQJ0QfDUBGogPi8BEEECdEHw1ARq/QkCAP1WAgAB/VYCAAL9VgIAAyAALwEWQQJ0QfDUBGogAC8BFEECdEHw1ARqIAAvARJBAnRB8NQEaiAALwEQQQJ0QfDUBGr9CQIA/VYCAAH9VgIAAv1WAgAD/eYB/eQBIacCIKkCID4vAQ5BAnRB8NQEaiA+LwEMQQJ0QfDUBGogPi8BCkECdEHw1ARqID4vAQhBAnRB8NQEav0JAgD9VgIAAf1WAgAC/VYCAAMgAC8BDkECdEHw1ARqIAAvAQxBAnRB8NQEaiAALwEKQQJ0QfDUBGogAC8BCEECdEHw1ARq/QkCAP1WAgAB/VYCAAL9VgIAA/3mAf3kASGpAiClAiA+LwEGQQJ0QfDUBGogPi8BBEECdEHw1ARqID4vAQJBAnRB8NQEaiA+LwEAQQJ0QfDUBGr9CQIA/VYCAAH9VgIAAv1WAgADIAAvAQZBAnRB8NQEaiAALwEEQQJ0QfDUBGogAC8BAkECdEHw1ARqIAAvAQBBAnRB8NQEav0JAgD9VgIAAf1WAgAC/VYCAAP95gH95AEhpQIgV0EQaiJXIAFIDQALIKUCIKcC/eQBIKkCIKYC/eQB/eQBIqUC/R8DIKUC/R8CIKUC/R8AIKUC/R8BkpKSIZICIAEgU0gEQCCSArshxQIgUgR/IMUCIEQvAQBBAnRB8NQEaioCACBBIE1qLwEAQQJ0QfDUBGoqAgCUu6AhxQIgPQUgAQshACBOBEADQCDFAiBJIABBAXQiPmovAQBBAnRB8NQEaioCACA+IE1qLwEAQQJ0QfDUBGoqAgCUu6AgSSA+QQJqIj5qLwEAQQJ0QfDUBGoqAgAgPiBNai8BAEECdEHw1ARqKgIAlLugIcUCIABBAmoiACBTRw0ACwsgxQK2IZICCyBYID8gQmpBAnRqIgAgkgIgACoCAJI4AgAgAkIBfCICIBlSDQALIAVCAXwiBSAcUg0ACyAEQgF8IgQgC1INAAsgByAUQgF8IhRSDQALDAELA0AgCiALfiEGIFkgCqdsIUVCACEEA0AgWyAEIAZ8IBd+p0EBdGoiSSABQQF0IkFqIUQgWSAEp2whQ0IAIQUDQCBFIAWnaiBabCBDaiFCIEwgBSAJfqdBAXRqIUBCACECA0AgQCACpyI/IFNsQQF0aiFNRAAAAAAAAAAAIcUCIAEhACBSBEAgRC8BAEECdEHw1ARqKgIAIEEgTWovAQBBAnRB8NQEaioCAJS7RAAAAAAAAAAAoCHFAiA9IQALIE4EQANAIMUCIEkgAEEBdCI+ai8BAEECdEHw1ARqKgIAID4gTWovAQBBAnRB8NQEaioCAJS7oCBJID5BAmoiPmovAQBBAnRB8NQEaioCACA+IE1qLwEAQQJ0QfDUBGoqAgCUu6AhxQIgAEECaiIAIFNHDQALCyBYID8gQmpBAnRqIgAgACoCACDFAraSOAIAIAJCAXwiAiAZUg0ACyAFQgF8IgUgHFINAAsgBEIBfCIEIAtSDQALIApCAXwiCiAHUg0ACwsgUSBdQQFqIl1HDQALDAULIFBBtNAANgIIIFBBv9wANgIEIFBBxyY2AgBBqMICKAIAIgBBpeMAIFAQMAwkCyBQQcLSADYCGCBQQb7cADYCFCBQQccmNgIQQajCAigCACIAQaXjACBQQRBqEDAMIwsgUEHgOzYCKCBQQbLcADYCJCBQQccmNgIgQajCAigCACIAQaXjACBQQSBqEDAMIgsgUEH7OzYCOCBQQbHcADYCNCBQQccmNgIwQajCAigCACIAQaXjACBQQTBqEDAMIQsgUEGEOTYCSCBQQbDcADYCRCBQQccmNgJAQajCAigCACIAQaXjACBQQUBrEDAMIAsgUEHQAGokAAwXCyABKAKMASE9IwBBMGsiRSQAAkACQAJAIAEoAlBFBEAgASgCSCJBIAEoAkxHDQECQAJAIAAoAgAOAwEAAQALIAEoAkQhPiA9KQMgIQMgPSkDGCECID0oAsABIU8CfyA9KAIAIgBBEGtBcU0EQCAAQSRsQZiaAWooAgAgPSgCMCA9KAIQQQFrbGogPSgCNCJkIAKnQQFrbGogPSgCOCADp0EBa2xqID0oAjwgPSgCKEEBa2xqDAELID0oAjQiZK0gAkIBfX4gPSkDECA9NQIwfiAAQSRsQZSaAWo1AgB/fCA9NQI4IANCAX1+fCA9NQI8ID0pAyhCAX1+fKcLIgBBAEwNACABKQMQIgRCAFcNACA+QQJGDQMgACBPaiFDIAEoAsABIT0gBKchQiBBsiGTAiBBQQBKBEAgPkEBRgRAIEFBA3EhPyBBQQRJIT4DQEIAIQJBACEBA0AgPSACp0ECdGoiREEANgIAQwAAAAAhkgIgASEAQQAhYSA/BEADQCBEIJICIE8gAEECdGoqAgCSIpICOAIAIABBAWohACBhQQFqImEgP0cNAAsLIAEgQWohASA+RQRAA0AgRCCSAiBPIABBAnRqIkAqAgCSIpICOAIAIEQgkgIgQCoCBJIikgI4AgAgRCCSAiBAKgIIkiKSAjgCACBEIJICIEAqAgySIpICOAIAIABBBGoiACABRw0ACwsgRCCSAiCTApU4AgAgAkIBfCICIARSDQALID0gQkECdGohPSBPIGRqIk8gQ0kNAAsMAgsgPg0BIEFBA3EhPyBBQQRJIT4DQEEAIQFCACECA0AgPSACp0ECdGoiREH///97NgIAQ///f/8hkgIgASEAQQAhYSA/BEADQCCSAiBPIABBAnRqKgIAIpMCXQRAIEQgkwI4AgAgkwIhkgILIABBAWohACBhQQFqImEgP0cNAAsLIAEgQWohASA+RQRAA0AgkgIgTyAAQQJ0aiJAKgIAIpMCXQRAIEQgkwI4AgAgkwIhkgILIJICIEAqAgQikwJdBEAgRCCTAjgCACCTAiGSAgsgkgIgQCoCCCKTAl0EQCBEIJMCOAIAIJMCIZICCyCSAiBAKgIMIpMCXQRAIEQgkwI4AgAgkwIhkgILIABBBGoiACABRw0ACwsgAkIBfCICIARSDQALID0gQkECdGohPSBPIGRqIk8gQ0kNAAsMAQsgPkEBRgRAIARCfIMhA0MAAAAAIJMClSKSAv0TIaUCIARCBFQhAANAQgAhAgJAIABFBEADQCA9IAKnQQJ0aiClAv0LAgAgAkIEfCICIANSDQALIAMiAiAEUQ0BCwNAID0gAqdBAnRqIJICOAIAIAJCAXwiAiAEUg0ACwsgPSBCQQJ0aiE9IE8gZGoiTyBDSQ0ACwwBCyA+DQAgBEJ8gyEDIARCBFQhAANAQgAhAgJAIABFBEADQCA9IAKnQQJ0av0M//9/////f////3////9///0LAgAgAkIEfCICIANSDQALIAMiAiAEUQ0BCwNAID0gAqdBAnRqQf///3s2AgAgAkIBfCICIARSDQALCyA9IEJBAnRqIT0gTyBkaiJPIENJDQALCyBFQTBqJAAMAwsgRUG/wQA2AiggRUHP3QA2AiQgRUHHJjYCIEGowgIoAgAiYUGl4wAgRUEgahAwDCILIEVBpT82AhggRUHQ3QA2AhQgRUHHJjYCEEGowgIoAgAiYUGl4wAgRUEQahAwDCELIEVB/iA2AgggRUGt3QA2AgQgRUHHJjYCAEGowgIoAgAiYUGl4wAgRRAwDCALDBYLIAAoAgAhACABKAKMASFBIwBBIGsiRiQAAkACQAJAAkAgAA4DAQABAAsgQSkDICECIEEpAxghDiABKAJcIUIgASgCWCFEIAEoAlQhQCABKAJQIUMgASgCTCE/IAEoAkghPiBBKALAASFJIAEoAkQhRwJ/IEEoAgAiAEEQa0FxTQRAIABBJGxBmJoBaigCACBBKAIwIEEpAxAiBKdBAWtsaiBBKAI0Ij0gDqdBAWtsaiBBKAI4Il0gAqdBAWtsaiBBKAI8IEEoAihBAWtsagwBCyBBKAI0Ij2tIA5CAX1+IEEpAxAiBCBBNQIwfiAAQSRsQZSaAWo1AgB/fCBBKAI4Il2tIAJCAX1+fCBBNQI8IEEpAyhCAX1+fKcLIgBBAEwNACABKQMYIg9CAFcNACABKQMQIhFCAFcNAAJAAkAgR0ECRwRAIAAgSWohRSABKALAASEAIA8gEX6nIUEgPiA/bLIhkwIgEachSCA/QQBMDQEgPkEATA0CID6tIgJC/v///w+DIQsgAkIBgyEHIAJCAX0hCSA/rSEIIEdBAWshPwNAQgAhHgNAIAAgHqciPiBIbEECdGohASA+IEBsIEJrrCEGQgAhIQNAIAEgIaciPkECdGohSwJAAkACQCBHDgIBAAILIEtBADYCACA+IENsIERrrCEMQgAhAwNAAkAgAyAGfCICQgBTDQAgDiACQv////8Pg1cNACBJID0gAqdsaiE+QgAhAkIAIQ0gCUIAUgRAA0ACQCACIAx8IgVCAFMNACAEIAVC/////w+DVw0AIEsgPiAFp0ECdGoqAgAgSyoCAJI4AgALAkAgAkIBhCAMfCIFQgBTDQAgBCAFQv////8Pg1cNACBLID4gBadBAnRqKgIAIEsqAgCSOAIACyACQgJ8IQIgDUICfCINIAtSDQALCyAHUA0AIAIgDHwiAkIAUw0AIAQgAkL/////D4NXDQAgSyA+IAKnQQJ0aioCACBLKgIAkjgCAAsgA0IBfCIDIAhSDQALDAELIEtB////ezYCACA+IENsIERrrCEMQgAhAwNAAkAgAyAGfCICQgBTDQAgDiACQv////8Pg1cNACBJID0gAqdsaiE+QgAhAkIAIQ0gCUIAUgRAA0ACQCACIAx8IgVCAFMNACAEIAVC/////w+DVw0AID4gBadBAnRqKgIAIpICIEsqAgBeRQ0AIEsgkgI4AgALAkAgAkIBhCAMfCIFQgBTDQAgBCAFQv////8Pg1cNACA+IAWnQQJ0aioCACKSAiBLKgIAXkUNACBLIJICOAIACyACQgJ8IQIgDUICfCINIAtSDQALCyAHUA0AIAIgDHwiAkIAUw0AIAQgAkL/////D4NXDQAgPiACp0ECdGoqAgAikgIgSyoCAF5FDQAgSyCSAjgCAAsgA0IBfCIDIAhSDQALCwJAAkACQCA/DgIBAAILIEZB/iA2AhggRkGV3gA2AhQgRkHHJjYCEEGowgIoAgAiSUGl4wAgRkEQahAwDAkLIEsgSyoCACCTApU4AgALICFCAXwiISARUg0ACyAeQgF8Ih4gD1INAAsgACBBQQJ0aiEAIEkgXWoiSSBFSQ0ACwwDCyBGQf4gNgIIIEZB/90ANgIEIEZBxyY2AgBBqMICKAIAIklBpeMAIEYQMAwDCyBHQQFGBEAgEUJ8gyEDQwAAAAAgkwKVIpIC/RMhpQIDQEIAIQ0DQCAAIA2nIEhsQQJ0aiEBQgAhBEIAIQICQCARQgRaBEADQCABIASnQQJ0aiClAv0LAgAgBEIEfCIEIANSDQALIAMiAiARUQ0BCwNAIAEgAqdBAnRqIJICOAIAIAJCAXwiAiARUg0ACwsgDUIBfCINIA9SDQALIAAgQUECdGohACBJIF1qIkkgRUkNAAsMAgsgEUJ8gyEDIEhBAnQhQiBBQQJ0IUBBACEBIAAhPQNAIAEgQGwhPkIAIQ0DQCANpyE/AkACQAJAIEcOAgABAgsgPSA/IEhsQQJ0aiE/QgAhAiARQgRaBEADQCA/IAKnQQJ0av0M//9/////f////3////9///0LAgAgAkIEfCICIANSDQALIAMiAiARUQ0CCwNAID8gAqdBAnRqQf///3s2AgAgAkIBfCICIBFSDQALDAELIAAgPiA/IEJsampBACBC/AsACyANQgF8Ig0gD1INAAsgAUEBaiEBID0gQGohPSBJIF1qIkkgRUkNAAsMAQsgR0EBRwRAIBFCfIMhBSARQgODIQYDQEIAIQMDQCAAIAOnIEhsQQJ0aiE9QgAhAkIAIQQgEUIEWgRAA0AgAqdBAnQhAUP//3//IZICAkACQAJAIEcOAgEAAgtDAAAAACGSAgsgASA9aiCSAjgCAAtD//9//yGSAgJAAkACQCBHDgIBAAILQwAAAAAhkgILID0gAUEEcmogkgI4AgALQ///f/8hkgICQAJAAkAgRw4CAQACC0MAAAAAIZICCyA9IAFBCHJqIJICOAIAC0P//3//IZICAkACQAJAIEcOAgEAAgtDAAAAACGSAgsgPSABQQxyaiCSAjgCAAsgAkIEfCECIARCBHwiBCAFUg0ACwtCACEEIAZCAFIEQANAQ///f/8hkgICQAJAAkAgRw4CAQACC0MAAAAAIZICCyA9IAKnQQJ0aiCSAjgCAAsgAkIBfCECIARCAXwiBCAGUg0ACwsgA0IBfCIDIA9SDQALIAAgQUECdGohACBJIF1qIkkgRUkNAAsMAQsgEUJ8gyEDQwAAAAAgkwKVIpIC/RMhpQIDQEIAIQ0DQCAAIA2nIEhsQQJ0aiEBQgAhBEIAIQICQCARQgRaBEADQCABIASnQQJ0aiClAv0LAgAgBEIEfCIEIANSDQALIAMiAiARUQ0BCwNAIAEgAqdBAnRqIJICOAIAIAJCAXwiAiARUg0ACwsgDUIBfCINIA9SDQALIAAgQUECdGohACBJIF1qIkkgRUkNAAsLIEZBIGokAAwBCyBJEDMaDCILDBULIAEoAowBIT0jAEEgayJJJAACQAJAID0oAgBFBEACQAJAIAAoAgAOAwEAAQALID0oAjBBBEcNAiA9KQMoIgtCAFcNACA9KQMgIgcgADQCBCIDVw0AIAEpAxgiCUIAVw0AIAEpAxAiDEIAVw0AID0oAjwhRiA9KAI4IUggPSgCNCFFIAEoAkQhUSAMQn6DIQggDEIBgyEGIAEoAjwhQSABKAI4IUQgASgCNCFDIAEoAjAhSiABKALAASFCID0oAsABIUADQCBCIEEgBaciAGxqIT8gQCAAIEZsaiE+IAMhAgNAID8gRCACpyIAbGohPSA+IAAgSGxqIQFCACEKA0AgPSBDIAqnIgBsaiFLIAEgACBRbSBFbGohR0IAIQRCACEUIAxCAVIEQANAIEsgSiAEpyIAbGogRyAAIFFtQQJ0aioCADgCACBLIEogAEEBciIAbGogRyAAIFFtQQJ0aioCADgCACAEQgJ8IQQgFEICfCIUIAhSDQALCyAGpwRAIEsgSiAEpyIAbGogRyAAIFFtQQJ0aioCADgCAAsgCkIBfCIKIAlSDQALIAJCAXwiAiAHUg0ACyAFQgF8IgUgC1INAAsLIElBIGokAAwCCyBJQf4gNgIYIElB0d4ANgIUIElBxyY2AhBBqMICKAIAIgBBpeMAIElBEGoQMAweCyBJQanPADYCCCBJQareADYCBCBJQccmNgIAQajCAigCACIAQaXjACBJEDAMHQsMFAsgASgCRCI9QQJPDRUgACFCIAEoAowBIXsgASgCkAEhfyABKAKUASFfID1BAEchdiABIUQjAEGQA2siYCQAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQCB7KAIADgIOAAELIHspAxAiECBEKQMQUg0MIHspAxgiEyBEKQMYUg0LIH8pAxgiEiATfSIFQgBTDQogeygCMEECRw0JIH8oAjBBAkcNCCBfKAIwQQJHDQcgfykDECAQUg0GIF8pAxggEFINBSBEKAIwQQRHDQQgRCgCNCJ1QQNNDQMgdSBEKAI4InlLDQIgeSBEKAI8ImNLDQECQCBCKAIADgMPAA8ACyB7KQMgIBN+IhEgeykDKH6nIgEgQigCCCIAakEBayAAbSIAIEIoAgQiQWwiRSAAIEVqIgAgASAAIAFIGyJYTg0OIF8oAjwhbCBfKAI4IXggXygCNCF6IF8pAyAhDyB/KAI8IU8gfygCOCFlIH8oAjQhgQEgfykDICEOIHsoAjwhcCB7KAI4IXcgeygCNCFhIBKnIkNBcHEiPSBDQQ9xIlQgQ0EDcSJtayJdaiEBIAUgEyASIAVCAXwiAiACIBJTG3wgEn0iDEJ8gyILfCEDIBJCfIMhBCBDQXxxIVogEEIBgyEJIBJCAYMhCCAF/RIipQL9DAIAAAAAAAAAAwAAAAAAAAD9zgEhqAIgpQL9DAAAAAAAAAAAAQAAAAAAAAD9zgEhpQIgXykDEKciggFBAXEhTSAQpyJrQQFxIVsgdiATQgBVcSFSIIIBQXBxIkBBAXIhTiBrQXBxIj9BAXIhTCBDQQNqQXxxIn4gQ2siVkF8cSJeIENqIT4gPUEBayJQQQR2QQFqIgBB/v///wFxIVcgAEEBcSFTQwAAgD8gELSRlSKVAv0TIasCIEWsIR4gQSB+QQF0QRBqbEECdCFZQQAgggFrIEBBf3NHIUlBACBrayA/QX9zRyFRA0AgHiAeIBF/IgbEIBF+fSICIAIgE38iAiATfn0hByBCKAIQIFlqIXECQCBDIH5ODQBBACFcIEMhACBWQQRPBEADQCBxIEMgXGpBAnRq/QwAAID/AACA/wAAgP8AAID//QsCACBcQQRqIlwgXkcNAAsgPiEAIFYgXkYNAQsDQCBxIABBAnRqQYCAgHw2AgAgAEEBaiIAIH5HDQALCyAHpyFpIAanIXQgAsQhFiACpyF2AkAgCKcEQCASQgBXDQEgZSAWIA6Bp2wgTyB0bGohRyB7KALAASB2IHdsIHAgdGxqIGEgaWxqaiJLID9BAXQiRmohSCB/KALAASFFQgAhAgNAIEUgRyCBASACpyJBbGpqIUpBACFi/QwAAAAAAAAAAAAAAAAAAAAAIqYCIacC/QwAAAAAAAAAAAAAAAAAAAAAIaoC/QwAAAAAAAAAAAAAAAAAAAAAIakCID9BAEoEQANAIKYCIEogYkEBdCIAaiJcLwEeQQJ0QfDUBGogXC8BHEECdEHw1ARqIFwvARpBAnRB8NQEaiBcLwEYQQJ0QfDUBGr9CQIA/VYCAAH9VgIAAv1WAgADIAAgS2oiAC8BHkECdEHw1ARqIAAvARxBAnRB8NQEaiAALwEaQQJ0QfDUBGogAC8BGEECdEHw1ARq/QkCAP1WAgAB/VYCAAL9VgIAA/3mAf3kASGmAiCnAiBcLwEWQQJ0QfDUBGogXC8BFEECdEHw1ARqIFwvARJBAnRB8NQEaiBcLwEQQQJ0QfDUBGr9CQIA/VYCAAH9VgIAAv1WAgADIAAvARZBAnRB8NQEaiAALwEUQQJ0QfDUBGogAC8BEkECdEHw1ARqIAAvARBBAnRB8NQEav0JAgD9VgIAAf1WAgAC/VYCAAP95gH95AEhpwIgqgIgXC8BDkECdEHw1ARqIFwvAQxBAnRB8NQEaiBcLwEKQQJ0QfDUBGogXC8BCEECdEHw1ARq/QkCAP1WAgAB/VYCAAL9VgIAAyAALwEOQQJ0QfDUBGogAC8BDEECdEHw1ARqIAAvAQpBAnRB8NQEaiAALwEIQQJ0QfDUBGr9CQIA/VYCAAH9VgIAAv1WAgAD/eYB/eQBIaoCIKkCIFwvAQZBAnRB8NQEaiBcLwEEQQJ0QfDUBGogXC8BAkECdEHw1ARqIFwvAQBBAnRB8NQEav0JAgD9VgIAAf1WAgAC/VYCAAMgAC8BBkECdEHw1ARqIAAvAQRBAnRB8NQEaiAALwECQQJ0QfDUBGogAC8BAEECdEHw1ARq/QkCAP1WAgAB/VYCAAL9VgIAA/3mAf3kASGpAiBiQRBqImIgP0gNAAsgqQIgpwL95AEgqgIgpgL95AH95AEhpgILIKYC/R8DIKYC/R8CIKYC/R8AIKYC/R8BkpKSIZICIEFBAnQgcWogPyBrSAR9IJICuyHFAiBbBH8gxQIgRiBKai8BAEECdEHw1ARqKgIAIEgvAQBBAnRB8NQEaioCAJS7oCHFAiBMBSA/CyEAIFEEQANAIMUCIEogAEEBdCJBai8BAEECdEHw1ARqKgIAIEEgS2ovAQBBAnRB8NQEaioCAJS7oCBKIEFBAmoiQWovAQBBAnRB8NQEaioCACBBIEtqLwEAQQJ0QfDUBGoqAgCUu6AhxQIgAEECaiIAIGtHDQALCyDFArYFIJICCzgCACACQgF8IgIgElINAAsMAQsgEkIAVw0AIHYgd2wgcCB0bGogYSBpbGohRSBlIBYgDoGnbCBPIHRsaiFBQgAhAgNAIGsggQEgcSACpyIAQQJ0aiB/KALAASBBIAAggQFsamogeygCwAEgRWoQ6gQgAkICfCICIBJTDQALCwJAID1BAEwNAEEAIVxBACFiIFBBD0cEQANAIHEgXEECdCIAaiJBIKsCIEH9AAAA/eYB/QsAACBBIKsCIEH9AAAQ/eYB/QsAECBBIKsCIEH9AAAg/eYB/QsAICBBIKsCIEH9AAAw/eYB/QsAMCBxIABBwAByaiIAIKsCIAD9AAAA/eYB/QsAACAAIKsCIAD9AAAQ/eYB/QsAECAAIKsCIAD9AAAg/eYB/QsAICAAIKsCIAD9AAAw/eYB/QsAMCBcQSBqIVwgYkECaiJiIFdHDQALCyBTRQ0AIHEgXEECdGoiACCrAiAA/QAAAP3mAf0LAAAgACCrAiAA/QAAEP3mAf0LABAgACCrAiAA/QAAIP3mAf0LACAgACCrAiAA/QAAMP3mAf0LADALAkAgPSBDTiJIDQBBACFcID0hACBUQQRPBEADQCBxID0gXGpBAnRqIgAgqwIgAP0AAgD95gH9CwIAIFxBBGoiXCBdRw0ACyABIQAgbUUNAQsDQCBxIABBAnRqIkEglQIgQSoCAJQ4AgAgAEEBaiIAIENHDQALCwJAIFJFDQAgB8QgBXwhBiAFIQIgDEIEWgRAIAb9EiGqAkIAIQIgpQIhpgIgqAIhpwIDQCACIAV8pyEAIKYCIKoC/dkBIqkC/RsAQQFxBEAgcSAAQQJ0akGAgIB8NgIACyCpAv0bAkEBcQRAIABBAnQgcWpBgICAfDYCBAsgpwIgqgL92QEiqQL9GwBBAXEEQCAAQQJ0IHFqQYCAgHw2AggLIKkC/RsCQQFxBEAgAEECdCBxakGAgIB8NgIMCyCmAv0MBAAAAAAAAAAEAAAAAAAAAP3OASGmAiCnAv0MBAAAAAAAAAAEAAAAAAAAAP3OASGnAiACQgR8IgIgC1INAAsgAyECIAsgDFENAQsDQCACIAZVBEAgcSACp0ECdGpBgICAfDYCAAsgAkIBfCICIBJTDQALCwJAIENBAEwEQEMAAID/IZICDAELQwAAgP8hkgJBACFiQQAhAEEAIUcgQ0EETwRAA0AgkgIgcSAAQQJ0IkFqKgIAIpMCIJICIJMCXhsikwIgcSBBQQRyaioCACKSAiCSAiCTAl0bIpMCIHEgQUEIcmoqAgAikgIgkgIgkwJdGyKTAiBxIEFBDHJqKgIAIpICIJICIJMCXRshkgIgAEEEaiEAIEdBBGoiRyBaRw0ACwsgbUUNAANAIJICIHEgAEECdGoqAgAikwIgkgIgkwJeGyGSAiAAQQFqIQAgYkEBaiJiIG1HDQALC0EAIVxEAAAAAAAAAAAhxQJEAAAAAAAAAAAhxgJEAAAAAAAAAAAhyAJEAAAAAAAAAAAhxwIgfkEASgRAA0BDAAAAACGUAgJAIHEgXEECdGoiRioCACKTAkMAAID/WwRAQwAAAAAhkwIMAQsgxQJBgPwBIJMCIJICkyKTAotDAACAd5RDAACACJRBgICAiAcgkwK8IkVBAXQiQUGAgIB4cSIAIABBgICAiAdNG0EBdkGAgIA8ar6SvCIAQQ12QYD4AXEgAEH/H3FqIEFBgICAeEsbIEVBEHZBgIACcXJBAXRB8NQsai8BAEECdEHw1ARqKgIAIpMCu6AhxQILIEYgkwI4AgAgRioCBCKTAkMAAID/XARAIMYCQYD8ASCTAiCSApMikwKLQwAAgHeUQwAAgAiUQYCAgIgHIJMCvCJFQQF0IkFBgICAeHEiACAAQYCAgIgHTRtBAXZBgICAPGq+krwiAEENdkGA+AFxIABB/x9xaiBBQYCAgHhLGyBFQRB2QYCAAnFyQQF0QfDULGovAQBBAnRB8NQEaioCACKUArugIcYCCyBGIJQCOAIEQwAAAAAhlAICQCBGKgIIIpMCQwAAgP9bBEBDAAAAACGTAgwBCyDIAkGA/AEgkwIgkgKTIpMCi0MAAIB3lEMAAIAIlEGAgICIByCTArwiRUEBdCJBQYCAgHhxIgAgAEGAgICIB00bQQF2QYCAgDxqvpK8IgBBDXZBgPgBcSAAQf8fcWogQUGAgIB4SxsgRUEQdkGAgAJxckEBdEHw1CxqLwEAQQJ0QfDUBGoqAgAikwK7oCHIAgsgRiCTAjgCCCBGKgIMIpMCQwAAgP9cBEAgxwJBgPwBIJMCIJICkyKTAotDAACAd5RDAACACJRBgICAiAcgkwK8IkVBAXQiQUGAgIB4cSIAIABBgICAiAdNG0EBdkGAgIA8ar6SvCIAQQ12QYD4AXEgAEH/H3FqIEFBgICAeEsbIEVBEHZBgIACcXJBAXRB8NQsai8BAEECdEHw1ARqKgIAIpQCu6AhxwILIEYglAI4AgwgXEEEaiJcIH5IDQALC0QAAAAAAADwPyDFAkQAAAAAAAAAAKAgxgKgIMgCoCDHAqCjtiGSAgJAID1BAEwNACCSAv0TIacCQQAhXEEAIWIgUEEPRwRAA0AgcSBcQQJ0IgBqIkEgpwIgQf0AAAD95gH9CwAAIEEgpwIgQf0AABD95gH9CwAQIEEgpwIgQf0AACD95gH9CwAgIEEgpwIgQf0AADD95gH9CwAwIHEgAEHAAHJqIgAgpwIgAP0AAAD95gH9CwAAIAAgpwIgAP0AABD95gH9CwAQIAAgpwIgAP0AACD95gH9CwAgIAAgpwIgAP0AADD95gH9CwAwIFxBIGohXCBiQQJqImIgV0cNAAsLIFNFDQAgcSBcQQJ0aiIAIKcCIAD9AAAA/eYB/QsAACAAIKcCIAD9AAAQ/eYB/QsAECAAIKcCIAD9AAAg/eYB/QsAICAAIKcCIAD9AAAw/eYB/QsAMAsCQCBIDQAgPSEAIFRBBE8EQCCSAv0TIacCQQAhAANAIHEgACA9akECdGoiQSBB/QACACCnAv3mAf0LAgAgAEEEaiIAIF1HDQALIAEhACBtRQ0BCwNAIHEgAEECdGoiQSBBKgIAIJIClDgCACAAQQFqIgAgQ0cNAAsLIEIoAhAgWWogfkECdGohXAJAIBJCAFcNAEIAIQIgEkIEWgRAA0AgXCACpyIAQQF0av0MAH4AAAB+AAAAfgAAAH4AACBxIABBAnRq/QACACKpAv3gAf0MAACAdwAAgHcAAIB3AACAd/3mAf0MAACACAAAgAgAAIAIAACACP3mASCpAkEB/asBIqYC/QwAAAD/AAAA/wAAAP8AAAD//U79DAAAAHEAAABxAAAAcQAAAHH9uQFBAf2tAf0MAACABwAAgAcAAIAHAACAB/2uAf3kASKnAkEN/a0B/QwAfAAAAHwAAAB8AAAAfAAA/U4gpwL9DP8PAAD/DwAA/w8AAP8PAAD9Tv2uASCmAv0MAAAA/wAAAP8AAAD/AAAA//08/VIgqQJBEP2tAf0MAIAAAACAAAAAgAAAAIAAAP1O/VAgqQL9DQABBAUICQwNAAEAAQABAAH9WwEAACACQgR8IgIgBFINAAsgBCICIBJRDQELA0AgXCACpyIAQQF0akGA/AEgcSAAQQJ0aioCACKSAotDAACAd5RDAACACJRBgICAiAcgkgK8IkVBAXQiQUGAgIB4cSIAIABBgICAiAdNG0EBdkGAgIA8ar6SvCIAQQ12QYD4AXEgAEH/H3FqIEFBgICAeEsbIEVBEHZBgIACcXI7AQAgAkIBfCICIBJSDQALCwJAIAmnBEAgEEIAVw0BIHYgeWwgYyB0bGogaSB1bGohSiB4IBYgD4GnbCBsIHRsaiFLIFwgQEEBdCJHaiFGIF8oAsABIUggRCgCwAEhRUIAIQIDQCBIIEsgeiACpyJBbGpqIXZBACFi/QwAAAAAAAAAAAAAAAAAAAAAIqYCIacC/QwAAAAAAAAAAAAAAAAAAAAAIaoC/QwAAAAAAAAAAAAAAAAAAAAAIakCIEBBAEoEQANAIKYCIHYgYkEBdCIAaiJpLwEeQQJ0QfDUBGogaS8BHEECdEHw1ARqIGkvARpBAnRB8NQEaiBpLwEYQQJ0QfDUBGr9CQIA/VYCAAH9VgIAAv1WAgADIAAgXGoiAC8BHkECdEHw1ARqIAAvARxBAnRB8NQEaiAALwEaQQJ0QfDUBGogAC8BGEECdEHw1ARq/QkCAP1WAgAB/VYCAAL9VgIAA/3mAf3kASGmAiCnAiBpLwEWQQJ0QfDUBGogaS8BFEECdEHw1ARqIGkvARJBAnRB8NQEaiBpLwEQQQJ0QfDUBGr9CQIA/VYCAAH9VgIAAv1WAgADIAAvARZBAnRB8NQEaiAALwEUQQJ0QfDUBGogAC8BEkECdEHw1ARqIAAvARBBAnRB8NQEav0JAgD9VgIAAf1WAgAC/VYCAAP95gH95AEhpwIgqgIgaS8BDkECdEHw1ARqIGkvAQxBAnRB8NQEaiBpLwEKQQJ0QfDUBGogaS8BCEECdEHw1ARq/QkCAP1WAgAB/VYCAAL9VgIAAyAALwEOQQJ0QfDUBGogAC8BDEECdEHw1ARqIAAvAQpBAnRB8NQEaiAALwEIQQJ0QfDUBGr9CQIA/VYCAAH9VgIAAv1WAgAD/eYB/eQBIaoCIKkCIGkvAQZBAnRB8NQEaiBpLwEEQQJ0QfDUBGogaS8BAkECdEHw1ARqIGkvAQBBAnRB8NQEav0JAgD9VgIAAf1WAgAC/VYCAAMgAC8BBkECdEHw1ARqIAAvAQRBAnRB8NQEaiAALwECQQJ0QfDUBGogAC8BAEECdEHw1ARq/QkCAP1WAgAB/VYCAAL9VgIAA/3mAf3kASGpAiBiQRBqImIgQEgNAAsgqQIgpwL95AEgqgIgpgL95AH95AEhpgILIKYC/R8DIKYC/R8CIKYC/R8AIKYC/R8BkpKSIZICIEFBAnQgSmogRWogQCCCAUgEfSCSArshxQIgTQR/IMUCIEcgdmovAQBBAnRB8NQEaioCACBGLwEAQQJ0QfDUBGoqAgCUu6AhxQIgTgUgQAshACBJBEADQCDFAiB2IABBAXQiQWovAQBBAnRB8NQEaioCACBBIFxqLwEAQQJ0QfDUBGoqAgCUu6AgdiBBQQJqIkFqLwEAQQJ0QfDUBGoqAgAgQSBcai8BAEECdEHw1ARqKgIAlLugIcUCIABBAmoiACCCAUcNAAsLIMUCtgUgkgILOAIAIAJCAXwiAiAQUg0ACwwBCyAQQgBXDQAgdiB5bCBjIHRsaiBpIHVsaiFFIHggFiAPgadsIGwgdGxqIUFCACECA0AgggEgeiBEKALAASBFIAKnIgBBAnRqaiBfKALAASBBIAAgemxqaiBcEOoEIAJCAnwiAiAQUw0ACwsgWCAeQgF8Ih6nRw0ACwwOCyBgQf4gNgIIIGBBiuIANgIEIGBBxyY2AgBBqMICKAIAIgBBpeMAIGAQMAw2CyBgQd05NgIoIGBBx+AANgIkIGBBxyY2AiBBqMICKAIAIgBBpeMAIGBBIGoQMAw1CyBgQfI6NgIYIGBBxuAANgIUIGBBxyY2AhBBqMICKAIAIgBBpeMAIGBBEGoQMAw0CyBgQaQ9NgI4IGBBxeAANgI0IGBBxyY2AjBBqMICKAIAIgBBpeMAIGBBMGoQMAwzCyBgQYjQADYCSCBgQcTgADYCRCBgQccmNgJAQajCAigCACIAQaXjACBgQUBrEDAMMgsgYEHHMjYCWCBgQb3gADYCVCBgQccmNgJQQajCAigCACIAQaXjACBgQdAAahAwDDELIGBB3DI2AmggYEG84AA2AmQgYEHHJjYCYEGowgIoAgAiAEGl4wAgYEHgAGoQMAwwCyBgQZrRADYCeCBgQbngADYCdCBgQccmNgJwQajCAigCACIAQaXjACBgQfAAahAwDC8LIGBB0tEANgKIASBgQbjgADYChAEgYEHHJjYCgAFBqMICKAIAIgBBpeMAIGBBgAFqEDAMLgsgYEG20QA2ApgBIGBBt+AANgKUASBgQccmNgKQAUGowgIoAgAiAEGl4wAgYEGQAWoQMAwtCyBgQZzAADYCqAEgYEG14AA2AqQBIGBBxyY2AqABQajCAigCACIAQaXjACBgQaABahAwDCwLIGBBji42ArgBIGBBtOAANgK0ASBgQccmNgKwAUGowgIoAgAiAEGl4wAgYEGwAWoQMAwrCyBgQeYyNgLIASBgQbPgADYCxAEgYEHHJjYCwAFBqMICKAIAIgBBpeMAIGBBwAFqEDAMKgsgeykDECIWIEQpAxBSDQwgeykDGCIPIEQpAxhSDQsgfykDGCIRIA99IgJCAFMNCiB7KAIwQQRHDQkgfygCMEEERw0IIF8oAjBBBEcNByB/KQMQIBZSDQYgXykDGCAWUg0FIEQoAjBBBEcNBCBEKAI0IndBA00NAyB3IEQoAjgiYUsNAiBhIEQoAjwiV0sNAQJAIEIoAgAOAwEAAQALIHspAyAgD34iDiB7KQMofqciPSBCKAIIIgBqQQFrIABtIgAgQigCBCIBbCI+IAAgPmoiACA9IAAgPUgbIgBODQAgXygCPCFTIF8oAjghWSBfKAI0IVggXykDICEJIH8oAjwhWiB/KAI4IU0gfygCNCFbIH8pAyAhCCB7KAI8IVIgeygCOCFOIHsoAjQhTCACQgF8IQYgFqciZUEDcSFUIBGnIj9BA2pBfHEiTyA/ayJdQXxxIlYgP2ohPUMAAIA/IBa0kZUilQL9EyGoAiAArCEFID6sIQogT6whDCABIE9BEGpsQQJ0IUkgXUEESSFRIGVBcHEiPkF/cyBlakEDSSFKA0AgCiAKIA5/IgPEIA5+fSICIAIgD38iBCAPfn0hAiBCKAIQIElqIWMCQCA/IE9ODQBBACFcID8hACBRRQRAA0AgYyA/IFxqQQJ0av0MAACA/wAAgP8AAID/AACA//0LAgAgXEEEaiJcIFZHDQALID0hACBWIF1GDQELA0AgYyAAQQJ0akGAgIB8NgIAIABBAWoiACBPRw0ACwsgAqchRiADpyFQIATEIQsgBKchSCAGIALEfCARIHYbIgNCAFciRUUEQCBNIAsgCIGnbCBQIFpsaiFBIHsoAsABIEggTmwgUCBSbGogRiBMbGpqIV4gfygCwAEhQ0IAIQIDQCBDIEEgWyACpyJAbGpqIUtBACEA/QwAAAAAAAAAAAAAAAAAAAAAIqYCIacC/QwAAAAAAAAAAAAAAAAAAAAAIaoC/QwAAAAAAAAAAAAAAAAAAAAAIakCIEBBAnQh/wEgPkEASgRAA0AgpgIgSyAAQQJ0IgFqIkf9AAAwIAEgXmoiAf0AADD95gH95AEhpgIgpwIgR/0AACAgAf0AACD95gH95AEhpwIgqgIgR/0AABAgAf0AABD95gH95AEhqgIgqQIgR/0AAAAgAf0AAAD95gH95AEhqQIgAEEQaiIAID5IDQALIKkCIKcC/eQBIKoCIKYC/eQB/eQBIaYCCyCmAv0fAyCmAv0fAiCmAv0fACCmAv0fAZKSkiGSAgJAID4gZU4NAEEAIVwgPiEAIFQEQANAIEsgAEECdCIBaioCACABIF5qKgIAlCCSApIhkgIgAEEBaiEAIFxBAWoiXCBURw0ACwsgSg0AA0AgSyAAQQJ0IkdBDGoiAWoqAgAgASBeaioCAJQgSyBHQQhqIgFqKgIAIAEgXmoqAgCUIEsgR0EEaiIBaioCACABIF5qKgIAlCBHIEtqKgIAIEcgXmoqAgCUIJICkpKSkiGSAiAAQQRqIgAgZUcNAAsLIP8BIGNqIJICOAIAIAJCAXwiAiADUg0ACwsCQCADpyJsQXBxIgFBAEwiSw0AIAFBAWsiQEEEdkEBaiIAQQFxIYACQQAhXCBAQQ9HBEAgAEH+////AXEhQEEAIUcDQCBjIFxBAnQiAGoiQSCoAiBB/QAAAP3mAf0LAAAgQSCoAiBB/QAAEP3mAf0LABAgQSCoAiBB/QAAIP3mAf0LACAgQSCoAiBB/QAAMP3mAf0LADAgYyAAQcAAcmoiACCoAiAA/QAAAP3mAf0LAAAgACCoAiAA/QAAEP3mAf0LABAgACCoAiAA/QAAIP3mAf0LACAgACCoAiAA/QAAMP3mAf0LADAgXEEgaiFcIEdBAmoiRyBARw0ACwsggAJFDQAgYyBcQQJ0aiIAIKgCIAD9AAAA/eYB/QsAACAAIKgCIAD9AAAQ/eYB/QsAECAAIKgCIAD9AAAg/eYB/QsAICAAIKgCIAD9AAAw/eYB/QsAMAsCQCABIGxOIl4NACABIQAgbEEPcSJAQQRPBEAgACBAIGxBA3EiQWsiQ2ohAEEAIVwDQCBjIAEgXGpBAnRqIkAgqAIgQP0AAgD95gH9CwIAIFxBBGoiXCBDRw0ACyBBRQ0BCwNAIGMgAEECdGoiQCCVAiBAKgIAlDgCACAAQQFqIgAgbEcNAAsLAkAgAyARWQ0AIBEgAyICfSIHQgRaBEAgAiAHQnyDIgR8IQJCACEUA0AgYyADIBR8p0ECdGr9DAAAgP8AAID/AACA/wAAgP/9CwIAIBRCBHwiFCAEUg0ACyAEIAdRDQELA0AgYyACp0ECdGpBgICAfDYCACACQgF8IgIgEVINAAsLAkAgbEEATARAQwAAgP8hkgIMAQtDAACA/yGSAkEAIUdBACEAIGxBBE8EQCBsQXxxIUBBACFcA0AgkgIgYyAAQQJ0IkNqKgIAIpMCIJICIJMCXhsikwIgYyBDQQRyaioCACKSAiCSAiCTAl0bIpMCIGMgQ0EIcmoqAgAikgIgkgIgkwJdGyKTAiBjIENBDHJqKgIAIpICIJICIJMCXRshkgIgAEEEaiEAIFxBBGoiXCBARw0ACwsgbEEDcSJARQ0AA0AgkgIgYyAAQQJ0aioCACKTAiCSAiCTAl4bIZICIABBAWohACBHQQFqIkcgQEcNAAsLRAAAAAAAAAAAIcUCAkAgT0EATARARAAAAAAAAAAAIcYCRAAAAAAAAAAAIcgCRAAAAAAAAAAAIccCDAELRAAAAAAAAAAAIcYCRAAAAAAAAAAAIcgCRAAAAAAAAAAAIccCIEUNACAMIAMgAyAMVRshBEIAIQIDQEMAAAAAIZQCIGMgAqdBAnRqIgAqAgAikwJDAACA/1wEQCDFAiCTAiCSApMQRSKUArugIcUCCyAAIJQCOAIAAkAgAyACQgGEVw0AQwAAAAAhlAIgACoCBCKTAkMAAID/XARAIMYCIJMCIJICkxBFIpQCu6AhxgILIAAglAI4AgQgAyACQgKEVw0AQwAAAAAhlAIgACoCCCKTAkMAAID/XARAIMgCIJMCIJICkxBFIpQCu6AhyAILIAAglAI4AgggAyACQgOEVw0AQwAAAAAhlAIgACoCDCKTAkMAAID/XARAIMcCIJMCIJICkxBFIpQCu6AhxwILIAAglAI4AgwLIAJCBHwiAiAEUw0ACwtEAAAAAAAA8D8gxQJEAAAAAAAAAACgIMYCoCDIAqAgxwKgo7YhkgICQCABQQBMDQAgAUEBayJAQQR2QQFqIgBBAXEhgQIgkgL9EyGlAkEAIVwgQEEPRwRAIABB/v///wFxIUBBACFHA0AgYyBcQQJ0IgBqIkEgpQIgQf0AAAD95gH9CwAAIEEgpQIgQf0AABD95gH9CwAQIEEgpQIgQf0AACD95gH9CwAgIEEgpQIgQf0AADD95gH9CwAwIGMgAEHAAHJqIgAgpQIgAP0AAAD95gH9CwAAIAAgpQIgAP0AABD95gH9CwAQIAAgpQIgAP0AACD95gH9CwAgIAAgpQIgAP0AADD95gH9CwAwIFxBIGohXCBHQQJqIkcgQEcNAAsLIIECRQ0AIGMgXEECdGoiACClAiAA/QAAAP3mAf0LAAAgACClAiAA/QAAEP3mAf0LABAgACClAiAA/QAAIP3mAf0LACAgACClAiAA/QAAMP3mAf0LADALAkAgXg0AIAEhACBsQQ9xIkBBBE8EQCAAIEAgbEEDcSJBayJDaiEAIJIC/RMhpQJBACFcA0AgYyABIFxqQQJ0aiJAIED9AAIAIKUC/eYB/QsCACBcQQRqIlwgQ0cNAAsgQUUNAQsDQCBjIABBAnRqIkAgQCoCACCSApQ4AgAgAEEBaiIAIGxHDQALCyAWQgBVBEAgSCBhbCBQIFdsaiBGIHdsaiFHIFkgCyAJgadsIFAgU2xqIUYgbEEDcSFQIAFBf3MgbGohSCBfKALAASFFIEQoAsABIUFCACECA0AgRSBGIFggAqciQGxqaiF4QQAhXP0MAAAAAAAAAAAAAAAAAAAAACKmAiGnAv0MAAAAAAAAAAAAAAAAAAAAACGqAv0MAAAAAAAAAAAAAAAAAAAAACGpAiBLRQRAA0AgpgIgeCBcQQJ0IgBqIkP9AAAwIAAgY2oiAP0AADD95gH95AEhpgIgpwIgQ/0AACAgAP0AACD95gH95AEhpwIgqgIgQ/0AABAgAP0AABD95gH95AEhqgIgqQIgQ/0AAAAgAP0AAAD95gH95AEhqQIgXEEQaiJcIAFIDQALIKkCIKcC/eQBIKoCIKYC/eQB/eQBIaYCCyBAQQJ0IEdqIUMgpgL9HwMgpgL9HwIgpgL9HwAgpgL9HwGSkpIhkgICQCBeDQBBACFcIAEhACBQBEADQCB4IABBAnQiQGoqAgAgQCBjaioCAJQgkgKSIZICIABBAWohACBcQQFqIlwgUEcNAAsLIEhBA0kNAANAIHggAEECdCJwQQxqIkBqKgIAIEAgY2oqAgCUIHggcEEIaiJAaioCACBAIGNqKgIAlCB4IHBBBGoiQGoqAgAgQCBjaioCAJQgcCB4aioCACBjIHBqKgIAlCCSApKSkpIhkgIgAEEEaiIAIGxHDQALCyBBIENqIJICOAIAIAJCAXwiAiAWUg0ACwsgCkIBfCIKIAVSDQALCyBgQZADaiQADAwLIGBB3Tk2AugBIGBBid8ANgLkASBgQccmNgLgAUGowgIoAgAiAEGl4wAgYEHgAWoQMAwnCyBgQfI6NgLYASBgQYjfADYC1AEgYEHHJjYC0AFBqMICKAIAIgBBpeMAIGBB0AFqEDAMJgsgYEGkPTYC+AEgYEGH3wA2AvQBIGBBxyY2AvABQajCAigCACIAQaXjACBgQfABahAwDCULIGBBiNAANgKIAiBgQYbfADYChAIgYEHHJjYCgAJBqMICKAIAIgBBpeMAIGBBgAJqEDAMJAsgYEHHMjYCmAIgYEH/3gA2ApQCIGBBxyY2ApACQajCAigCACIAQaXjACBgQZACahAwDCMLIGBB3DI2AqgCIGBB/t4ANgKkAiBgQccmNgKgAkGowgIoAgAiAEGl4wAgYEGgAmoQMAwiCyBgQcbPADYCuAIgYEH73gA2ArQCIGBBxyY2ArACQajCAigCACIAQaXjACBgQbACahAwDCELIGBB8s8ANgLIAiBgQfreADYCxAIgYEHHJjYCwAJBqMICKAIAIgBBpeMAIGBBwAJqEDAMIAsgYEHczwA2AtgCIGBB+d4ANgLUAiBgQccmNgLQAkGowgIoAgAiAEGl4wAgYEHQAmoQMAwfCyBgQZzAADYC6AIgYEH33gA2AuQCIGBBxyY2AuACQajCAigCACIAQaXjACBgQeACahAwDB4LIGBBji42AvgCIGBB9t4ANgL0AiBgQccmNgLwAkGowgIoAgAiAEGl4wAgYEHwAmoQMAwdCyBgQeYyNgKIAyBgQfXeADYChAMgYEHHJjYCgANBqMICKAIAIgBBpeMAIGBBgANqEDAMHAsMEwsgASgCjAEhayABKAKQASFtIAEoApQBIUggASgCmAEhdSABKAKcASFFIwBB0AJrIl8kAAJAAkAgbSgCACI9QQFHBEAgPQ0BIF9B/iA2AsgCIF9BpeMANgLEAiBfQccmNgLAAkGowgIoAgAiAEGl4wAgX0HAAmoQMAwdCyBrKQMQIgkgASkDEFEEQCBrKQMYIgggASkDGFEEQCBrKQMgIgIgASkDIFEEQCBrKAIwQQJGBEAgbSgCMEECRgRAIEgoAjBBBEYEQCB1KAIwQQJGBEAgRSgCMEEERgRAIAkgbSkDEFEEQCBtKQMYIgcgSCkDEFEEQCBIKQMYQgFRBEAgByB1KQMQUQRAIAkgdSkDGFEEQCAJIEUpAxBRBEAgRSkDGEIBUQRAIAEoAjBBBEYEQCABKAI0InhBA0sEQCABKAI4Ik8geE8EQCABKAI8Il0gT08EQAJAAkAgACgCAA4DAQABAAsgAiAIfiIGIGspAyh+pyI/IAAoAggiPWpBAWsgPW0iPSAAKAIEIj5sIkEgPSBBaiI9ID8gPSA/SBsiRE4NACB1KAI8IVYgdSgCOCFeIHUoAjQhUCBtKAI8IVcgbSgCOCFTIG0oAjQhWSBrKAI8IVggaygCOCFaIGsoAjQhTSAAKAIQID4gB6cidEEBdEEQamxBAnRqIoIBIHRBAnQiQ2oiaSB0QXBxIkJBAXQiW2ohUiAHQnyDIQMgCacifkEDcSFlIH5BfHEhPyB0QQFxIU4gdEF4cSE+IHRBA3EhcCB0QXxxIT0gfkEBcSFMIHRBAWshdyBCQQFyIUkgfkFwcSJAQQFyIVEgRSgCwAEieSB+QQJ0IgBqIUogASgCwAEiYSAAaiFLIESsIQUgQawhDUEAIH5rIEBBf3NHIUcgggEgSCgCwAEieiBDakkgaSB6S3EgdEEESXIhRgNAIA0gDSAGfyIExCAGfn0iAiACIAh/IgIgCH59pyFUIASnIYEBIAKnIXYgB0IAVyJIRQRAIFMgdmwgVyCBAWxqIUUgaygCwAEgWiB2bCBYIIEBbGogTSBUbGpqImwgQEEBdCJBaiFEIG0oAsABIUNCACECA0AgQyBFIFkgAqciAWxqaiFjQQAhYv0MAAAAAAAAAAAAAAAAAAAAACKmAiGnAv0MAAAAAAAAAAAAAAAAAAAAACGpAv0MAAAAAAAAAAAAAAAAAAAAACGlAiBAQQBKBEADQCCmAiBjIGJBAXQiAGoiXC8BHkECdEHw1ARqIFwvARxBAnRB8NQEaiBcLwEaQQJ0QfDUBGogXC8BGEECdEHw1ARq/QkCAP1WAgAB/VYCAAL9VgIAAyAAIGxqIgAvAR5BAnRB8NQEaiAALwEcQQJ0QfDUBGogAC8BGkECdEHw1ARqIAAvARhBAnRB8NQEav0JAgD9VgIAAf1WAgAC/VYCAAP95gH95AEhpgIgpwIgXC8BFkECdEHw1ARqIFwvARRBAnRB8NQEaiBcLwESQQJ0QfDUBGogXC8BEEECdEHw1ARq/QkCAP1WAgAB/VYCAAL9VgIAAyAALwEWQQJ0QfDUBGogAC8BFEECdEHw1ARqIAAvARJBAnRB8NQEaiAALwEQQQJ0QfDUBGr9CQIA/VYCAAH9VgIAAv1WAgAD/eYB/eQBIacCIKkCIFwvAQ5BAnRB8NQEaiBcLwEMQQJ0QfDUBGogXC8BCkECdEHw1ARqIFwvAQhBAnRB8NQEav0JAgD9VgIAAf1WAgAC/VYCAAMgAC8BDkECdEHw1ARqIAAvAQxBAnRB8NQEaiAALwEKQQJ0QfDUBGogAC8BCEECdEHw1ARq/QkCAP1WAgAB/VYCAAL9VgIAA/3mAf3kASGpAiClAiBcLwEGQQJ0QfDUBGogXC8BBEECdEHw1ARqIFwvAQJBAnRB8NQEaiBcLwEAQQJ0QfDUBGr9CQIA/VYCAAH9VgIAAv1WAgADIAAvAQZBAnRB8NQEaiAALwEEQQJ0QfDUBGogAC8BAkECdEHw1ARqIAAvAQBBAnRB8NQEav0JAgD9VgIAAf1WAgAC/VYCAAP95gH95AEhpQIgYkEQaiJiIEBIDQALIKUCIKcC/eQBIKkCIKYC/eQB/eQBIaYCCyCmAv0fAyCmAv0fAiCmAv0fACCmAv0fAZKSkiGSAiABQQJ0IIIBaiBAIH5IBH0gkgK7IcUCIEwEfyDFAiBBIGNqLwEAQQJ0QfDUBGoqAgAgRC8BAEECdEHw1ARqKgIAlLugIcUCIFEFIEALIQAgRwRAA0AgxQIgYyAAQQF0IgFqLwEAQQJ0QfDUBGoqAgAgASBsai8BAEECdEHw1ARqKgIAlLugIGMgAUECaiIBai8BAEECdEHw1ARqKgIAIAEgbGovAQBBAnRB8NQEaioCAJS7oCHFAiAAQQJqIgAgfkcNAAsLIMUCtgUgkgILOAIAIAJCAXwiAiAHUg0ACwsCQCB0QQBMIkENAEEAIWJBACEAIEZFBEADQCCCASAAQQJ0IkNqIgEgAf0AAgAgQyB6av0AAgD95AH9CwIAIABBBGoiACA9Rw0ACyA9IgAgdEYNAQsgdyAAayGCAiBwBEADQCCCASAAQQJ0IkNqIgEgASoCACBDIHpqKgIAkjgCACAAQQFqIQAgYkEBaiJiIHBHDQALCyCCAkEDSQ0AA0AgggEgAEECdCJEaiIBIAEqAgAgRCB6aioCAJI4AgAgggEgREEEaiJDaiIBIAEqAgAgQyB6aioCAJI4AgAgggEgREEIaiJDaiIBIAEqAgAgQyB6aioCAJI4AgAgggEgREEMaiJDaiIBIAEqAgAgQyB6aioCAJI4AgAgAEEEaiIAIHRHDQALCwJAIEgNAEIAIQIgB0IEWgRAA0AgaSACpyIAQQF0av0MAH4AAAB+AAAAfgAAAH4AACCCASAAQQJ0av0AAgAipgL94AH9DAAAgHcAAIB3AACAdwAAgHf95gH9DAAAgAgAAIAIAACACAAAgAj95gEgpgJBAf2rASKoAv0MAAAA/wAAAP8AAAD/AAAA//1O/QwAAABxAAAAcQAAAHEAAABx/bkBQQH9rQH9DAAAgAcAAIAHAACABwAAgAf9rgH95AEipQJBDf2tAf0MAHwAAAB8AAAAfAAAAHwAAP1OIKUC/Qz/DwAA/w8AAP8PAAD/DwAA/U79rgEgqAL9DAAAAP8AAAD/AAAA/wAAAP/9PP1SIKYCQRD9rQH9DACAAAAAgAAAAIAAAACAAAD9Tv1QIKYC/Q0AAQQFCAkMDQABAAEAAQAB/VsBAAAgAkIEfCICIANSDQALIAMiAiAHUQ0BCwNAIGkgAqciAEEBdGpBgPwBIIIBIABBAnRqKgIAIpICi0MAAIB3lEMAAIAIlEGAgICIByCSArwiQ0EBdCIBQYCAgHhxIgAgAEGAgICIB00bQQF2QYCAgDxqvpK8IgBBDXZBgPgBcSAAQf8fcWogAUGAgIB4SxsgQ0EQdkGAgAJxcjsBACACQgF8IgIgB1INAAsLAkAgQQ0AQQAhACB0QQhPBEADQCBpIABBAXRqIgEgAf0AAQAipQIgpgL9DQgJCgsMDQ4PAAEAAQABAAH9qQEiqAL9GwNBAXRB8NQUaiCoAv0bAkEBdEHw1BRqIKgC/RsBQQF0QfDUFGogqAL9GwBBAXRB8NQUaiClAv2pASKmAv0bA0EBdEHw1BRqIKYC/RsCQQF0QfDUFGogpgL9GwFBAXRB8NQUaiCmAv0bAEEBdEHw1BRq/QgBAP1VAQAB/VUBAAL9VQEAA/1VAQAE/VUBAAX9VQEABv1VAQAH/QsBACAAQQhqIgAgPkcNAAsgPiIAIHRGDQELA0AgaSAAQQF0aiIBIAEvAQBBAXRB8NQUai8BADsBACAAQQFqIgAgdEcNAAsLIFQgeGwiSCBPIHZsIkUgXSCBAWwiQWpqIVQgCUIAVQRAIF4gdmwgViCBAWxqIUQgdSgCwAEhQ0IAIQIDQCBDIEQgUCACpyIBbGpqIWxBACFi/QwAAAAAAAAAAAAAAAAAAAAAIqYCIacC/QwAAAAAAAAAAAAAAAAAAAAAIakC/QwAAAAAAAAAAAAAAAAAAAAAIaUCIEJBAEoEQANAIKYCIGwgYkEBdCIAaiJjLwEeQQJ0QfDUBGogYy8BHEECdEHw1ARqIGMvARpBAnRB8NQEaiBjLwEYQQJ0QfDUBGr9CQIA/VYCAAH9VgIAAv1WAgADIAAgaWoiAC8BHkECdEHw1ARqIAAvARxBAnRB8NQEaiAALwEaQQJ0QfDUBGogAC8BGEECdEHw1ARq/QkCAP1WAgAB/VYCAAL9VgIAA/3mAf3kASGmAiCnAiBjLwEWQQJ0QfDUBGogYy8BFEECdEHw1ARqIGMvARJBAnRB8NQEaiBjLwEQQQJ0QfDUBGr9CQIA/VYCAAH9VgIAAv1WAgADIAAvARZBAnRB8NQEaiAALwEUQQJ0QfDUBGogAC8BEkECdEHw1ARqIAAvARBBAnRB8NQEav0JAgD9VgIAAf1WAgAC/VYCAAP95gH95AEhpwIgqQIgYy8BDkECdEHw1ARqIGMvAQxBAnRB8NQEaiBjLwEKQQJ0QfDUBGogYy8BCEECdEHw1ARq/QkCAP1WAgAB/VYCAAL9VgIAAyAALwEOQQJ0QfDUBGogAC8BDEECdEHw1ARqIAAvAQpBAnRB8NQEaiAALwEIQQJ0QfDUBGr9CQIA/VYCAAH9VgIAAv1WAgAD/eYB/eQBIakCIKUCIGMvAQZBAnRB8NQEaiBjLwEEQQJ0QfDUBGogYy8BAkECdEHw1ARqIGMvAQBBAnRB8NQEav0JAgD9VgIAAf1WAgAC/VYCAAMgAC8BBkECdEHw1ARqIAAvAQRBAnRB8NQEaiAALwECQQJ0QfDUBGogAC8BAEECdEHw1ARq/QkCAP1WAgAB/VYCAAL9VgIAA/3mAf3kASGlAiBiQRBqImIgQkgNAAsgpQIgpwL95AEgqQIgpgL95AH95AEhpgILIKYC/R8DIKYC/R8CIKYC/R8AIKYC/R8BkpKSIZICIAFBAnQgVGogYWogQiB0SAR9IJICuyHFAiBOBH8gxQIgWyBsai8BAEECdEHw1ARqKgIAIFIvAQBBAnRB8NQEaioCAJS7oCHFAiBJBSBCCyEAIEIgd0cEQANAIMUCIGwgAEEBdCIBai8BAEECdEHw1ARqKgIAIAEgaWovAQBBAnRB8NQEaioCAJS7oCBsIAFBAmoiAWovAQBBAnRB8NQEaioCACABIGlqLwEAQQJ0QfDUBGoqAgCUu6AhxQIgAEECaiIAIHRHDQALCyDFArYFIJICCzgCACACQgF8IgIgCVINAAsLAkAgfkEATA0AIFQgYWohVEEAIWJBACEAAkAgfkEISQ0AIHkgSyBBIEhqIEVqakkgSiBUS3ENAANAIFQgAEECdCJDaiIBIAH9AAIAIEMgeWr9AAIA/eQB/QsCACAAQQRqIgAgP0cNAAsgPyIAIH5GDQELIABBf3MgfmohgwIgZQRAA0AgVCAAQQJ0IkNqIgEgASoCACBDIHlqKgIAkjgCACAAQQFqIQAgYkEBaiJiIGVHDQALCyCDAkEDSQ0AA0AgVCAAQQJ0IkRqIgEgASoCACBEIHlqKgIAkjgCACBUIERBBGoiQ2oiASABKgIAIEMgeWoqAgCSOAIAIFQgREEIaiJDaiIBIAEqAgAgQyB5aioCAJI4AgAgVCBEQQxqIkNqIgEgASoCACBDIHlqKgIAkjgCACAAQQRqIgAgfkcNAAsLIA1CAXwiDSAFUg0ACwsgX0HQAmokAAwUCyBfQd05NgIoIF9ByOIANgIkIF9BxyY2AiBBqMICKAIAIgBBpeMAIF9BIGoQMAwuCyBfQfI6NgIYIF9Bx+IANgIUIF9BxyY2AhBBqMICKAIAIgBBpeMAIF9BEGoQMAwtCyBfQaQ9NgI4IF9BxuIANgI0IF9BxyY2AjBBqMICKAIAIgBBpeMAIF9BMGoQMAwsCyBfQYjQADYCSCBfQcXiADYCRCBfQccmNgJAQajCAigCACIAQaXjACBfQUBrEDAMKwsgX0HbPjYCWCBfQcLiADYCVCBfQccmNgJQQajCAigCACIAQaXjACBfQdAAahAwDCoLIF9B+TI2AmggX0HB4gA2AmQgX0HHJjYCYEGowgIoAgAiAEGl4wAgX0HgAGoQMAwpCyBfQdEyNgJ4IF9BwOIANgJ0IF9BxyY2AnBBqMICKAIAIgBBpeMAIF9B8ABqEDAMKAsgX0HKLjYCiAEgX0G/4gA2AoQBIF9BxyY2AoABQajCAigCACIAQaXjACBfQYABahAwDCcLIF9B5j42ApgBIF9BveIANgKUASBfQccmNgKQAUGowgIoAgAiAEGl4wAgX0GQAWoQMAwmCyBfQb8uNgKoASBfQbziADYCpAEgX0HHJjYCoAFBqMICKAIAIgBBpeMAIF9BoAFqEDAMJQsgX0GEMzYCuAEgX0G64gA2ArQBIF9BxyY2ArABQajCAigCACIAQaXjACBfQbABahAwDCQLIF9BndAANgLIASBfQbjiADYCxAEgX0HHJjYCwAFBqMICKAIAIgBBpeMAIF9BwAFqEDAMIwsgX0Gl0gA2AtgBIF9Bt+IANgLUASBfQccmNgLQAUGowgIoAgAiAEGl4wAgX0HQAWoQMAwiCyBfQcrQADYC6AEgX0G24gA2AuQBIF9BxyY2AuABQajCAigCACIAQaXjACBfQeABahAwDCELIF9B3tIANgL4ASBfQbXiADYC9AEgX0HHJjYC8AFBqMICKAIAIgBBpeMAIF9B8AFqEDAMIAsgX0GJ0gA2AogCIF9BtOIANgKEAiBfQccmNgKAAkGowgIoAgAiAEGl4wAgX0GAAmoQMAwfCyBfQf06NgKYAiBfQbLiADYClAIgX0HHJjYCkAJBqMICKAIAIgBBpeMAIF9BkAJqEDAMHgsgX0GvPTYCqAIgX0Gx4gA2AqQCIF9BxyY2AqACQajCAigCACIAQaXjACBfQaACahAwDB0LIF9ByD82ArgCIF9BsOIANgK0AiBfQccmNgKwAkGowgIoAgAiAEGl4wAgX0GwAmoQMAwcCyBfQf4gNgIIIF9BqeMANgIEIF9BxyY2AgBBqMICKAIAIgBBpeMAIF8QMAwbCwwSCyABKAJEIj1BAk8NFCAAIUMgASgCjAEhhQEgASgCkAEhhgEgASgClAEhiQEgASgCmAEhhwEgPUEARyFpIwBB4AFrImYkAAJAIIUBKAIARQRAIIYBKQMYIhAghQEpAxgiE30iBEIAWQRAIIUBKAIwQQRGBEAghgEoAjBBBEYEQCCJASgCMEEERgRAIIUBKQMQIhIghgEpAxBRBEAgEiCJASkDGFEEQCASIIcBKQMQUQRAIBMghwEpAxhRBEAgASgCMEEERgRAIAEoAjQiPUEDSwRAID0gASgCOCIATQRAIAEoAjwgAE8EQCBDKAIEIUACQAJAIEMoAgAOAwABDwELIEANDiABKALAAUEAIAEpAyggASkDICABKQMQIAEpAxh+fn6nQQJ0/AsADA4LIAEoAgAiPUEQa0FySQRAIIUBKQMgIgUghgEpAyAiFn8hOSCGASkDKCAWfiICpyI+IEMoAggiAGpBAWsgAG0iACBAbCJBIAAgQWoiACA+IAAgPkgbIj9ODQ4gOacidUEATA0OIBNCAFcNDiCHASgCPCF5IIcBKAI4IXoghwEoAjQhkgEgiQEoAjwhgQEgiQEoAjghdiCJASgCNCFjIIYBKAI8IWwghgEoAjgheCCGASgCNCFgIIUBKAI8IU8ghQEoAjghZSCFASgCNCFxIIcBKAIwIXsgASgCwAEifyA9QSRsQZiaAWooAgAiASCFASkDKCASIBN+IAV+fqdsQQNqQXxxIgAgASAQIBJ+IAJ+p2xBA2pBfHFqaiFwIAAgf2ohdyCJASkDEEIChiIMIBJ+IgMgBX4hCyAQIBJCAoYiEX4iAiAFfiEHIBGnIWEgA6chVCACpyFdIBEgE34iAqchViACIAV+pyFeIARCAXwhCUMAAIA/IBK0kZUilQL9EyGoAiAWpyFQIBKnIogBQXBxIj0giAFBD3EiXyCIAUEDcSKMAWsiYmohPiAQpyJEQXxxIUIgQCASIERBA2pBfHEijQGsIg8gDyASUxunIgFBEGoiV0EBdGwiAEECdCFTII0BIERrInRBfHEiXCBEaiFAIAAgAWpBAnRBQGshWSA/rCEIIEGsIR4gdEEESSFYID1Bf3MgiAFqQQNJIVoDQCAepyAeIBZ/IgIgFn6nayKOASB2bCCBASACpyIAbGohTSB4II4BbCAAIGxsaiF+IFQgjgFsrSACIAt+Qvz///8Pg3whBiBdII4BbK0gAiAHfkL8////D4N8IQUgACBebCFbIAAgeWwhUiAAIE9sIU5BACGRAQNAIFAgkQFsII4BaiIAIFZsIFtqIUwgACB6bCBSaiGCASAAIGVsIE5qIWtCACENA0AgQygCECJJIFNqIWoCQCBEII0BTg0AQQAhZCBEIQAgWEUEQANAIGogRCBkakECdGr9DAAAgP8AAID/AACA/wAAgP/9CwIAIGRBBGoiZCBcRw0ACyBAIQAgXCB0Rg0BCwNAIGogAEECdGpBgICAfDYCACAAQQFqIgAgjQFHDQALCyAJIA18IBAgaRsiA0IAVSJRBEAghQEoAsABIHEgDadsIGtqaiFGIIYBKALAASFBQgAhAgNAIEEgYCACpyIBbCB+amohSEEAIWT9DAAAAAAAAAAAAAAAAAAAAAAipwIhqQL9DAAAAAAAAAAAAAAAAAAAAAAhpQL9DAAAAAAAAAAAAAAAAAAAAAAhqgIgPUEASgRAA0AgpwIgSCBkQQJ0IgBqIj/9AAAwIAAgRmoiAP0AADD95gH95AEhpwIgqQIgP/0AACAgAP0AACD95gH95AEhqQIgpQIgP/0AABAgAP0AABD95gH95AEhpQIgqgIgP/0AAAAgAP0AAAD95gH95AEhqgIgZEEQaiJkID1IDQALIKoCIKkC/eQBIKUCIKcC/eQB/eQBIacCCyABQQJ0IYQCIKcC/R8DIKcC/R8CIKcC/R8AIKcC/R8BkpKSIZICAkAgPSCIAU4NAEEAIWQgPSEAIIwBBEADQCBIIABBAnQiAWoqAgAgASBGaioCAJQgkgKSIZICIABBAWohACBkQQFqImQgjAFHDQALCyBaDQADQCBIIABBAnQiRUEMaiIBaioCACABIEZqKgIAlCBIIEVBCGoiAWoqAgAgASBGaioCAJQgSCBFQQRqIgFqKgIAIAEgRmoqAgCUIEUgSGoqAgAgRSBGaioCAJQgkgKSkpKSIZICIABBBGoiACCIAUcNAAsLIIQCIGpqIJICOAIAIAJCAXwiAiADUg0ACwsCQCADpyJuQXBxIgFBAEwijwENACABQQFrIj9BBHZBAWoiAEEBcSGFAkEAIWQgP0EPRwRAIABB/v///wFxIT9BACFoA0AgaiBkQQJ0IgBqIkUgqAIgRf0AAAD95gH9CwAAIEUgqAIgRf0AABD95gH9CwAQIEUgqAIgRf0AACD95gH9CwAgIEUgqAIgRf0AADD95gH9CwAwIGogAEHAAHJqIgAgqAIgAP0AAAD95gH9CwAAIAAgqAIgAP0AABD95gH9CwAQIAAgqAIgAP0AACD95gH9CwAgIAAgqAIgAP0AADD95gH9CwAwIGRBIGohZCBoQQJqImggP0cNAAsLIIUCRQ0AIGogZEECdGoiACCoAiAA/QAAAP3mAf0LAAAgACCoAiAA/QAAEP3mAf0LABAgACCoAiAA/QAAIP3mAf0LACAgACCoAiAA/QAAMP3mAf0LADALAkAgASBuTiKKAQ0AIAEhACBuQQ9xIj9BBE8EQCAAID8gbkEDcSJFayJBaiEAQQAhZANAIGogASBkakECdGoiPyCoAiA//QACAP3mAf0LAgAgZEEEaiJkIEFHDQALIEVFDQELA0AgaiAAQQJ0aiI/IJUCID8qAgCUOAIAIABBAWoiACBuRw0ACwsCQCADIBBZDQAgECADIgJ9Ig5CBFoEQCACIA5CfIMiBHwhAkIAIR0DQCBqIAMgHXynQQJ0av0MAACA/wAAgP8AAID/AACA//0LAgAgHUIEfCIdIARSDQALIAQgDlENAQsDQCBqIAKnQQJ0akGAgIB8NgIAIAJCAXwiAiAQUg0ACwsCQCBuQQBMIm0EQEMAAID/IZICDAELQwAAgP8hkgJBACFoQQAhACBuQQFrQQNPBEAgbkF8cSE/QQAhZANAIJICIGogAEECdCJBaioCACKTAiCSAiCTAl4bIpMCIGogQUEEcmoqAgAikgIgkgIgkwJdGyKTAiBqIEFBCHJqKgIAIpICIJICIJMCXRsikwIgaiBBQQxyaioCACKSAiCSAiCTAl0bIZICIABBBGohACBkQQRqImQgP0cNAAsLIG5BA3EiP0UNAANAIJICIGogAEECdGoqAgAikwIgkgIgkwJeGyGSAiAAQQFqIQAgaEEBaiJoID9HDQALCyBqIFdBAnRqIX1EAAAAAAAAAAAhxwICQCCNAUEATARARAAAAAAAAAAAIcUCRAAAAAAAAAAAIcYCRAAAAAAAAAAAIcgCDAELRAAAAAAAAAAAIcUCRAAAAAAAAAAAIcYCRAAAAAAAAAAAIcgCIANCAFcNACAPIAMgAyAPVRshBEIAIQIDQEMAAAAAIZQCIGogAqdBAnQiAGoiPyoCACKTAkMAAID/XARAIMcCIJMCIJICkxBFIpQCu6AhxwILIAAgfWoiACCUAjgCAAJAIAMgAkIBhFcNAEMAAAAAIZQCID8qAgQikwJDAACA/1wEQCDFAiCTAiCSApMQRSKUArugIcUCCyAAIJQCOAIEIAMgAkIChFcNAEMAAAAAIZQCID8qAggikwJDAACA/1wEQCDGAiCTAiCSApMQRSKUArugIcYCCyAAIJQCOAIIIAMgAkIDhFcNAEMAAAAAIZQCID8qAgwikwJDAACA/1wEQCDIAiCTAiCSApMQRSKUArugIcgCCyAAIJQCOAIMCyACQgR8IgIgBFMNAAsLRAAAAAAAAPA/IMcCRAAAAAAAAAAAoCDFAqAgxgKgIMgCoKO2IZICAkAgAUEATA0AIAFBAWsiP0EEdkEBaiIAQQFxIYYCIJIC/RMhpQJBACFkID9BD0cEQCAAQf7///8BcSE/QQAhaANAIH0gZEECdCIAaiJFIKUCIEX9AAAA/eYB/QsAACBFIKUCIEX9AAAQ/eYB/QsAECBFIKUCIEX9AAAg/eYB/QsAICBFIKUCIEX9AAAw/eYB/QsAMCB9IABBwAByaiIAIKUCIAD9AAAA/eYB/QsAACAAIKUCIAD9AAAQ/eYB/QsAECAAIKUCIAD9AAAg/eYB/QsAICAAIKUCIAD9AAAw/eYB/QsAMCBkQSBqIWQgaEECaiJoID9HDQALCyCGAkUNACB9IGRBAnRqIgAgpQIgAP0AAAD95gH9CwAAIAAgpQIgAP0AABD95gH9CwAQIAAgpQIgAP0AACD95gH9CwAgIAAgpQIgAP0AADD95gH9CwAwCwJAIIoBDQAgASEAIG5BD3EiP0EETwRAIAAgPyBuQQNxIkVrIkFqIQAgkgL9EyGlAkEAIWQDQCB9IAEgZGpBAnRqIj8gP/0AAgAgpQL95gH9CwIAIGRBBGoiZCBBRw0ACyBFRQ0BCwNAIH0gAEECdGoiPyA/KgIAIJIClDgCACAAQQFqIgAgbkcNAAsLIG1FBEAgakEAIG5BAnT8CwALIBJCAFUiSgRAIAEgbkEPcSJLIG5BA3EiR2siRmohPyCSASANp2wgggFqIUhCACECA0AgiQEoAsABIE0gYyACpyIAbGpqIWQghwEoAsABIEggACB7bGpqKgIAIZICII8BRQRAIJIC/RMhpQJBACFoA0AgaiBoQQJ0IgBqIkEgpQIgACBkaiIA/QAAAP3mASBB/QAAAP3kAf0LAAAgQSClAiAA/QAAEP3mASBB/QAAEP3kAf0LABAgQSClAiAA/QAAIP3mASBB/QAAIP3kAf0LACAgQSClAiAA/QAAMP3mASBB/QAAMP3kAf0LADAgaEEQaiJoIAFIDQALCwJAIIoBDQAgASEAIEtBBE8EQCCSAv0TIaUCQQAhAANAIGogACABakECdCJFaiJBIEUgZGr9AAIAIKUC/eYBIEH9AAIA/eQB/QsCACAAQQRqIgAgRkcNAAsgPyEAIEdFDQELA0AgaiAAQQJ0IkVqIkEgRSBkaioCACCSApQgQSoCAJI4AgAgAEEBaiIAIG5HDQALCyACQgF8IgIgElINAAsLQQAhaP0MAAAAAAAAAAAAAAAAAAAAACKnAiGpAv0MAAAAAAAAAAAAAAAAAAAAACGlAv0MAAAAAAAAAAAAAAAAAAAAACGqAiCPAUUEQANAIKcCIH0gaEECdCIAaiI//QAAMCAAIGpqIgD9AAAw/eYB/eQBIacCIKkCID/9AAAgIAD9AAAg/eYB/eQBIakCIKUCID/9AAAQIAD9AAAQ/eYB/eQBIaUCIKoCID/9AAAAIAD9AAAA/eYB/eQBIaoCIGhBEGoiaCABSA0ACyCqAiCpAv3kASClAiCnAv3kAf3kASGnAgsgpwL9HwMgpwL9HwIgpwL9HwAgpwL9HwGSkpIhkgICQCCKAQ0AQQAhZCABIQAgbkEDcSJBBEADQCB9IABBAnQiP2oqAgAgPyBqaioCAJQgkgKSIZICIABBAWohACBkQQFqImQgQUcNAAsLIAFBf3MgbmpBA0kNAANAIH0gAEECdCJBQQxqIj9qKgIAID8gamoqAgCUIH0gQUEIaiI/aioCACA/IGpqKgIAlCB9IEFBBGoiP2oqAgAgPyBqaioCAJQgQSB9aioCACBBIGpqKgIAlCCSApKSkpIhkgIgAEEEaiIAIG5HDQALCwJAIERBAEwNAEEAIQAgREEETwRAIJIC/RMhpQIDQCBqIABBAnRqIj8gP/0AAgAgpQL95QH9CwIAIABBBGoiACBCRw0ACyBCIgAgREYNAQsDQCBqIABBAnRqIj8gPyoCACCSApM4AgAgAEEBaiIAIERHDQALCwJAIG0NAEEAIWRBACEAAkAgbkEMSQ0AIG5BAnQiPyBJIFlqaiBqSyB9ID8gampJcQ0AIG5BfHEhAEEAIWgDQCBqIGhBAnQiQWoiPyA//QACACBBIH1q/QACAP3mAf0LAgAgaEEEaiJoIABHDQALIAAgbkYNAQsgAEF/cyBuaiGHAiBuQQNxIkUEQANAIGogAEECdCJBaiI/ID8qAgAgQSB9aioCAJQ4AgAgAEEBaiEAIGRBAWoiZCBFRw0ACwsghwJBA0kNAANAIGogAEECdCJFaiI/ID8qAgAgRSB9aioCAJQ4AgAgaiBFQQRqIkFqIj8gPyoCACBBIH1qKgIAlDgCACBqIEVBCGoiQWoiPyA/KgIAIEEgfWoqAgCUOAIAIGogRUEMaiJBaiI/ID8qAgAgQSB9aioCAJQ4AgAgAEEEaiIAIG5HDQALCwJAII8BDQAgAUEBayI/QQR2QQFqIgBBAXEhiAJBACFkID9BD0cEQCAAQf7///8BcSE/QQAhaANAIGogZEECdCIAaiJFIKgCIEX9AAAA/eYB/QsAACBFIKgCIEX9AAAQ/eYB/QsAECBFIKgCIEX9AAAg/eYB/QsAICBFIKgCIEX9AAAw/eYB/QsAMCBqIABBwAByaiIAIKgCIAD9AAAA/eYB/QsAACAAIKgCIAD9AAAQ/eYB/QsAECAAIKgCIAD9AAAg/eYB/QsAICAAIKgCIAD9AAAw/eYB/QsAMCBkQSBqIWQgaEECaiJoID9HDQALCyCIAkUNACBqIGRBAnRqIgAgqAIgAP0AAAD95gH9CwAAIAAgqAIgAP0AABD95gH9CwAQIAAgqAIgAP0AACD95gH9CwAgIAAgqAIgAP0AADD95gH9CwAwCwJAIIoBDQAgASEAIG5BD3EiP0EETwRAIAAgPyBuQQNxIkVrIkFqIQBBACFkA0AgaiABIGRqQQJ0aiI/IKgCID/9AAIA/eYB/QsCACBkQQRqImQgQUcNAAsgRUUNAQsDQCBqIABBAnRqIj8glQIgPyoCAJQ4AgAgAEEBaiIAIG5HDQALCyBRBEAgfyBMIA2nIkUgYWxqaiFLQgAhAgNAIIYBKALAASBgIAKnIgBsIH5qaiFHIGogAEECdGoqAgAhkgIgPUEATCJGRQRAIJIC/RMhpQJBACFoA0AgSyBoQQJ0IgBqIj8gpQIgACBHaiIA/QAAAP3mASA//QAAAP3kAf0LAAAgPyClAiAA/QAAEP3mASA//QAAEP3kAf0LABAgPyClAiAA/QAAIP3mASA//QAAIP3kAf0LACAgPyClAiAA/QAAMP3mASA//QAAMP3kAf0LADAgaEEQaiJoID1IDQALCwJAID0giAFOIkgNACA9IQAgX0EETwRAIJIC/RMhpQJBACEAA0AgSyAAID1qQQJ0IkFqIj8gQSBHav0AAgAgpQL95gEgP/0AAgD95AH9CwIAIABBBGoiACBiRw0ACyA+IQAgjAFFDQELA0AgSyAAQQJ0IkFqIj8gQSBHaioCACCSApQgPyoCAJI4AgAgAEEBaiIAIIgBRw0ACwsgAkIBfCICIANSDQALIEUgcWwga2ohRUIAIQIDQCCFASgCwAEgRWohSyB3IAUgAiARfnynaiFHIGogAqdBAnRqKgIAIZICIEZFBEAgkgL9EyGlAkEAIWgDQCBHIGhBAnQiAGoiPyClAiAAIEtqIgD9AAAA/eYBID/9AAAA/eQB/QsAACA/IKUCIAD9AAAQ/eYBID/9AAAQ/eQB/QsAECA/IKUCIAD9AAAg/eYBID/9AAAg/eQB/QsAICA/IKUCIAD9AAAw/eYBID/9AAAw/eQB/QsAMCBoQRBqImggPUgNAAsLAkAgSA0AID0hACBfQQRPBEAgkgL9EyGlAkEAIQADQCBHIAAgPWpBAnQiQWoiPyBBIEtq/QACACClAv3mASA//QACAP3kAf0LAgAgAEEEaiIAIGJHDQALID4hACCMAUUNAQsDQCBHIABBAnQiQWoiPyBBIEtqKgIAIJIClCA/KgIAkjgCACAAQQFqIgAgiAFHDQALCyACQgF8IgIgA1INAAsLIEoEQCABIG5BD3EiSyBuQQNxIkdrIkZqIT8gkgEgDadsIIIBaiFIQgAhAgNAIHAgBiACIAx+fKdqIUoghwEoAsABIEggeyACp2xqaioCACGSAiCPAUUEQCCSAv0TIaUCQQAhaANAIEogaEECdCIAaiJBIKUCIAAgfWoiAP0AAAD95gEgQf0AAAD95AH9CwAAIEEgpQIgAP0AABD95gEgQf0AABD95AH9CwAQIEEgpQIgAP0AACD95gEgQf0AACD95AH9CwAgIEEgpQIgAP0AADD95gEgQf0AADD95AH9CwAwIGhBEGoiaCABSA0ACwsCQCCKAQ0AIAEhACBLQQRPBEAgkgL9EyGlAkEAIQADQCBKIAAgAWpBAnQiRWoiQSBFIH1q/QACACClAv3mASBB/QACAP3kAf0LAgAgAEEEaiIAIEZHDQALID8hACBHRQ0BCwNAIEogAEECdCJFaiJBIEUgfWoqAgAgkgKUIEEqAgCSOAIAIABBAWoiACBuRw0ACwsgAkIBfCICIBJSDQALCyANQgF8Ig0gE1INAAsgkQFBAWoikQEgdUcNAAsgCCAeQgF8Ih5SDQALDA4LIGZBhD82AiggZkH44wA2AiQgZkHHJjYCIEGowgIoAgAiAEGl4wAgZkEgahAwDCcLIGZB3Tk2AhggZkHn4wA2AhQgZkHHJjYCEEGowgIoAgAiAEGl4wAgZkEQahAwDCYLIGZB8jo2AgggZkHm4wA2AgQgZkHHJjYCAEGowgIoAgAiAEGl4wAgZhAwDCULIGZBpD02AjggZkHl4wA2AjQgZkHHJjYCMEGowgIoAgAiAEGl4wAgZkEwahAwDCQLIGZBiNAANgJIIGZB5OMANgJEIGZBxyY2AkBBqMICKAIAIgBBpeMAIGZBQGsQMAwjCyBmQZcuNgJYIGZB4eMANgJUIGZBxyY2AlBBqMICKAIAIgBBpeMAIGZB0ABqEDAMIgsgZkHvMjYCaCBmQdzjADYCZCBmQccmNgJgQajCAigCACIAQaXjACBmQeAAahAwDCELIGZBxzI2AnggZkHb4wA2AnQgZkHHJjYCcEGowgIoAgAiAEGl4wAgZkHwAGoQMAwgCyBmQdwyNgKIASBmQdrjADYChAEgZkHHJjYCgAFBqMICKAIAIgBBpeMAIGZBgAFqEDAMHwsgZkHGzwA2ApgBIGZB1+MANgKUASBmQccmNgKQAUGowgIoAgAiAEGl4wAgZkGQAWoQMAweCyBmQfLPADYCqAEgZkHW4wA2AqQBIGZBxyY2AqABQajCAigCACIAQaXjACBmQaABahAwDB0LIGZB3M8ANgK4ASBmQdXjADYCtAEgZkHHJjYCsAFBqMICKAIAIgBBpeMAIGZBsAFqEDAMHAsgZkGcwAA2AsgBIGZB0+MANgLEASBmQccmNgLAAUGowgIoAgAiAEGl4wAgZkHAAWoQMAwbCyBmQf4gNgLYASBmQaDmADYC1AEgZkHHJjYC0AFBqMICKAIAIgBBpeMAIGZB0AFqEDAMGgsgZkHgAWokAAwRCyABKAKMASFCIwBBEGsiTyQAAkAgQigCAEUEQAJAAkAgACgCAA4DAQABAAsgASgCSCI/QQBMDQAgASgCRCJAQQBMDQAgASkDICIuQgBXDQAgASkDGCIhQgBXDQAgASkDECInQgBXDQAgQikDICEmICdCA4MhKSAnQnyDIQMgQikDECIoQgKGIR0gJ0IChiEaIEIpAxgiKiAofiIEQgKGISAgISAufiAnfiEkICenIgBBAnQhPiAAICGnbEECdCE9ICEgJ34iAkIChiIlIC5+ISMgBCABKAJMIgCsIit+QgKGQvz///8PgyEfIAIgLn4iAkIChkL8////D4MhGSACIECtIh5+QgKGQvz///8PgyEbIAAgKKdsQQJ0rSEXID+tIRwDQCAFICt+IRggBSAefiEVIAUgH34hEiAFIBt+IRAgQCAFp2whAEIAIQ0DQCANICt+IRMgDSAVfCICIC5+IRYgEiANIBd+fCERIBAgDSAZfnwhDyACICR+QgKGIQ4gIyAAIA2naq1+Qvz///8PgyEMQgAhCgNAIAogJX4hBAJAICYgCiAYfCICVQRAIAIgKn4hCyAKIBZ8ICF+IQcgBCAMfCEJIBEgCiAgfnwhCCAEIA98IQZCACEUA0AgFCAafiEEAkAgKiATIBR8IgJXBEAgASgCwAEgBCAJfKdqQQAgPvwLAAwBCyAHIBR8ICd+ISwgAiALfCAofiEtIAEoAsABIUMgQigCwAEhP0IAISJCACECAkAgJ0IIVA0AIEMgBCAGfKdqID8gCCAUIB1+fKdqa0EQSQ0AA0AgQyACICx8p0ECdGogPyACIC18p0ECdGr9AAIA/QsCACACQgR8IgIgA1INAAsgAyICICdRDQELICcgAkJ/hXwhOiApQgBSBEADQCBDIAIgLHynQQJ0aiA/IAIgLXynQQJ0aioCADgCACACQgF8IQIgIkIBfCIiIClSDQALCyA6QgNUDQADQCBDIAIgLHynQQJ0aiA/IAIgLXynQQJ0aioCADgCACBDIAJCAXwiBCAsfKdBAnRqID8gBCAtfKdBAnRqKgIAOAIAIEMgAkICfCIEICx8p0ECdGogPyAEIC18p0ECdGoqAgA4AgAgQyACQgN8IgQgLHynQQJ0aiA/IAQgLXynQQJ0aioCADgCACACQgR8IgIgJ1INAAsLIBRCAXwiFCAhUg0ACwwBCyABKALAASAEIA58p2pBACA9/AsACyAKQgF8IgogLlINAAsgDUIBfCINIB5SDQALIAVCAXwiBSAcUg0ACwsgT0EQaiQADAELIE9B/iA2AgggT0He5gA2AgQMFwsMEAsgASgCjAEhQCMAQRBrIkkkAAJAIEAoAgBFBEACQAJAIAAoAgAOAwEAAQALIAE0AkQiFyABKQMYIhUgF4F9IBeBIBV8IBd/IRAgASkDICITQgBXDQAgFUIAVw0AIAEpAxAiG0IAVw0AIBtCA4MhEiAbQnyDIQMgG0IChiEWIEApAxAiEadBAnQhPyAVIBt+QgKGIQ8gQCkDICIOpyE+IEApAxgiDKchPSBAKALAASFAIAEoAsABIgGtIQsDQCANIBV+IQcgDSAPfiALfCEJIA0gF38iAiAQfiEIIA0gAiAXfn0iBqchAEIAIQoDQCAKIBd/IgIgCHwiBcQgDn4gBnwgDH4gCiACIBd+fSIEfCARfiEcIAcgCnwgG34hGEIAIR1CACECAkACQCAbQgxUDQAgCSAKIBZ+fKcgPyAEpyA+IAWnbCAAaiA9bGpsIEBqa0EQSQ0AA0AgASACIBh8p0ECdGogQCACIBx8p0ECdGr9AAIA/QsCACACQgR8IgIgA1INAAsgAyICIBtRDQELIBsgAkJ/hXwhOyASQgBSBEADQCABIAIgGHynQQJ0aiBAIAIgHHynQQJ0aioCADgCACACQgF8IQIgHUIBfCIdIBJSDQALCyA7QgNUDQADQCABIAIgGHynQQJ0aiBAIAIgHHynQQJ0aioCADgCACABIAJCAXwiBCAYfKdBAnRqIEAgBCAcfKdBAnRqKgIAOAIAIAEgAkICfCIEIBh8p0ECdGogQCAEIBx8p0ECdGoqAgA4AgAgASACQgN8IgQgGHynQQJ0aiBAIAQgHHynQQJ0aioCADgCACACQgR8IgIgG1INAAsLIApCAXwiCiAVUg0ACyANQgF8Ig0gE1INAAsLIElBEGokAAwBCyBJQf4gNgIIIElBmucANgIEDBULDA8LIAEoAowBIT8jAEHgAmsiSiQAAkACQAJAAkACQAJAAkACQAJAAkACQCABKAJAQTlGBEACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAIAEoAkQOCwABAgMEBQYHCAkKDQsgPygCAEUEQAJAIAAoAgAOAwwADAALID8pAyggPykDICA/KQMYfn6nIkFBAEwNCyA/KAIQIkhBAEwNCyA/KAI0IUQgASgCNCFDID8oAsABIUIgASgCwAEhQCBIQQNxIUUgSEF8cSEBIEhBBEkhPwNAIEIgRCBJbGohRyBAIEMgSWxqIUZBACEAAkACQCA/DQAgRiBHa0EQSQ0AA0AgRiAAQQJ0Ij1qID0gR2r9AAIA/eAB/QsCACAAQQRqIgAgAUcNAAsgASIAIEhGDQELIABBf3MgSGohiQJBACFPIEUEQANAIEYgAEECdCI9aiA9IEdqKgIAizgCACAAQQFqIQAgT0EBaiJPIEVHDQALCyCJAkEDSQ0AA0AgRiAAQQJ0Ij5qID4gR2oqAgCLOAIAIEYgPkEEaiI9aiA9IEdqKgIAizgCACBGID5BCGoiPWogPSBHaioCAIs4AgAgRiA+QQxqIj1qID0gR2oqAgCLOAIAIABBBGoiACBIRw0ACwsgSUEBaiJJIEFHDQALDAsLIEpB/iA2AhggSkHYwQA2AhQgSkHHJjYCEEGowgIoAgAiT0Gl4wAgSkEQahAwDBcLID8oAgBFBEACQCAAKAIADgMLAAsACyA/KQMoID8pAyAgPykDGH5+pyJIQQBMDQogPygCECJLQQBMDQogPygCNCFFIAEoAjQhQSA/KALAASFEIAEoAsABIUNBACBLayFCIEtBAXEhQCBLQXxxIQEgS0EESSE/A0AgRCBFIElsaiFHIEMgQSBJbGohRkEAIQACQAJAID8NACBGIEdrQRBJDQADQCBGIABBAnQiPWr9DAAAgD8AAIA/AACAPwAAgD/9DAAAgL8AAIC/AACAvwAAgL/9DAAAAAAAAAAAAAAAAAAAAAAgPSBHav0AAgAipQL9DAAAAAAAAAAAAAAAAAAAAAD9Q/1SIKUC/QwAAAAAAAAAAAAAAAAAAAAA/UT9Uv0LAgAgAEEEaiIAIAFHDQALIAEiACBLRg0BCyAAQX9zIYoCIEAEQCBGIABBAnQiPWpDAACAP0MAAIC/QwAAAAAgPSBHaioCACKSAkMAAAAAXRsgkgJDAAAAAF4bOAIAIABBAXIhAAsgigIgQkYNAANAIEYgAEECdCI9akMAAIA/QwAAgL9DAAAAACA9IEdqKgIAIpICQwAAAABdGyCSAkMAAAAAXhs4AgAgRiA9QQRqIj1qQwAAgD9DAACAv0MAAAAAID0gR2oqAgAikgJDAAAAAF0bIJICQwAAAABeGzgCACAAQQJqIgAgS0cNAAsLIElBAWoiSSBIRw0ACwwKCyBKQf4gNgIoIEpBgsIANgIkIEpBxyY2AiBBqMICKAIAIk9BpeMAIEpBIGoQMAwWCyA/KAIARQRAAkAgACgCAA4DCgAKAAsgPykDKCA/KQMgID8pAxh+fqciQUEATA0JID8oAhAiSEEATA0JID8oAjQhRCABKAI0IUMgPygCwAEhQiABKALAASFAIEhBA3EhRSBIQXxxIQEgSEEESSE/A0AgQiBEIElsaiFHIEAgQyBJbGohRkEAIQACQAJAID8NACBGIEdrQRBJDQADQCBGIABBAnQiPWogPSBHav0AAgD94QH9CwIAIABBBGoiACABRw0ACyABIgAgSEYNAQsgAEF/cyBIaiGLAkEAIU8gRQRAA0AgRiAAQQJ0Ij1qID0gR2oqAgCMOAIAIABBAWohACBPQQFqIk8gRUcNAAsLIIsCQQNJDQADQCBGIABBAnQiPmogPiBHaioCAIw4AgAgRiA+QQRqIj1qID0gR2oqAgCMOAIAIEYgPkEIaiI9aiA9IEdqKgIAjDgCACBGID5BDGoiPWogPSBHaioCAIw4AgAgAEEEaiIAIEhHDQALCyBJQQFqIkkgQUcNAAsMCQsgSkH+IDYCOCBKQazCADYCNCBKQccmNgIwQajCAigCACJPQaXjACBKQTBqEDAMFQsgPygCAEUEQAJAIAAoAgAOAwkACQALID8pAyggPykDICA/KQMYfn6nIkFBAEwNCCA/KAIQIkhBAEwNCCA/KAI0IUQgASgCNCFDID8oAsABIUIgASgCwAEhQCBIQQNxIUUgSEF8cSEBIEhBBEkhPwNAIEIgRCBJbGohRyBAIEMgSWxqIUZBACEAAkACQCA/DQAgRiBHa0EQSQ0AA0AgRiAAQQJ0Ij1q/QwAAIA/AACAPwAAgD8AAIA//QwAAAAAAAAAAAAAAAAAAAAAID0gR2r9AAIA/QwAAAAAAAAAAAAAAAAAAAAA/UT9Uv0LAgAgAEEEaiIAIAFHDQALIAEiACBIRg0BCyAAQX9zIEhqIYwCQQAhTyBFBEADQCBGIABBAnQiPWpDAACAP0MAAAAAID0gR2oqAgBDAAAAAF4bOAIAIABBAWohACBPQQFqIk8gRUcNAAsLIIwCQQNJDQADQCBGIABBAnQiPmpDAACAP0MAAAAAID4gR2oqAgBDAAAAAF4bOAIAIEYgPkEEaiI9akMAAIA/QwAAAAAgPSBHaioCAEMAAAAAXhs4AgAgRiA+QQhqIj1qQwAAgD9DAAAAACA9IEdqKgIAQwAAAABeGzgCACBGID5BDGoiPWpDAACAP0MAAAAAID0gR2oqAgBDAAAAAF4bOAIAIABBBGoiACBIRw0ACwsgSUEBaiJJIEFHDQALDAgLIEpB/iA2AkggSkHWwgA2AkQgSkHHJjYCQEGowgIoAgAiT0Gl4wAgSkFAaxAwDBQLID8oAgBFBEACQCAAKAIADgMIAAgACyA/KQMoID8pAyAgPykDGH5+pyJBQQBMDQcgPygCECJEQQBMDQcgPygCNCFDIAEoAjQhQiA/KALAASFAIAEoAsABIT8DQCBAIEMgT2xqIT4gPyBCIE9saiE9QQAhAANAID0gAEECdCIBaiABID5qKgIAEI0EOAIAIABBAWoiACBERw0ACyBPQQFqIk8gQUcNAAsMBwsgSkH+IDYCWCBKQYDDADYCVCBKQccmNgJQQajCAigCACJPQaXjACBKQdAAahAwDBMLID8oAgBFBEACQCAAKAIADgMHAAcACyA/KQMoID8pAyAgPykDGH5+pyJIQQBMDQYgPygCECJLQQBMDQYgPygCNCFFIAEoAjQhQSA/KALAASFEIAEoAsABIUNBACBLayFCIEtBAXEhQCBLQXxxIQEgS0EESSE/A0AgRCBFIElsaiFHIEMgQSBJbGohRkEAIQACQAJAID8NACBGIEdrQRBJDQADQCBHIABBAnQiPWr9AAIAIaUCID0gRmogpQIgpQL9HwAQRf0TIKUC/R8BEEX9IAEgpQL9HwIQRf0gAiClAv0fAxBF/SAD/QwAAIC/AACAvwAAgL8AAIC//eQBIKUC/QwAAAAAAAAAAAAAAAAAAAAA/UT9Uv0LAgAgAEEEaiIAIAFHDQALIAEiACBLRg0BCyAAQX9zIY0CIEAEQCBHIABBAnQiPWoqAgAikgJDAAAAAF5FBEAgkgIQRUMAAIC/kiGSAgsgPSBGaiCSAjgCACAAQQFyIQALII0CIEJGDQADQCBHIABBAnQiPWoqAgAikgJDAAAAAF5FBEAgkgIQRUMAAIC/kiGSAgsgPSBGaiCSAjgCACBHIABBAWpBAnQiPWoqAgAikgJDAAAAAF5FBEAgkgIQRUMAAIC/kiGSAgsgPSBGaiCSAjgCACAAQQJqIgAgS0cNAAsLIElBAWoiSSBIRw0ACwwGCyBKQf4gNgJoIEpBqsMANgJkIEpBxyY2AmBBqMICKAIAIk9BpeMAIEpB4ABqEDAMEgsgPygCAEUEQAJAIAAoAgAOAwYABgALID8pAyggPykDICA/KQMYfn6nIkFBAEwNBSA/KAIQIkhBAEwNBSA/KAI0IUQgASgCNCFDID8oAsABIUIgASgCwAEhQCBIQQNxIUUgSEF8cSEBIEhBBEkhPwNAIEIgRCBJbGohRyBAIEMgSWxqIUZBACEAAkACQCA/DQAgRiBHa0EQSQ0AA0AgRiAAQQJ0Ij1q/QwAAAAAAAAAAAAAAAAAAAAAID0gR2r9AAIA/esB/QsCACAAQQRqIgAgAUcNAAsgASIAIEhGDQELIABBf3MgSGohjgJBACFPIEUEQANAIEYgAEECdCI9aiA9IEdqKgIAIpICQwAAAAAgkgJDAAAAAF4bOAIAIABBAWohACBPQQFqIk8gRUcNAAsLII4CQQNJDQADQCBGIABBAnQiPmogPiBHaioCACKSAkMAAAAAIJICQwAAAABeGzgCACBGID5BBGoiPWogPSBHaioCACKSAkMAAAAAIJICQwAAAABeGzgCACBGID5BCGoiPWogPSBHaioCACKSAkMAAAAAIJICQwAAAABeGzgCACBGID5BDGoiPWogPSBHaioCACKSAkMAAAAAIJICQwAAAABeGzgCACAAQQRqIgAgSEcNAAsLIElBAWoiSSBBRw0ACwwFCyBKQf4gNgJ4IEpB1MMANgJ0IEpBxyY2AnBBqMICKAIAIk9BpeMAIEpB8ABqEDAMEQsgPygCAEUEQCA/KAIwQQRHDQggPzUCOCICID8pAxgiBiA/KAI0IkitflINCCA/NQI8IAIgPykDICIFflINCCABKAIwIAEoAgBBJGxBmJoBaigCAEcNCSABNQI4IgQgASkDGCIDIAEoAjQiRa1+Ug0JIAE1AjwgBCABKQMgIgJ+Ug0JIAIgBVINCiADIAZSDQogPykDECIDIAEpAxBSDQogPykDKCICIAEpAyhSDQoCQCAAKAIADgMFAAUACyAFIAZ+IAJ+pyI+IAAoAggiPWpBAWsgPW0iPSAAKAIEbCJPID0gT2oiACA+IAAgPkgbIkFODQQgA6ciREEATA0EID8oAsABIUMgASgCwAEhQgNAIEMgSCBPbGohQCBCIEUgT2xqIT9BACEAA0AgPyAAQQJ0IgFqQYD8ASABIEBqKgIAIpICi0MAAIB3lEMAAIAIlEGAgICIByCSArwiPkEBdCI9QYCAgHhxIgEgAUGAgICIB00bQQF2QYCAgDxqvpK8IgFBDXZBgPgBcSABQf8fcWogPUGAgIB4SxsgPkEQdkGAgAJxckEBdEHw1BRqLwEAQQJ0QfDUBGoqAgA4AgAgAEEBaiIAIERHDQALIE9BAWoiTyBBRw0ACwwECyBKQf4gNgK4ASBKQY/EADYCtAEgSkHHJjYCsAFBqMICKAIAIk9BpeMAIEpBsAFqEDAMEAsgPygCAEUEQCA/KAIwQQRHDQogPzUCOCICID8pAxgiBiA/KAI0IkitflINCiA/NQI8IAIgPykDICIFflINCiABKAIwIAEoAgBBJGxBmJoBaigCAEcNCyABNQI4IgQgASkDGCIDIAEoAjQiRa1+Ug0LIAE1AjwgBCABKQMgIgJ+Ug0LIAIgBVINDCADIAZSDQwgPykDECIDIAEpAxBSDQwgPykDKCICIAEpAyhSDQwCQCAAKAIADgMEAAQACyAFIAZ+IAJ+pyI+IAAoAggiPWpBAWsgPW0iPSAAKAIEbCJPID0gT2oiACA+IAAgPkgbIkFODQMgA6ciREEATA0DID8oAsABIUMgASgCwAEhQgNAIEMgSCBPbGohQCBCIEUgT2xqIT9BACEAA0AgPyAAQQJ0IgFqQYD8ASABIEBqKgIAIpICi0MAAIB3lEMAAIAIlEGAgICIByCSArwiPkEBdCI9QYCAgHhxIgEgAUGAgICIB00bQQF2QYCAgDxqvpK8IgFBDXZBgPgBcSABQf8fcWogPUGAgIB4SxsgPkEQdkGAgAJxckEBdEHw1BxqLwEAQQJ0QfDUBGoqAgA4AgAgAEEBaiIAIERHDQALIE9BAWoiTyBBRw0ACwwDCyBKQf4gNgL4ASBKQcrEADYC9AEgSkHHJjYC8AFBqMICKAIAIk9BpeMAIEpB8AFqEDAMDwsgPygCAEUEQCA/KAIwQQRHDQwgPzUCOCICID8pAxgiBiA/KAI0IkitflINDCA/NQI8IAIgPykDICIFflINDCABKAIwIAEoAgBBJGxBmJoBaigCAEcNDSABNQI4IgQgASkDGCIDIAEoAjQiRa1+Ug0NIAE1AjwgBCABKQMgIgJ+Ug0NIAIgBVINDiADIAZSDQ4gPykDECIDIAEpAxBSDQ4gPykDKCICIAEpAyhSDQ4CQCAAKAIADgMDAAMACyAFIAZ+IAJ+pyI+IAAoAggiPWpBAWsgPW0iPSAAKAIEbCJPID0gT2oiACA+IAAgPkgbIkFODQIgA6ciREEATA0CID8oAsABIUMgASgCwAEhQgNAIEMgSCBPbGohQCBCIEUgT2xqIT9BACEAA0AgPyAAQQJ0IgFqQYD8ASABIEBqKgIAIpICi0MAAIB3lEMAAIAIlEGAgICIByCSArwiPkEBdCI9QYCAgHhxIgEgAUGAgICIB00bQQF2QYCAgDxqvpK8IgFBDXZBgPgBcSABQf8fcWogPUGAgIB4SxsgPkEQdkGAgAJxckEBdEHw1CRqLwEAQQJ0QfDUBGoqAgA4AgAgAEEBaiIAIERHDQALIE9BAWoiTyBBRw0ACwwCCyBKQf4gNgK4AiBKQYXFADYCtAIgSkHHJjYCsAJBqMICKAIAIk9BpeMAIEpBsAJqEDAMDgsgPygCAA0BAkAgACgCAA4DAQABAAsgPykDKCA/KQMgID8pAxh+fqciSEEATA0AID8oAhAiS0EATA0AID8oAjQhRSABKAI0IUEgPygCwAEhRCABKALAASFDQQAgS2shQiBLQQFxIUAgS0F8cSEBIEtBBEkhPwNAIEQgRSBJbGohRyBDIEEgSWxqIUZBACEAAkACQCA/DQAgRiBHa0EQSQ0AA0AgRiAAQQJ0Ij1qID0gR2r9AAIAIqUCIKUC/QzNzMw9zczMPc3MzD3NzMw9/eYBIKUC/QwAAAAAAAAAAAAAAAAAAAAA/UT9Uv0LAgAgAEEEaiIAIAFHDQALIAEiACBLRg0BCyAAQX9zIY8CIEAEQCBGIABBAnQiPWogPSBHaioCACKSAiCSAkPNzMw9lCCSAkMAAAAAXhs4AgAgAEEBciEACyCPAiBCRg0AA0AgRiAAQQJ0Ij1qID0gR2oqAgAikgIgkgJDzczMPZQgkgJDAAAAAF4bOAIAIEYgPUEEaiI9aiA9IEdqKgIAIpICIJICQ83MzD2UIJICQwAAAABeGzgCACAAQQJqIgAgS0cNAAsLIElBAWoiSSBIRw0ACwsgSkHgAmokAAwNCyBKQf4gNgLIAiBKQa/FADYCxAIgSkHHJjYCwAJBqMICKAIAIk9BpeMAIEpBwAJqEDAMCwsgSkH+IDYCCCBKQdbnADYCBCBKQccmNgIAQajCAigCACJPQaXjACBKEDAMCgsgSkGNKjYC2AIgSkHUFzYC1AIgSkHHJjYC0AJBqMICKAIAIk9BpeMAIEpB0AJqEDAMCQsgSkG42gA2AqgBIEpB38MANgKkASBKQccmNgKgAUGowgIoAgAiT0Gl4wAgSkGgAWoQMAwICyBKQZ/NADYCmAEgSkHgwwA2ApQBIEpBxyY2ApABQajCAigCACJPQaXjACBKQZABahAwDAcLIEpB5M4ANgKIASBKQeHDADYChAEgSkHHJjYCgAFBqMICKAIAIk9BpeMAIEpBgAFqEDAMBgsgSkG42gA2AugBIEpBmsQANgLkASBKQccmNgLgAUGowgIoAgAiT0Gl4wAgSkHgAWoQMAwFCyBKQZ/NADYC2AEgSkGbxAA2AtQBIEpBxyY2AtABQajCAigCACJPQaXjACBKQdABahAwDAQLIEpB5M4ANgLIASBKQZzEADYCxAEgSkHHJjYCwAFBqMICKAIAIk9BpeMAIEpBwAFqEDAMAwsgSkG42gA2AqgCIEpB1cQANgKkAiBKQccmNgKgAkGowgIoAgAiT0Gl4wAgSkGgAmoQMAwCCyBKQZ/NADYCmAIgSkHWxAA2ApQCIEpBxyY2ApACQajCAigCACJPQaXjACBKQZACahAwDAELIEpB5M4ANgKIAiBKQdfEADYChAIgSkHHJjYCgAJBqMICKAIAIk9BpeMAIEpBgAJqEDALIE8QMxoMGwsMDgsgASgCjAEhPiMAQRBrIj0kAAJAID4oAgBBAUYEQAJAAkAgACgCAA4DAQABAAsgASkDICITQgBXDQAgASkDGCIVQgBXDQAgASkDECIXQgBXDQAgF0IDgyEQIBdCeIMhAyA+KQMQIhJC/v///w9+IRYgEkIBhiERIBdCAYYhDyAVIBd+QgGGIQ4gPigCwAEiPiASpyAVp0EBa2xBAXRqrSEMIAEoAsABIgCtIQsDQCAFIBV+IQcgBSAVfCEJIAUgEX4gDHwhCCAFIA5+IAt8IQZCACENA0AgByANfCAXfiEcIAkgDUJ/hXwgEn4hGEIAIR1CACECAkACQCAXQghUDQAgBiANIA9+fKcgCCANIBZ+fKdrQRBJDQADQCAAIAIgHHynQQF0aiA+IAIgGHynQQF0av0AAQD9CwEAIAJCCHwiAiADUg0ACyADIgIgF1ENAQsgFyACQn+FfCE8IBBCAFIEQANAIAAgAiAcfKdBAXRqID4gAiAYfKdBAXRqLwEAOwEAIAJCAXwhAiAdQgF8Ih0gEFINAAsLIDxCA1QNAANAIAAgAiAcfKdBAXRqID4gAiAYfKdBAXRqLwEAOwEAIAAgAkIBfCIEIBx8p0EBdGogPiAEIBh8p0EBdGovAQA7AQAgACACQgJ8IgQgHHynQQF0aiA+IAQgGHynQQF0ai8BADsBACAAIAJCA3wiBCAcfKdBAXRqID4gBCAYfKdBAXRqLwEAOwEAIAJCBHwiAiAXUg0ACwsgDUIBfCINIBVSDQALIAVCAXwiBSATUg0ACwsgPUEQaiQADAELID1B/iA2AgggPUGD6AA2AgQMFQsMDQsgASgCjAEhPyABKAKQASFCIAEoApQBIT4jAEEQayJJJAACQCA/KAIARQRAAkAgACgCACI9IAEoAkRyRQRAIAEpAyAhAyABKQMYIQIgPygCwAEhPiABKALAASE9IAEoAgAiAEEQa0FxTQRAID0gPiAAQSRsQZiaAWooAgAgASgCMCABKAIQQQFrbGogASgCNCACp0EBa2xqIAEoAjggA6dBAWtsaiABKAI8IAEoAihBAWtsavwKAAAMAgsgPSA+IAE1AjQgAkIBfX4gASkDECABNQIwfiAAQSRsQZSaAWo1AgB/fCABNQI4IANCAX1+fCABNQI8IAEpAyhCAX1+fKf8CgAADAELAkAgPQ4DAQABAAsgQigCKCJAIAAoAggiPWpBAWsgPW0iPSAAKAIEbCI/ID0gP2oiACBAIAAgQEgbIgBODQAgQikDICIRQgBXDQAgQikDGCIPQgBXDQAgQikDECIQQgBXDQAgAKwhDiABKALAASFAID4oAsABIT4gQigCwAEhPUIBIBB9IQwgEEJ+gyELIBBCAYMhByA/rCEFIBBCAVEhAQNAIAUgEX4hCUIAIQ0DQCAJIA18IA9+IQhCACEKA0AgCCAKfCAQfiEGQgAhBANAIAQgBnwiAiAQfiITIAQgDH58IRYgPiACp0ECdCIAaioCACGTAiAAID1qKgIAIZICQgAhA0IAIR0gAUUEQANAIEAgAyATfKdBAnRqIgAgkwIgACoCAJI4AgAgQCAWIAMgEH58p0ECdGoiACCSAiAAKgIAkjgCACBAIANCAYQiAiATfKdBAnRqIgAgkwIgACoCAJI4AgAgQCAWIAIgEH58p0ECdGoiACCSAiAAKgIAkjgCACADQgJ8IQMgHUICfCIdIAtSDQALCyAHpwRAIEAgAyATfKdBAnRqIgAgkwIgACoCAJI4AgAgQCAWIAMgEH58p0ECdGoiACCSAiAAKgIAkjgCAAsgBEIBfCIEIBBSDQALIApCAXwiCiAPUg0ACyANQgF8Ig0gEVINAAsgBUIBfCIFIA5SDQALCyBJQRBqJAAMAQsgSUH+IDYCCCBJQdjoADYCBAwSCwwMCyABKAKMASFEIAEoAkQhQiMAQSBrIkMkAAJAAkAgRCgCAEUEQCBEKQMQIgUgASkDEFINASBEKQMYIgQgASkDGFINASBEKQMgIgMgASkDIFINASBEKQMoIgIgASkDKFINAQJAAkAgACgCAA4DAQABAAsgAyAEfiACfqciQEEATA0AIAWnIT9BACEAIEBBAUcEQCBAQX5xIT4DQCA/IAEoAsABIAEoAjQgAGxqIEQoAsABIEQoAjQgAGxqIEIRBQAgPyABKALAASAAQQFyIj0gASgCNGxqIEQoAsABIEQoAjQgPWxqIEIRBQAgAEECaiEAIGFBAmoiYSA+Rw0ACwsgQEEBcUUNACA/IAEoAsABIAEoAjQgAGxqIEQoAsABIEQoAjQgAGxqIEIRBQALIENBIGokAAwCCyBDQf4gNgIYIENBg+kANgIUIENBxyY2AhBBqMICKAIAIgBBpeMAIENBEGoQMAwVCyBDQeTOADYCCCBDQeToADYCBCBDQccmNgIAQajCAigCACIAQaXjACBDEDAMFAsMCwsgASgCjAEhQiABKAKQASFAIAEoAkQhPyMAQRBrIkkkAAJAIEIoAgBFBEACQAJAIAAoAgAOAwEAAQALIEIpAyggQikDICBCKQMYfn6nIj5BAEwNACBCKAIQIT1BACEAA0AgPSABKALAASABKAI0IABsaiBCKALAASBCKAI0IABsaiBAKALAASBAKAI0IABsaiA/EQYAIABBAWoiACA+Rw0ACwsgSUEQaiQADAELIElB/iA2AgggSUGz6QA2AgQMEAsMCgsCQCAAKAIADgMKAAoACyABIAEoAowBIAEoAkQRAgAMCQsCQCAAKAIADgMJAAkACyABIAEoAowBIAEoApABIAEoAkQRBQAMCAsCQCAAKAIADgMIAAgACyABIAEoAowBIAEoApABIAEoApQBIAEoAkQRBgAMBwsgASgCjAEhPQJAAkAgACgCAA4DAQABAAsgASA9IAAoAgQgACgCCCABKAJMIAEoAkQRCwALDAYLIAEoAowBIT4gASgCkAEhPQJAAkAgACgCAA4DAQABAAsgASA+ID0gACgCBCAAKAIIIAEoAkwgASgCRBEMAAsMBQsgASgCjAEhPyABKAKQASE+IAEoApQBIT0CQAJAIAAoAgAOAwEAAQALIAEgPyA+ID0gACgCBCAAKAIIIAEoAkwgASgCRBEQAAsMBAsgACE+IAEoAowBIVcgASgCkAEhUyMAQeAAayJWJAACQAJ9AkAgVygCAEUEQAJAIFcoAjBBBEcNACBXNQI0IgMgVykDECIJQgKGUg0AIFc1AjgiAiADIFcpAxgiCH5SDQAgVzUCPCACIFcpAyAiBn5SDQACQCBTKAIwIj0gUygCAEEkbCIAQZiaAWooAgBHDQAgUzUCNCICIFMpAxAiBSA9rX4gAEGUmgFqNAIAf1INACBTNQI4IgQgAiBTKQMYIgN+Ug0AIFM1AjwgBCBTKQMgIgJ+Ug0AAkAgASkDEEIBUg0AIAEpAxhCAVINACABKQMgQgFSDQAgASkDKEIBUg0AAkAgBSAJUg0AIAMgCFINACACIAZSDQAgVykDKCICIFMpAyhSDQAgPigCCCJEIAmnIlBBAnQiUkEEamwiACA+KAIMTQRAIAYgCH4gAn6nIUAgPigCECFDID4oAgQhQgJAAkACQCA+KAIADgMAAgECCyBCDQogQ0EAIAD8CwAMCgsgQg0JIAEoAsABIT1DAAAAACBEQQBMDQgaIERBA3EhPiBEQQRJBEBBACEADAgLIERBfHEhAUEAIQADQCDFAiBDIABBAnQiP2oqAgC7oCBDID9BBHJqKgIAu6AgQyA/QQhyaioCALugIEMgP0EMcmoqAgC7oCHFAiAAQQRqIQAgYUEEaiJhIAFHDQALDAcLIEAgRGpBAWsgRG0iACBCbCKAASAAIIABaiIAIEAgACBASBsiTk4NCCBQQXBxIj8gUEEPcSJMIFBBA3EiWWsiSWohPSBEQQJ0IlEgQkECdCIAQQRqIFBsaiFKIFBBfHEhASBQQX5xIUsgUEEBcSFHIFBBAWshWiAAIENqIU0gP0EBayJGQQR2QQFqIgBB/v///wFxIUggAEEBcSFFIEIgUGxBAnQhQQNAID4oAhAiRCBRaiBBaiFeIFMoAjQhQyBTKALAASFbAkAgUEEATCJCBEBEAAAAAAAAAAAhxQIMAQsgVygCwAEgVygCNCCAAWxqIVhDAACA/yGSAkEAIWlBACEAQQAhTyBaQQNPBEADQCCSAiBYIABBAnQiQGoqAgAikwIgkgIgkwJeGyKTAiBYIEBBBHJqKgIAIpICIJICIJMCXRsikwIgWCBAQQhyaioCACKSAiCSAiCTAl0bIpMCIFggQEEMcmoqAgAikgIgkgIgkwJdGyGSAiAAQQRqIQAgT0EEaiJPIAFHDQALCyBZBEADQCCSAiBYIABBAnRqKgIAIpMCIJICIJMCXhshkgIgAEEBaiEAIGlBAWoiaSBZRw0ACwtEAAAAAAAAAAAhxQJBACEAQQAhXCBaBEADQEMAAAAAIZQCAkAgWCAAQQJ0IkBqKgIAIpMCQwAAgP9bBEBDAAAAACGTAgwBCyDFAiCTAiCSApMQRSKTArugIcUCCyBAIF5qIJMCOAIAIFggAEEBckECdCJAaioCACKTAkMAAID/XARAIMUCIJMCIJICkxBFIpQCu6AhxQILIEAgXmoglAI4AgAgAEECaiEAIFxBAmoiXCBLRw0ACwsgR0UNAEMAAAAAIZQCIFggAEECdCIAaioCACKTAkMAAID/XARAIMUCIJMCIJICkxBFIpQCu6AhxQILIAAgXmoglAI4AgALRKGPdv///+8/IMUCo7YhkgICQCA/QQBMDQAgkgL9EyGlAkEAIQBBACFcIEZBD0cEQANAIF4gAEECdCJAaiJYIKUCIFj9AAAA/eYB/QsAACBYIKUCIFj9AAAQ/eYB/QsAECBYIKUCIFj9AAAg/eYB/QsAICBYIKUCIFj9AAAw/eYB/QsAMCBeIEBBwAByaiJAIKUCIED9AAAA/eYB/QsAACBAIKUCIED9AAAQ/eYB/QsAECBAIKUCIED9AAAg/eYB/QsAICBAIKUCIED9AAAw/eYB/QsAMCAAQSBqIQAgXEECaiJcIEhHDQALCyBFRQ0AIF4gAEECdGoiACClAiAA/QAAAP3mAf0LAAAgACClAiAA/QAAEP3mAf0LABAgACClAiAA/QAAIP3mAf0LACAgACClAiAA/QAAMP3mAf0LADALAkAgPyBQTg0AID8hACBMQQRPBEAgkgL9EyGlAkEAIQADQCBeIAAgP2pBAnRqIkAgQP0AAgAgpQL95gH9CwIAIABBBGoiACBJRw0ACyA9IQAgWUUNAQsDQCBeIABBAnRqIkAgQCoCACCSApQ4AgAgAEEBaiIAIFBHDQALCyBNIEIEfUMAAAAABUEAIQACQCBQQQRJIkJFBEADQCBeIABBAnRqIkAgQP0AAgD9DF9wiTBfcIkwX3CJMF9wiTD95AH9CwIAIABBBGoiACABRw0ACyABIgAgUEYNAQsDQCBeIABBAnRqIkAgQCoCAENfcIkwkjgCACAAQQFqIgAgUEcNAAsLIEMggAFsIUNBACEAAkAgQkUEQANAIF4gAEECdGoiQCBA/QACACKlAv0fABBX/RMgpQL9HwEQV/0gASClAv0fAhBX/SACIKUC/R8DEFf9IAP9CwIAIABBBGoiACABRw0ACyABIgAgUEYNAQsDQCBeIABBAnRqIkAgQCoCABBXOAIAIABBAWoiACBQRw0ACwsgQyBbaiFYQQAhXEEAIQACQAJAIFBBCEkNACBYIEQgSmpJIFIgW2ogQ2ogXktxDQADQCBeIABBAnQiQmoiQCBA/QACACBCIFhq/QACAP3mAf0LAgAgAEEEaiIAIAFHDQALIAEiACBQRg0BCyAAQX9zIFBqIZACIFkEQANAIF4gAEECdCJCaiJAIEAqAgAgQiBYaioCAJQ4AgAgAEEBaiEAIFxBAWoiXCBZRw0ACwsgkAJBAk0NAANAIF4gAEECdCJDaiJAIEAqAgAgQyBYaioCAJQ4AgAgXiBDQQRqIkJqIkAgQCoCACBCIFhqKgIAlDgCACBeIENBCGoiQmoiQCBAKgIAIEIgWGoqAgCUOAIAIF4gQ0EMaiJCaiJAIEAqAgAgQiBYaioCAJQ4AgAgAEEEaiIAIFBHDQALC0QAAAAAAAAAACHFAkEAIVxBACEAQQAhaSBaQQNPBEADQCDFAiBeIABBAnQiQGoqAgC7oCBeIEBBBHJqKgIAu6AgXiBAQQhyaioCALugIF4gQEEMcmoqAgC7oCHFAiAAQQRqIQAgaUEEaiJpIAFHDQALCyBZBEADQCDFAiBeIABBAnRqKgIAu6AhxQIgAEEBaiEAIFxBAWoiXCBZRw0ACwsgxQK2CyBNKgIAkjgCACBOIIABQQFqIoABRw0ACwwICyBWQbvVADYCCCBWQbDqADYCBCBWQccmNgIAQajCAigCACIAQaXjACBWEDAMEwsgVkGE2AA2AhggVkGl6gA2AhQgVkHHJjYCEEGowgIoAgAiAEGl4wAgVkEQahAwDBILIFZBi80ANgIoIFZBpOoANgIkIFZBxyY2AiBBqMICKAIAIgBBpeMAIFZBIGoQMAwRCyBWQbTXADYCOCBWQaPqADYCNCBWQccmNgIwQajCAigCACIAQaXjACBWQTBqEDAMEAsgVkHY2AA2AkggVkGi6gA2AkQgVkHHJjYCQEGowgIoAgAiAEGl4wAgVkFAaxAwDA8LIFZB/iA2AlggVkGT6wA2AlQgVkHHJjYCUEGowgIoAgAiAEGl4wAgVkHQAGoQMAwOCyA+BEADQCDFAiBDIABBAnRqKgIAu6AhxQIgAEEBaiEAIE9BAWoiTyA+Rw0ACwsgxQK2CyGSAiA9QwAAgL8gQLKVIJIClDgCAAsgVkHgAGokAAwDCyABKAKMASFYIAEoApABIVogASgClAEhPiABIT8jAEHgAGsiVyQAAkAgWCgCAEUEQAJAIAEoAjAiPSABKAIAQSRsIgFBmJoBaigCAEcNACA/NQI0IgMgPykDECIOID2tfiABQZSaAWo0AgB/Ug0AID81AjgiAiADID8pAxgiDH5SDQAgPzUCPCACID8pAyAiC35SDQACQCBYKAIwQQRHDQAgWDUCNCIDIFgpAxAiB0IChlINACBYNQI4IgIgAyBYKQMYIgl+Ug0AIFg1AjwgAiBYKQMgIgh+Ug0AAkAgWigCMCI9IFooAgBBJGwiAUGYmgFqKAIARw0AIFo1AjQiAyBaKQMQIgYgPa1+IAFBlJoBajQCAH9SDQAgWjUCOCICIAMgWikDGCIFflINACBaNQI8IAIgWikDICIEflINAAJAID4oAjAiPSA+KAIAQSRsIgFBmJoBaigCAEcNACA+NQI0IgMgPikDECA9rX4gAUGUmgFqNAIAf1INACA+NQI4IgIgPikDGCADflINACA+NQI8ID4pAyAgAn5SDQACQCAGIAdSDQAgBSAJUg0AIAQgCFINACAIIAtSDQAgCSAMUg0AIAcgDlINACBYKQMoIgIgWikDKFINACACID8pAyhSDQACQAJAIAAoAgAOAwEAAQALIAsgDH4gAn4iBCAANAIIIgJ8QgF9IAJ/IgIgADQCBH4iAyACIAN8IgIgBCACIARTGyIIWQ0AID4oAsABIUYgDqciWUFwcSI+IFlBD3EiWyBZQQNxIk1rIlJqIQEgDkJ+gyEGIA5CAYMhAiBZQXxxIT0gWUECdCFOID5BAWsiTEEEdkEBaiIAQf7///8BcSFJIABBAXEhUSAEtCGVAiBZQQFrQQNJIUgDQCBYKALAASADpyJKIFgoAjRsaiFEID8oAjQgSmwhS0MAAID/IZICAkAgWUEATCJFDQBBACFcQQAhXUEAIQAgSEUEQANAIJICIEQgXUECdCJAaioCACKTAiCSAiCTAl4bIpMCIEQgQEEEcmoqAgAikgIgkgIgkwJdGyKTAiBEIEBBCHJqKgIAIpICIJICIJMCXRsikwIgRCBAQQxyaioCACKSAiCSAiCTAl0bIZICIF1BBGohXSAAQQRqIgAgPUcNAAsLIE1FDQADQCCSAiBEIF1BAnRqKgIAIpMCIJICIJMCXhshkgIgXUEBaiFdIFxBAWoiXCBNRw0ACwsgWigCNCFDIFooAsABIUcgPygCwAEiQiBLaiFTAkAgDkIAVwRARAAAAAAAAAAAIcUCDAELRAAAAAAAAAAAIcUCQgAhBEIAIQUgDkIBUgRAA0BDAAAAACGUAgJAIEQgBKciQEECdCIAaioCACKTAkMAAID/WwRAQwAAAAAhkwIMAQsgxQIgkwIgkgKTEEUikwK7oCHFAgsgACBTaiCTAjgCACBEIEBBAXJBAnQiAGoqAgAikwJDAACA/1wEQCDFAiCTAiCSApMQRSKUArugIcUCCyAAIFNqIJQCOAIAIARCAnwhBCAFQgJ8IgUgBlINAAsLIAJQDQBDAAAAACGUAiBEIASnQQJ0IgBqKgIAIpMCQwAAgP9cBEAgxQIgkwIgkgKTEEUilAK7oCHFAgsgACBTaiCUAjgCAAtEoY92////7z8gxQKjtiGSAgJAID5BAEwiQQ0AIJIC/RMhpQJBACEAQQAhXCBMQQ9HBEADQCBTIABBAnQiQGoiRCClAiBE/QAAAP3mAf0LAAAgRCClAiBE/QAAEP3mAf0LABAgRCClAiBE/QAAIP3mAf0LACAgRCClAiBE/QAAMP3mAf0LADAgUyBAQcAAcmoiQCClAiBA/QAAAP3mAf0LAAAgQCClAiBA/QAAEP3mAf0LABAgQCClAiBA/QAAIP3mAf0LACAgQCClAiBA/QAAMP3mAf0LADAgAEEgaiEAIFxBAmoiXCBJRw0ACwsgUUUNACBTIABBAnRqIgAgpQIgAP0AAAD95gH9CwAAIAAgpQIgAP0AABD95gH9CwAQIAAgpQIgAP0AACD95gH9CwAgIAAgpQIgAP0AADD95gH9CwAwCwJAID4gWU4iRA0AID4hACBbQQRPBEAgkgL9EyGlAkEAIQADQCBTIAAgPmpBAnRqIkAgQP0AAgAgpQL95gH9CwIAIABBBGoiACBSRw0ACyABIQAgTUUNAQsDQCBTIABBAnRqIkAgQCoCACCSApQ4AgAgAEEBaiIAIFlHDQALCwJAIEUNACBDIEpsIUNBACEAAkAgWUEETwRAA0AgUyAAQQJ0aiJAIED9AAIA/QxfcIkwX3CJMF9wiTBfcIkw/eQB/QsCACAAQQRqIgAgPUcNAAsgWSA9IgBGDQELA0AgUyAAQQJ0aiJAIEAqAgBDX3CJMJI4AgAgAEEBaiIAIFlHDQALCyBDIEdqIUVBACFcQQAhAAJAIFlBCEkNACBFIEIgTmogS2pJIEcgTmogQ2ogU0txDQADQCBTIABBAnQiQmoiQCBA/QACACBCIEVq/QACAP3lAf0LAgAgAEEEaiIAID1HDQALIFkgPSIARg0BCyAAQX9zIFlqIZECIE0EQANAIFMgAEECdCJCaiJAIEAqAgAgQiBFaioCAJM4AgAgAEEBaiEAIFxBAWoiXCBNRw0ACwsgkQJBA0kNAANAIFMgAEECdCJDaiJAIEAqAgAgQyBFaioCAJM4AgAgUyBDQQRqIkJqIkAgQCoCACBCIEVqKgIAkzgCACBTIENBCGoiQmoiQCBAKgIAIEIgRWoqAgCTOAIAIFMgQ0EMaiJCaiJAIEAqAgAgQiBFaioCAJM4AgAgAEEEaiIAIFlHDQALCyBGKgIAIJUClSGSAgJAIEENACCSAv0TIaUCQQAhAEEAIVwgTEEPRwRAA0AgUyAAQQJ0IkBqIkIgpQIgQv0AAAD95gH9CwAAIEIgpQIgQv0AABD95gH9CwAQIEIgpQIgQv0AACD95gH9CwAgIEIgpQIgQv0AADD95gH9CwAwIFMgQEHAAHJqIkAgpQIgQP0AAAD95gH9CwAAIEAgpQIgQP0AABD95gH9CwAQIEAgpQIgQP0AACD95gH9CwAgIEAgpQIgQP0AADD95gH9CwAwIABBIGohACBcQQJqIlwgSUcNAAsLIFFFDQAgUyAAQQJ0aiIAIKUCIAD9AAAA/eYB/QsAACAAIKUCIAD9AAAQ/eYB/QsAECAAIKUCIAD9AAAg/eYB/QsAICAAIKUCIAD9AAAw/eYB/QsAMAsCQCBEDQAgPiEAIFtBBE8EQCCSAv0TIaUCQQAhAANAIFMgACA+akECdGoiQCClAiBA/QACAP3mAf0LAgAgAEEEaiIAIFJHDQALIAEhACBNRQ0BCwNAIFMgAEECdGoiQCCSAiBAKgIAlDgCACAAQQFqIgAgWUcNAAsLIANCAXwiAyAIUg0ACwsgV0HgAGokAAwGCyBXQf7NADYCCCBXQaTrADYCBCBXQccmNgIAQajCAigCACIAQaXjACBXEDAMEAsgV0Gk2AA2AhggV0Gj6wA2AhQgV0HHJjYCEEGowgIoAgAiAEGl4wAgV0EQahAwDA8LIFdBtNcANgIoIFdBousANgIkIFdBxyY2AiBBqMICKAIAIgBBpeMAIFdBIGoQMAwOCyBXQdjYADYCOCBXQaHrADYCNCBXQccmNgIwQajCAigCACIAQaXjACBXQTBqEDAMDQsgV0GaywA2AkggV0Gg6wA2AkQgV0HHJjYCQEGowgIoAgAiAEGl4wAgV0FAaxAwDAwLIFdB/iA2AlggV0GB7AA2AlQgV0HHJjYCUEGowgIoAgAiAEGl4wAgV0HQAGoQMAwLCwwCCyCEAUH+IDYCGCCEAUHF7gA2AhQghAFBxyY2AhBBqMICKAIAIgBBpeMAIIQBQRBqEDAMCQsgACABKAKMASABEPYCCyCEAUFAayQADwsghAFBxRA2AggghAFBiewANgIEIIQBQccmNgIAQajCAigCACIAQaXjACCEARAwDAYLIIQBQf89NgIoIIQBQeDtADYCJCCEAUHHJjYCIEGowgIoAgAiAEGl4wAghAFBIGoQMAwFCyCEAUH/PTYCOCCEAUHr7QA2AjQghAFBxyY2AjBBqMICKAIAIgBBpeMAIIQBQTBqEDAMBAsgVEHHJjYCAEGowgIoAgAiAEGl4wAgVBAwDAMLIElBxyY2AgBBqMICKAIAIgBBpeMAIEkQMAwCCyBPQccmNgIAQajCAigCACIAQaXjACBPEDAMAQsgPUHHJjYCAEGowgIoAgAiAEGl4wAgPRAwCyAAEDMaDAMLIGEQMxoMAgsgARAzGgwBCyA9EDMaC0GswgIoAgAQMxpBARAAAAuIAQEBfyAALQALQQd2BH8gACgCCEH/////B3FBAWsFQQoLIgMgAk8EQAJ/IAAtAAtBB3YEQCAAKAIADAELIAALIgMgASAC/AoAACAAIAMgAhCcAw8LIAAgAyACIANrAn8gAC0AC0EHdgRAIAAoAgQMAQsgAC0AC0H/AHELIgBBACAAIAIgARDNAQuIAwEFfyMAQRBrIggkACACIAFBf3NB7////wdqTQRAAn8gAC0AC0EHdgRAIAAoAgAMAQsgAAshCiAIQQRqIgkgACABQef///8DSQR/IAggAUEBdDYCDCAIIAEgAmo2AgQjAEEQayICJAAgCSgCACAIQQxqIgsoAgBJIQwgAkEQaiQAIAsgCSAMGygCACICQQtPBH8gAkEQakFwcSICIAJBAWsiAiACQQtGGwVBCgtBAWoFQe////8HCxDDASAIKAIEIQIgCCgCCBogBARAIAIgCiAEEHgLIAYEQCACIARqIAcgBhB4CyADIAQgBWoiCWshByADIAlHBEAgAiAEaiAGaiAEIApqIAVqIAcQeAsgAUEBaiIBQQtHBEAgACAKIAEQ8QELIAAgAjYCACAAIAAoAghBgICAgHhxIAgoAghB/////wdxcjYCCCAAIAAoAghBgICAgHhyNgIIIAAgBCAGaiAHaiIANgIEIAhBADoADCAAIAJqIAgtAAw6AAAgCEEQaiQADwsQTQALCwAgBCACNgIAQQML7AICBX8BfgJ/IwBBMGsiAyQAAkACQAJAIAIpAxBCAVINACACKQMYQgFSDQAgAikDIEIBUg0AIAIpAyhCAVINACABKAIwIAEoAgAiBEEkbEGYmgFqKAIARw0BIAE1AjgiCCABKQMYIAE1AjR+Ug0BIAE1AjwgASkDICAIflINAQJ/AkAgASgCiAENACACKAKIAQ0AQQAMAQtBAQshByAAIAQgASgCDCABQRBqQQBBABBKIgRBGTYCQCAHBEAgACAEKAIAIAQoAgwgBEEQakEAQQAQSiEFCyAEIAE2AowBIAQgBTYCiAEgBCACNgKQASADQTBqJAAgBAwDCyADQZTWADYCKCADQf0fNgIkIANBxyY2AiBBqMICKAIAIgBBpeMAIANBIGoQMAwBCyADQYTXADYCGCADQf4fNgIUIANBxyY2AhBBqMICKAIAIgBBpeMAIANBEGoQMAsgABAzGkGswgIoAgAQMxpBARAAAAsLeAECfyMAQRBrIgMkACADQQxqIgQgASgCHCIBNgIAIAFBBGpBAf4eAgAaIAIgBBC/ASIBIAEoAgAoAhARAQA2AgAgACABIAEoAgAoAhQRAgAgBCgCACIAQQRqQX/+HgIARQRAIAAgACgCACgCCBEAAAsgA0EQaiQAC3ABAn8jAEEQayICJAAgAkEMaiIDIAAoAhwiADYCACAAQQRqQQH+HgIAGiADEG0iAEHA6QJB2ukCIAEgACgCACgCMBEIABogAygCACIAQQRqQX/+HgIARQRAIAAgACgCACgCCBEAAAsgAkEQaiQAIAELeAECfyMAQRBrIgMkACADQQxqIgQgASgCHCIBNgIAIAFBBGpBAf4eAgAaIAIgBBDBASIBIAEoAgAoAhARAQA6AAAgACABIAEoAgAoAhQRAgAgBCgCACIAQQRqQX/+HgIARQRAIAAgACgCACgCCBEAAAsgA0EQaiQACwsAIAAQmgQgABAvCykAAkAgACgCAEEATg0AIABB/////wf+HgIAQYGAgIB4Rg0AIAAQjAELC0cBAn8CQCACKAJMQQBIBEAgACABIAIQzwIhAAwBCyACEIABIQQgACABIAIQzwIhACAERQ0AIAIQfwsgACABRgRAIAEPCyAAC48CAgF/AnwgAEEDcQR/QWQFRAAAAAAAAAAAENcBIwZFBEACfxADIQVBAEEAIAD+SALg7zQaAkAQAyIEIAUgAqAiAmQNAAJ/A0BBACAAQQAgAEEA/kgC4O80IgMgACADRhtFDQEaIAQQ1wEgASAA/hACAEYEQEEAQQAgAP5IAuDvNBoQAyIEIAJkDQMMAQsLQXoLDAELQQAgAEEA/kgC4O80GkG3fwsPCyACRAAAAAAAAPB/YiEDQXpBt39BACAAIAECfiACRAAAAAAAQI9AokQAAAAAAECPQKIiAplEAAAAAAAA4ENjBEAgArAMAQtCgICAgICAgICAfwtCfyADG/4BAgAiAEECRhsgAEEBRhsLCyUAAkAjBQRAQdzvNP4QAgANARDYBgsPC0Hc7zT+EAIAECgQJwALsgEDAnwBfwF+IwEiAy0ACEUEQCADECk6AAkgA0EBOgAICyAAAn4CfCMBLQAJBEAQAwwBCyMDQRxqQRw2AgAPCyIBRAAAAAAAQI9AoyICmUQAAAAAAADgQ2MEQCACsAwBC0KAgICAgICAgIB/CyIENwMAIAACfyABIARC6Ad+uaFEAAAAAABAj0CiRAAAAAAAQI9AoiIBmUQAAAAAAADgQWMEQCABqgwBC0GAgICAeAs2AggLygQCAn8CfCMAQRBrIQQgAisDACEGAn8CQCABKwMAIgcgACsDAGRFBEBBACAGIAdkRQ0CGiAEIAH9AAMA/QsDACABIAIoAgg2AgggASACKQMANwMAIAIgBCgCCDYCCCACIAQpAwA3AwBBASABKwMAIAArAwBkRQ0CGiAEIAD9AAMA/QsDACAAIAEoAgg2AgggACABKQMANwMAIAEgBCgCCDYCCCABIAQpAwA3AwAMAQsgBiAHZARAIAQgAP0AAwD9CwMAIAAgAigCCDYCCCAAIAIpAwA3AwAgAiAEKAIINgIIIAIgBCkDADcDAEEBDAILIAQgAP0AAwD9CwMAIAAgASgCCDYCCCAAIAEpAwA3AwAgASAEKAIINgIIIAEgBCkDADcDAEEBIAIrAwAgASsDAGRFDQEaIAQgAf0AAwD9CwMAIAEgAigCCDYCCCABIAIpAwA3AwAgAiAEKAIINgIIIAIgBCkDADcDAAtBAgshBSADKwMAIAIrAwBkBH8gBCAC/QADAP0LAwAgAiADKAIINgIIIAIgAykDADcDACADIAQoAgg2AgggAyAEKQMANwMAIAIrAwAgASsDAGRFBEAgBUEBag8LIAQgAf0AAwD9CwMAIAEgAigCCDYCCCABIAIpAwA3AwAgAiAEKAIINgIIIAIgBCkDADcDACABKwMAIAArAwBkRQRAIAVBAmoPCyAEIAD9AAMA/QsDACAAIAEoAgg2AgggACABKQMANwMAIAEgBCgCCDYCCCABIAQpAwA3AwAgBUEDagUgBQsLpwMBC38CQAJAIAAoAgQiAyAAKAIARwRAIAMhAgwBCyAAKAIIIgQgACgCDCICSQRAIAQgAiAEa0ECdUEBakECbUECdCIGaiAEIANrIgVrIgIgAyAF/AoAACAAIAI2AgQgACAAKAIIIAZqNgIIDAELQQEgAiADa0EBdSACIANGGyIFQYCAgIAETw0BIAVBAnQiAhAxIgcgAmohDCAHIAVBA2oiCEF8cWoiAiEJAkAgAyAERg0AIAIgBCADayIEQXxxaiEJIAIhBiADIQUCQCAEQQRrIgRBHEkNACAIQXxxIAdqIANrQRBJDQAgAyAEQQJ2QQFqIghB/P///wdxIgpBAnQiBmohBSACIAZqIQYDQCACIAtBAnQiBGogAyAEav0AAgD9CwIAIAtBBGoiCyAKRw0ACyAIIApGDQELA0AgBiAFKAIANgIAIAVBBGohBSAGQQRqIgYgCUcNAAsLIAAgDDYCDCAAIAk2AgggACACNgIEIAAgBzYCACADRQ0AIAMQLyAAKAIEIQILIAJBBGsgASgCADYCACAAIAAoAgRBBGs2AgQPCxBIAAu8EAENfyAAKAIAIQsgACgCBCIDKAIIIQACQCABIggoAhgiASADKAIETQRAIAFBA3QhAiABQQJ0IQQMAQsgAARAIAAQLwsgAygCDCIABEAgABAvCyABQQJ0IgQQOyEAIAMgATYCBCADIAA2AgggAyABQQN0IgIQOzYCDAsgAEEAIAT8CwAgAygCDEEAIAL8CwAgAyALNgIAQQAhACMAQaABayIEJAAgAygCHCEHIAMoAhghCiAIKAIEIgFBAEoEQANAAkAgCCgCDCAAQQJ0aigCACIBKAK4ASICRQ0AIAQgAykCBDcDmAEgBEGYAWogAhBYIQIgAygCDCACQQN0aiICIAIoAgRBAWo2AgQgASgCCA0AIAEoAsABRQ0AIAMgARCQAQsCQCABKAKMASICRQ0AIAQgAykCBDcDkAEgBEGQAWogAhBYIQUgAygCDCAFQQN0aiIFIAUoAgBBAWo2AgACQCACKAK4AUUNACACKAIIDQAgAigCwAFFDQAgAyACEJABCyABKAKQASICRQ0AIAQgAykCBDcDiAEgBEGIAWogAhBYIQUgAygCDCAFQQN0aiIFIAUoAgBBAWo2AgACQCACKAK4AUUNACACKAIIDQAgAigCwAFFDQAgAyACEJABCyABKAKUASICRQ0AIAQgAykCBDcDgAEgBEGAAWogAhBYIQUgAygCDCAFQQN0aiIFIAUoAgBBAWo2AgACQCACKAK4AUUNACACKAIIDQAgAigCwAFFDQAgAyACEJABCyABKAKYASICRQ0AIAQgAykCBDcDeCAEQfgAaiACEFghBSADKAIMIAVBA3RqIgUgBSgCAEEBajYCAAJAIAIoArgBRQ0AIAIoAggNACACKALAAUUNACADIAIQkAELIAEoApwBIgJFDQAgBCADKQIENwNwIARB8ABqIAIQWCEFIAMoAgwgBUEDdGoiBSAFKAIAQQFqNgIAAkAgAigCuAFFDQAgAigCCA0AIAIoAsABRQ0AIAMgAhCQAQsgASgCoAEiAUUNACAEIAMpAgQ3A2ggBEHoAGogARBYIQIgAygCDCACQQN0aiICIAIoAgBBAWo2AgAgASgCuAFFDQAgASgCCA0AIAEoAsABRQ0AIAMgARCQAQsgAEEBaiIAIAgoAgQiAUgNAAsLIAcgASAHGyINQQBKBEBBACEAA0AgACEBIA0CfwJAIAcEQCAKIABBAnRqKAIAIgFBf0YNAQsCQCAIKAIMIAFBAnRqKAIAIgEoAowBIgJFDQAgAyACELcBIAEoApABIgJFDQAgAyACELcBIAEoApQBIgJFDQAgAyACELcBIAEoApgBIgJFDQAgAyACELcBIAEoApwBIgJFDQAgAyACELcBIAEoAqABIgJFDQAgAyACELcBCyADIAEQtwEgB0UNACAKIABBAnRqKAIAQX9GDQAgAEEBagwBCyAJIAAgBxsiASAAIABBAWoiDCAHGyIOSARAA0ACQCAIKAIMIAcEfyAKIAFBAnRqKAIABSABC0ECdGooAgAiBSgCjAEiAEUNACAEIAMpAgQ3A2AgBEHgAGogABBYIQIgAygCDCACQQN0aiICIAIoAgBBAWsiBjYCAAJAIAYNACACKAIEDQAgACgCuAEiAgRAIAQgAykCBDcDWCAEQdgAaiACEFghACADKAIMIABBA3RqIgYgBigCBEEBayIANgIEIAANASACIQAgBigCAA0BCyADIAAQygELIAUoApABIgBFDQAgBCADKQIENwNQIARB0ABqIAAQWCECIAMoAgwgAkEDdGoiAiACKAIAQQFrIgY2AgACQCAGDQAgAigCBA0AIAAoArgBIgIEQCAEIAMpAgQ3A0ggBEHIAGogAhBYIQAgAygCDCAAQQN0aiIGIAYoAgRBAWsiADYCBCAADQEgAiEAIAYoAgANAQsgAyAAEMoBCyAFKAKUASIARQ0AIAQgAykCBDcDQCAEQUBrIAAQWCECIAMoAgwgAkEDdGoiAiACKAIAQQFrIgY2AgACQCAGDQAgAigCBA0AIAAoArgBIgIEQCAEIAMpAgQ3AzggBEE4aiACEFghACADKAIMIABBA3RqIgYgBigCBEEBayIANgIEIAANASACIQAgBigCAA0BCyADIAAQygELIAUoApgBIgBFDQAgBCADKQIENwMwIARBMGogABBYIQIgAygCDCACQQN0aiICIAIoAgBBAWsiBjYCAAJAIAYNACACKAIEDQAgACgCuAEiAgRAIAQgAykCBDcDKCAEQShqIAIQWCEAIAMoAgwgAEEDdGoiBiAGKAIEQQFrIgA2AgQgAA0BIAIhACAGKAIADQELIAMgABDKAQsgBSgCnAEiAEUNACAEIAMpAgQ3AyAgBEEgaiAAEFghAiADKAIMIAJBA3RqIgIgAigCAEEBayIGNgIAAkAgBg0AIAIoAgQNACAAKAK4ASICBEAgBCADKQIENwMYIARBGGogAhBYIQAgAygCDCAAQQN0aiIGIAYoAgRBAWsiADYCBCAADQEgAiEAIAYoAgANAQsgAyAAEMoBCyAFKAKgASIARQ0AIAQgAykCBDcDECAEQRBqIAAQWCECIAMoAgwgAkEDdGoiAiACKAIAQQFrIgU2AgAgBQ0AIAIoAgQNACAAKAK4ASICBEAgBCADKQIENwMIIARBCGogAhBYIQAgAygCDCAAQQN0aiIFIAUoAgRBAWsiADYCBCAADQEgAiEAIAUoAgANAQsgAyAAEMoBCyABQQFqIgEgDkcNAAsLIAwgCSAHGyEJIAwLIgBHDQALCyAEQaABaiQAIANBADYCACALKAKUEBoLSQECfyAAKAIEIgVBCHUhBiAAKAIAIgAgASAFQQFxBH8gBiACKAIAaigCAAUgBgsgAmogA0ECIAVBAnEbIAQgACgCACgCGBELAAsZAQF/IAAoAgAiAQRAIAEQiAULIAEQLyAAC3sBAX8jAEEQayIDJAACQCACQQpNBEAgACAALQALQYABcSACcjoACyAAIAAtAAtB/wBxOgALIAAgASACEHggA0EAOgAPIAAgAmogAy0ADzoAAAwBCyAAQQogAkEKayAALQALQf8AcSIAQQAgACACIAEQzQELIANBEGokAAt4AQJ/IwBBEGsiBCQAAkAgAiAAKAIIQf////8HcSIDSQRAIAAoAgAhAyAAIAI2AgQgAyABIAIQeCAEQQA6AA8gAiADaiAELQAPOgAADAELIAAgA0EBayACIANrQQFqIAAoAgQiAEEAIAAgAiABEM0BCyAEQRBqJAALCQAgACABEJsDC1EBAX8jAEEgayIIJAAgCCADNwMIIAggAjcDACAIIAQ3AxAgACABQQMgCCAHEKwCIgAgBKcgBmw2AjwgACAGNgI4IAAgBTYCNCAIQSBqJAAgAAuOAwIHfwN+IwBB0ABrIgUkAAJAAkACQCABKAIwIgYgASgCACIIQSRsIgdBmJoBaigCAEcNACABNQI0IgwgASkDECIOIAatfiAHQZSaAWo0AgB/Ug0AIAE1AjgiDSAMIAEpAxgiDH5SDQAgATUCPCANIAEpAyAiDX5SDQAgASkDKCAMIA5+IA1+fiACIAN+IAR+Ug0BIAEoAogBIQsgBSAENwNAIAUgAzcDOCAFIAI3AzBBACEHIAAgCEEDIAVBMGogAUEAEEohCiAFIAFBxAFqNgIAIApBpNQAIAUQdCIGQR02AkAgCwRAIAAgBigCACAGKAIMIAZBEGpBAEEAEEohBwsgBiABNgKMASAGIAc2AogBIAVB0ABqJAAgBg8LIAVB19YANgIoIAVByiI2AiQgBUHHJjYCIEGowgIoAgAiAEGl4wAgBUEgahAwDAELIAVBtzo2AhggBUHLIjYCFCAFQccmNgIQQajCAigCACIAQaXjACAFQRBqEDALIAAQMxpBrMICKAIAEDMaQQEQAAALBABBBAuCAwIHfwN+IwBBQGoiBCQAAkACQAJAIAEoAjAiBSABKAIAIgdBJGwiBkGYmgFqKAIARw0AIAE1AjQiCyABKQMQIg0gBa1+IAZBlJoBajQCAH9SDQAgATUCOCIMIAsgASkDGCILflINACABNQI8IAwgASkDICIMflINACABKQMoIAsgDX4gDH5+IAIgA35SDQEgASgCiAEhCiAEIAM3AzggBCACNwMwQQAhBiAAIAdBAiAEQTBqIAFBABBKIQkgBCABQcQBajYCACAJQaTUACAEEHQiBUEdNgJAIAoEQCAAIAUoAgAgBSgCDCAFQRBqQQBBABBKIQYLIAUgATYCjAEgBSAGNgKIASAEQUBrJAAgBQ8LIARB19YANgIoIARBsCI2AiQgBEHHJjYCIEGowgIoAgAiAEGl4wAgBEEgahAwDAELIARB+zw2AhggBEGxIjYCFCAEQccmNgIQQajCAigCACIAQaXjACAEQRBqEDALIAAQMxpBrMICKAIAEDMaQQEQAAALpAEBAX8CQEHciDX+EgAAQQFxDQBB3Ig1EFRFDQACQEHQiDX+EgAAQQFxDQBB0Ig1EFRFDQAQ0gVByIg1QbiVNTYCAEHMiDVByIg1NgIAQdCINRBTC0HUiDVBzIg1KAIAKAIAIgE2AgAgAUEEakEB/h4CABpB2Ig1QdSINTYCAEHciDUQUwsgAEHYiDUoAgAoAgAiATYCACABQQRqQQH+HgIAGiAAC18BBH8gASgCiAEhBSAAIAEoAgAgASgCDCABQRBqQQBBABBKIgJCuYCAgPAANwNAIAUEQCAAIAIoAgAgAigCDCACQRBqQQBBABBKIQMLIAIgATYCjAEgAiADNgKIASACC0cBAX8jAEEQayICJAACQCABLQALQQd2RQRAIAAgASgCCDYCCCAAIAEpAgA3AgAMAQsgACABKAIAIAEoAgQQbAsgAkEQaiQACwgAQf////8HCwUAQf8AC3YBAX8jAEEQayICJAAgAiAANgIMAkAgACABRg0AA0AgAiABQQRrIgE2AgggACABTw0BIAIoAgwiACgCACEBIAAgAigCCCIAKAIANgIAIAAgATYCACACIAIoAgxBBGoiADYCDCACKAIIIQEMAAsACyACQRBqJAAL9gQBCH8jAEEQayILJAAgBhBtIQkgC0EEaiIHIAYQvwEiCCAIKAIAKAIUEQIAAkACfyAHLQALQQd2BEAgBygCBAwBCyAHLQALQf8AcQtFBEAgCSAAIAIgAyAJKAIAKAIwEQgAGiAFIAMgAiAAa0ECdGoiBjYCAAwBCyAFIAM2AgACQAJAIAAiCi0AACIGQStrDgMAAQABCyAJIAbAIAkoAgAoAiwRBAAhByAFIAUoAgAiBkEEajYCACAGIAc2AgAgAEEBaiEKCwJAIAIgCmtBAkgNACAKLQAAQTBHDQAgCi0AAUEgckH4AEcNACAJQTAgCSgCACgCLBEEACEHIAUgBSgCACIGQQRqNgIAIAYgBzYCACAJIAosAAEgCSgCACgCLBEEACEHIAUgBSgCACIGQQRqNgIAIAYgBzYCACAKQQJqIQoLIAogAhCtASAIIAgoAgAoAhARAQAhDkEAIQcgCiEGA38gAiAGTQR/IAMgCiAAa0ECdGogBSgCABDqASAFKAIABQJAAn8gC0EEaiIILQALQQd2BEAgCCgCAAwBCyAICyAHai0AAEUNACAMAn8gCC0AC0EHdgRAIAgoAgAMAQsgCAsgB2osAABHDQAgBSAFKAIAIg1BBGo2AgAgDSAONgIAIAcgBwJ/IAgtAAtBB3YEQCAIKAIEDAELIAgtAAtB/wBxC0EBa0lqIQdBACEMCyAJIAYsAAAgCSgCACgCLBEEACENIAUgBSgCACIIQQRqNgIAIAggDTYCACAGQQFqIQYgDEEBaiEMDAELCyEGCyAEIAYgAyABIABrQQJ0aiABIAJGGzYCACALQQRqEDIaIAtBEGokAAvQAQECfyACQYAQcQRAIABBKzoAACAAQQFqIQALIAJBgAhxBEAgAEEjOgAAIABBAWohAAsgAkGEAnEiA0GEAkcEQCAAQa7UADsAACAAQQJqIQALIAJBgIABcSECA0AgAS0AACIEBEAgACAEOgAAIABBAWohACABQQFqIQEMAQsLIAACfwJAIANBgAJHBEAgA0EERw0BQcYAQeYAIAIbDAILQcUAQeUAIAIbDAELQcEAQeEAIAIbIANBhAJGDQAaQccAQecAIAIbCzoAACADQYQCRwvtBAEIfyMAQRBrIgskACAGEHMhCSALQQRqIgcgBhDBASIIIAgoAgAoAhQRAgACQAJ/IActAAtBB3YEQCAHKAIEDAELIActAAtB/wBxC0UEQCAJIAAgAiADIAkoAgAoAiARCAAaIAUgAyACIABraiIGNgIADAELIAUgAzYCAAJAAkAgACIKLQAAIgZBK2sOAwABAAELIAkgBsAgCSgCACgCHBEEACEHIAUgBSgCACIGQQFqNgIAIAYgBzoAACAAQQFqIQoLAkAgAiAKa0ECSA0AIAotAABBMEcNACAKLQABQSByQfgARw0AIAlBMCAJKAIAKAIcEQQAIQcgBSAFKAIAIgZBAWo2AgAgBiAHOgAAIAkgCiwAASAJKAIAKAIcEQQAIQcgBSAFKAIAIgZBAWo2AgAgBiAHOgAAIApBAmohCgsgCiACEK0BIAggCCgCACgCEBEBACEOQQAhByAKIQYDfyACIAZNBH8gAyAKIABraiAFKAIAEK0BIAUoAgAFAkACfyALQQRqIggtAAtBB3YEQCAIKAIADAELIAgLIAdqLQAARQ0AIAwCfyAILQALQQd2BEAgCCgCAAwBCyAICyAHaiwAAEcNACAFIAUoAgAiDUEBajYCACANIA46AAAgByAHAn8gCC0AC0EHdgRAIAgoAgQMAQsgCC0AC0H/AHELQQFrSWohB0EAIQwLIAkgBiwAACAJKAIAKAIcEQQAIQ0gBSAFKAIAIghBAWo2AgAgCCANOgAAIAZBAWohBiAMQQFqIQwMAQsLIQYLIAQgBiADIAEgAGtqIAEgAkYbNgIAIAtBBGoQMhogC0EQaiQAC+0FAQt/IwBBgAFrIgkkACAJIAE2AnwgCUH1ATYCECAJQQhqQQAgCUEQaiIIEFEhCwJAAkAgAyACa0EMbSIKQeUATwRAIAoQOyIIRQ0BIAsoAgAhASALIAg2AgAgAQRAIAEgCygCBBEAAAsLIAghByACIQEDQCABIANGBEADQCAAIAlB/ABqEEJBASAKGwRAIAAgCUH8AGoQQgRAIAUgBSgCAEECcjYCAAsMBQsCfyAAKAIAIgcoAgwiASAHKAIQRgRAIAcgBygCACgCJBEBAAwBCyABKAIACyEOIAZFBEAgBCAOIAQoAgAoAhwRBAAhDgsgD0EBaiENQQAhECAIIQcgAiEBA0AgASADRgRAIA0hDyAQRQ0CIAAQXRogCCEHIAIhASAKIAxqQQJJDQIDQCABIANGBEAMBAUCQCAHLQAAQQJHDQACfyABLQALQQd2BEAgASgCBAwBCyABLQALQf8AcQsgD0YNACAHQQA6AAAgDEEBayEMCyAHQQFqIQcgAUEMaiEBDAELAAsABQJAIActAABBAUcNAAJ/IAEtAAtBB3YEQCABKAIADAELIAELIA9BAnRqKAIAIRECQCAGBH8gEQUgBCARIAQoAgAoAhwRBAALIA5GBEBBASEQAn8gAS0AC0EHdgRAIAEoAgQMAQsgAS0AC0H/AHELIA1HDQIgB0ECOgAAIAxBAWohDAwBCyAHQQA6AAALIApBAWshCgsgB0EBaiEHIAFBDGohAQwBCwALAAsABSAHQQJBAQJ/IAEtAAtBB3YEQCABKAIEDAELIAEtAAtB/wBxC0UiDRs6AAAgB0EBaiEHIAFBDGohASAMIA1qIQwgCiANayEKDAELAAsACxBHAAsCQAJAA0AgAiADRg0BIAgtAABBAkcEQCAIQQFqIQggAkEMaiECDAELCyACIQMMAQsgBSAFKAIAQQRyNgIACyALKAIAIQAgC0EANgIAIAAEQCAAIAsoAgQRAAALIAlBgAFqJAAgAwv0BQELfyMAQYABayIJJAAgCSABNgJ8IAlB9QE2AhAgCUEIakEAIAlBEGoiCBBRIQsCQAJAIAMgAmtBDG0iCkHlAE8EQCAKEDsiCEUNASALKAIAIQEgCyAINgIAIAEEQCABIAsoAgQRAAALCyAIIQcgAiEBA0AgASADRgRAA0AgACAJQfwAahBDQQEgChsEQCAAIAlB/ABqEEMEQCAFIAUoAgBBAnI2AgALDAULAn8gACgCACIHKAIMIgEgBygCEEYEQCAHIAcoAgAoAiQRAQAMAQsgAS0AAAvAIQ4gBkUEQCAEIA4gBCgCACgCDBEEACEOCyAPQQFqIQ1BACEQIAghByACIQEDQCABIANGBEAgDSEPIBBFDQIgABBeGiAIIQcgAiEBIAogDGpBAkkNAgNAIAEgA0YEQAwEBQJAIActAABBAkcNAAJ/IAEtAAtBB3YEQCABKAIEDAELIAEtAAtB/wBxCyAPRg0AIAdBADoAACAMQQFrIQwLIAdBAWohByABQQxqIQEMAQsACwAFAkAgBy0AAEEBRw0AAn8gAS0AC0EHdgRAIAEoAgAMAQsgAQsgD2otAAAhEQJAIA5B/wFxIAYEfyARBSAEIBHAIAQoAgAoAgwRBAALQf8BcUYEQEEBIRACfyABLQALQQd2BEAgASgCBAwBCyABLQALQf8AcQsgDUcNAiAHQQI6AAAgDEEBaiEMDAELIAdBADoAAAsgCkEBayEKCyAHQQFqIQcgAUEMaiEBDAELAAsACwAFIAdBAkEBAn8gAS0AC0EHdgRAIAEoAgQMAQsgAS0AC0H/AHELRSINGzoAACAHQQFqIQcgAUEMaiEBIAwgDWohDCAKIA1rIQoMAQsACwALEEcACwJAAkADQCACIANGDQEgCC0AAEECRwRAIAhBAWohCCACQQxqIQIMAQsLIAIhAwwBCyAFIAUoAgBBBHI2AgALIAsoAgAhACALQQA2AgAgAARAIAAgCygCBBEAAAsgCUGAAWokACADC74CAQR/IANB2IY1IAMbIgUoAgAhAwJAAn8CQCABRQRAIAMNAUEADwtBfiACRQ0BGgJAIAMEQCACIQQMAQsgAS0AACIDwCIEQQBOBEAgAARAIAAgAzYCAAsgBEEARw8LIwMoAmAoAgBFBEBBASAARQ0DGiAAIARB/78DcTYCAEEBDwsgA0HCAWsiA0EySw0BIANBAnRBoM4CaigCACEDIAJBAWsiBEUNAyABQQFqIQELIAEtAAAiBkEDdiIHQRBrIANBGnUgB2pyQQdLDQADQCAEQQFrIQQgBkGAAWsgA0EGdHIiA0EATgRAIAVBADYCACAABEAgACADNgIACyACIARrDwsgBEUNAyABQQFqIgEtAAAiBkHAAXFBgAFGDQALCyAFQQA2AgAjA0EcakEZNgIAQX8LDwsgBSADNgIAQX4LCQAgAUEBEPQDC3EBAX8gAEHExwI2AgAgABD3AxoCQCAALQBgRQ0AIAAoAiAiAUUNACABEC8LAkAgAC0AYUUNACAAKAI4IgFFDQAgARAvCyAAQdTGAjYCACAAKAIEIgFBBGpBf/4eAgBFBEAgASABKAIAKAIIEQAACyAACw8AIAAgACgCECABchC8Agu2CwEGfyAAIAFqIQUCQAJAIAAoAgQiAkEBcQ0AIAJBA3FFDQEgACgCACICIAFqIQECQAJAAkAgACACayIAQeSCNSgCAEcEQCACQf8BTQRAIAJBA3YhBCAAKAIIIgMgACgCDCICRw0CQdCCNUHQgjUoAgBBfiAEd3E2AgAMBQsgACgCGCEGIAAgACgCDCICRwRAQeCCNSgCABogACgCCCIDIAI2AgwgAiADNgIIDAQLIABBFGoiBCgCACIDRQRAIAAoAhAiA0UNAyAAQRBqIQQLA0AgBCEHIAMiAkEUaiIEKAIAIgMNACACQRBqIQQgAigCECIDDQALIAdBADYCAAwDCyAFKAIEIgJBA3FBA0cNA0HYgjUgATYCACAFIAJBfnE2AgQgACABQQFyNgIEIAUgATYCAA8LIAMgAjYCDCACIAM2AggMAgtBACECCyAGRQ0AAkAgACgCHCIDQQJ0QYCFNWoiBCgCACAARgRAIAQgAjYCACACDQFB1II1QdSCNSgCAEF+IAN3cTYCAAwCCyAGQRBBFCAGKAIQIABGG2ogAjYCACACRQ0BCyACIAY2AhggACgCECIDBEAgAiADNgIQIAMgAjYCGAsgACgCFCIDRQ0AIAIgAzYCFCADIAI2AhgLAkACQAJAAkAgBSgCBCICQQJxRQRAQeiCNSgCACAFRgRAQeiCNSAANgIAQdyCNUHcgjUoAgAgAWoiATYCACAAIAFBAXI2AgQgAEHkgjUoAgBHDQZB2II1QQA2AgBB5II1QQA2AgAPC0HkgjUoAgAgBUYEQEHkgjUgADYCAEHYgjVB2II1KAIAIAFqIgE2AgAgACABQQFyNgIEIAAgAWogATYCAA8LIAJBeHEgAWohASACQf8BTQRAIAJBA3YhBCAFKAIMIgIgBSgCCCIDRgRAQdCCNUHQgjUoAgBBfiAEd3E2AgAMBQsgAyACNgIMIAIgAzYCCAwECyAFKAIYIQYgBSAFKAIMIgJHBEBB4II1KAIAGiAFKAIIIgMgAjYCDCACIAM2AggMAwsgBUEUaiIEKAIAIgNFBEAgBSgCECIDRQ0CIAVBEGohBAsDQCAEIQcgAyICQRRqIgQoAgAiAw0AIAJBEGohBCACKAIQIgMNAAsgB0EANgIADAILIAUgAkF+cTYCBCAAIAFBAXI2AgQgACABaiABNgIADAMLQQAhAgsgBkUNAAJAIAUoAhwiA0ECdEGAhTVqIgQoAgAgBUYEQCAEIAI2AgAgAg0BQdSCNUHUgjUoAgBBfiADd3E2AgAMAgsgBkEQQRQgBigCECAFRhtqIAI2AgAgAkUNAQsgAiAGNgIYIAUoAhAiAwRAIAIgAzYCECADIAI2AhgLIAUoAhQiA0UNACACIAM2AhQgAyACNgIYCyAAIAFBAXI2AgQgACABaiABNgIAIABB5II1KAIARw0AQdiCNSABNgIADwsgAUH/AU0EQCABQXhxQfiCNWohAgJ/QdCCNSgCACIDQQEgAUEDdnQiAXFFBEBB0II1IAEgA3I2AgAgAgwBCyACKAIICyEBIAIgADYCCCABIAA2AgwgACACNgIMIAAgATYCCA8LQR8hAyABQf///wdNBEAgAUEmIAFBCHZnIgJrdkEBcSACQQF0a0E+aiEDCyAAIAM2AhwgAEIANwIQIANBAnRBgIU1aiECAkACQEHUgjUoAgAiBEEBIAN0IgdxRQRAQdSCNSAEIAdyNgIAIAIgADYCACAAIAI2AhgMAQsgAUEZIANBAXZrQQAgA0EfRxt0IQMgAigCACECA0AgAiIEKAIEQXhxIAFGDQIgA0EddiECIANBAXQhAyAEIAJBBHFqIgdBEGooAgAiAg0ACyAHIAA2AhAgACAENgIYCyAAIAA2AgwgACAANgIIDwsgBCgCCCIBIAA2AgwgBCAANgIIIABBADYCGCAAIAQ2AgwgACABNgIICwuQAwEGfyAALQAAQQ9xRQRAIABBBGpBAEEK/kgCAEEKcQ8LAn8gACgCACECAkACQAJAIwMiASgCGCIEIAAoAgQiA0H/////A3EiBkcNAAJAIAJBCHFFDQAgACgCFEEATg0AIABBADYCFCADQYCAgIAEcSEDDAILIAJBA3FBAUcNAEEGIQUgACgCFCIBQf7///8HSw0CIAAgAUEBajYCFEEADAMLQTghBSAGQf////8DRg0BAkAgBg0AQQAgAyACQQRxGw0AIAMgAEEEaiADIAJBgAFxBH8gASgCUEUEQCABQXQ2AlALIAAoAgghBiABIABBEGo2AlQgBEGAgICAeHIgBCAGGwUgBAsgA0GAgICABHFy/kgCAEYNASABQQA2AlQgAkEMcUEMRw0AIAAoAggNAgtBCgwCCyABKAJMIQIgACABQcwAaiIFNgIMIAAgAjYCECAAQRBqIQQgAiAFRwRAIAJBBGsgBDYCAAsgASAENgJMQQAhBSABQQA2AlQgA0UNACAAQQA2AhRBPgwBCyAFCwubBQEFfyMAQTBrIgUkAAJAIABFBEBBHCEEDAELQejxNCgCAEUEQEHo8TRBKzYCAAtB6e80LQAARQRAEPwBKAIAIgMEQANAAkAgA0UNACADKAJMQQBODQAgA0EANgJMCyADKAI4IgMNAAsLQaTxNBDUAQJAQeTvNCgCACIDRQ0AIAMoAkxBAE4NACADQQA2AkwLAkBBmLoDKAIAIgNFDQAgAygCTEEATg0AIANBADYCTAsCQEGAuQMoAgAiA0UNACADKAJMQQBODQAgA0EANgJMC0Hp7zRBAToAAAsgBUEIakEAQSj8CwAgBUHotwMoAgAiAzYCBEHstwMoAgBBmgFqIgRBACADQQ9qIAUoAgwbaiIGEDsiA0EAIAQQoQEgAyAGNgIwIAMgAzYCLCADIAM2AgBB6PE0QejxNCgCACIEQQFqNgIAIAMgA0HMAGo2AkwgAyAENgIYIANBiPA0NgJgIANBA0ECIAUoAhAbNgIgIAMgBSgCBCIGNgI4IAMgA0GHAWpBfHEiBDYCdCAEQRBqIQRB7LcDKAIABEAgAyAEQQNqQXxxIgQ2AkhB7LcDKAIAIARqIQQLIAMgBSgCDCIHIAQgBmpBD2pBcHEgBxs2AjQgAxCMBCMDIQQQywIgBCgCDCEGIAMgBDYCCCADIAY2AgwgBiADNgIIIAMoAgggAzYCDBDKAkHs7zRB7O80KAIAIgRBAWo2AgAgBEUEQEHr7zRBAToAAAsgAyAFQQRqIAEgAhAgIgQEQEHs7zRB7O80KAIAQQFrIgA2AgAgAEUEQEHr7zRBADoAAAsQywIgAygCDCIAIAMoAgg2AgggAygCCCAANgIMIAMgAzYCDCADIAM2AggQygIMAQsgACADNgIACyAFQTBqJAAgBAsVACAAQQD+QQIAQQJGBEAgABCMAQsLMgAgAEEAQQH+SAIABEAgAEEBQQL+SAIAGgNAIABBAEECEKIBIABBAEEC/kgCAA0ACwsL5wECAn8DfCMAQRBrIgIkAAJAAn8CQAJAIwUiAw0AIwMiBC0AKEEBRw0AIAQtAClFDQELQQFB5AAgAxu3IQUQA0QAAAAAAADwf6AhByMDIQMDQAJAIAMoAiRFBEAgBxADoSIGRAAAAAAAAAAAZUUNAUHJAAwEC0ELIQAMBAsgACABIAUgBiAFIAZjGxDWASIEQbd/Rg0AC0EAIARrDAELQQAgACABRAAAAAAAAPB/ENYBawsiAEEAIABBb3FBC0YbIAAgAEHJAEcbIgBBG0cNAEEbQQBB2PE0KAIAGyEACyACQRBqJAAgAAsNACAAQf////8HELQBC64EAQV/IwBBEGsiBCQAIAAQVhoCfwJAIAAgARCcBCIDRQRAIAAoAhwiAyAAKAIgRgRAIAAoAhggA0EBdEEBIAMbIgNBAnQQxAEiBUUNAiAAIAM2AiAgACAFNgIYCyABEKEEIgNFDQEgACAAKAIcIgFBAWo2AhwgACgCGCABQQJ0aiADNgIACyADDAELQQALIQEgABBSGiABBH8gBCACKAIINgIIIAQgAikCADcDACMAQTBrIgIkAAJAAn8gASIAKAIcIgP+EAJ8IQEDQEEAIAFFDQEaIAEgAyABIAFBAWr+SAJ8IgFHDQALQQELRQRAQQAhAwwBCyAAQQRqIgEQVhogAiAEKAIINgIgIAIgBCkCADcDGCAAIAJBGGoQnQQhAyABEFIaAn8gAwR/IABBAv5BAgAhBUEBIQMgACgCHCIBIAVBAkYNARogAiAANgIsIAIgADYCECACQb0BNgIoIAJBvgE2AiQgAiACKQIkNwMIIwBBEGsiAyQAIAEoAnhBBGoQVhogASgCeCEGIAMgAigCEDYCCCADIAIpAgg3AwAgBiADEJ0EGiABKAJ4QQRqEFIaAkAgASgCeEEC/kECAEECRg0AIAH+EAKAAQRAIAFBf/4AAgAaDAELIAEjA0Gg8DQQHwsgA0EQaiQAQQEFQQALIQMgACgCHAsiAEEB/iUCfEEBRgRAIABB/ABqQf////8HELQBCwsgAkEwaiQAIAMFQQALIQcgBEEQaiQAIAcLDQBBpPE0EKYEQajxNAvuAQMCfAJ/AX4CfQJAIAC8IgNBFHZB/w9xIgRBsAhJDQBDAAAAACADQYCAgHxGDQEaIARB+A9PBEAgACAAkg8LIABDAAAAAF4EQCMAQRBrIgNDAAAAcDgCDCADKgIMQwAAAHCUDwsgAEMAABbDX0UNACMAQRBrIgNDAAAAEDgCDCADKgIMQwAAABCUDwtByNkBKwMAIAC7IgEgAUHA2QErAwAiAaAiAiABoaEiAaJB0NkBKwMAoCABIAGiokHY2QErAwAgAaJEAAAAAAAA8D+goCACvSIFQi+GIAWnQR9xQQN0QcDXAWopAwB8v6K2CwsUAEEMEGBBBRBxQcCoA0HRABACAAsUAEEMEGBBBBBxQcCoA0HRABACAAsUAEEMEGBBAxBxQcCoA0HRABACAAulBAEEfwJAAkACQCAAKAIEIAAoAgAiAmtBNG0iBUEBaiIDQcWdsSdJBEBBxJ2xJyAAKAIIIAJrQTRtIgJBAXQiBCADIAMgBEkbIAJB4s7YE08bIgMEfyADQcWdsSdPDQIgA0E0bBAxBUEACyIEIAVBNGxqIgIgAf0AAgD9CwIAIAIgAf0AAhD9CwIQIAIgASgCIDYCICACIAEoAiQ2AiQgAUIANwIgIAH9DAAAAAAAAAAAAAAAAAAAAAD9CwIQIAIgAS0AMDoAMCACIAEpAig3AiggBCADQTRsaiEDIAJBNGohBSAAKAIEIgEgACgCACIERg0CA0AgAkE0ayICIAFBNGsiAf0AAgD9CwIAIAJBADYCGCACIAEoAhA2AhAgAiABKAIUNgIUIAIgASgCGDYCGCABQQA2AhggAUIANwIQIAJBADYCJCACIAEoAhw2AhwgAiABKAIgNgIgIAIgASgCJDYCJCABQQA2AiQgAUIANwIcIAIgAS0AMDoAMCACIAEpAig3AiggASAERw0ACyAAIAM2AgggACgCBCEDIAAgBTYCBCAAKAIAIQEgACACNgIAIAEgA0YNAwNAIANBNGsiACgCHCICBEAgA0EUayACNgIAIAIQLwsgA0EkaygCACICBEAgA0EgayACNgIAIAIQLwsgACIDIAFHDQALDAMLEDYACxBIAAsgACADNgIIIAAgBTYCBCAAIAI2AgALIAEEQCABEC8LC6kFAQh/IAEgACgCCCIDIAAoAgAiBGtBDG1NBEACQCAAKAIEIgUgBGtBDG0iCCABIAEgCEsbIgdFDQAgBCEDIAchBiAHQQNxIgkEQANAIAMgAigCADYCACADIAIoAgQ2AgQgAyACLQAIOgAIIAZBAWshBiADQQxqIQMgCkEBaiIKIAlHDQALCyAHQQRJDQADQCADIAIoAgA2AgAgAyACKAIENgIEIAMgAi0ACDoACCADIAIoAgA2AgwgAyACKAIENgIQIAMgAi0ACDoAFCADIAIoAgA2AhggAyACKAIENgIcIAMgAi0ACDoAICADIAIoAgA2AiQgAyACKAIENgIoIAMgAi0ACDoALCADQTBqIQMgBkEEayIGDQALCyABIAhLBEAgBSABIAhrQQxsaiEBA0AgBSACKQIANwIAIAUgAigCCDYCCCAFQQxqIgUgAUcNAAsgACABNgIEDwsgACAEIAFBDGxqNgIEDwsgBARAIAAgBDYCBCAEEC8gAEEANgIIIABCADcCAEEAIQMLAkAgAUHWqtWqAU8NAEHVqtWqASADQQxtIgNBAXQiBCABIAEgBEkbIANBqtWq1QBPGyIDQdaq1aoBTw0AIAAgA0EMbCIDEDEiBDYCBCAAIAQ2AgAgACADIARqNgIIIAQhAyABQQxsIgFBDGsiBkEMbkEBakEDcSIHBEADQCADIAIpAgA3AgAgAyACKAIINgIIIANBDGohAyAFQQFqIgUgB0cNAAsLIAEgBGohASAGQSRPBEADQCADIAIpAgA3AgAgAyACKAIINgIIIAMgAigCCDYCFCADIAIpAgA3AgwgAyACKAIINgIgIAMgAikCADcCGCADIAIpAgA3AiQgAyACKAIINgIsIANBMGoiAyABRw0ACwsgACABNgIEDwsQNgALFABBDBBgQQYQcUHAqANB0QAQAgALAgAL/QcBB38gACgCECEHIAAoAiQhCAJAIAIgASIDRg0AAkACQCADLAAAIgRBJGsOWQIBAQECAAICAQECAQEBAQEBAQEBAQEBAQEBAQIBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQECAgECAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQICAQsgACgCGA0BCyAAIAQQWiADQQFqIQMLAkACQAJAAkACQCABIANHDQACfwJAIAIgASIDRg0AIANBAWoiBSACRg0AIAMtAABB3ABHDQACQAJAIAUsAAAiBEEkaw5aAAEBAQAAAAABAQABAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAQsgACAEEFogA0ECagwCCyAAKAIMQfAHcUHAAEYEQCAAIAUgAkEAENgCDAILIANBAkEAAn9BACEFAkACQCAEQXhxQTBHIARB/gFxQThHcQ0AIARB/wFxIgRBMWtBCEsNACAEQTBrIgQgACgCEEsNASAAIAQQ2wJBASEFCyAFDAELEP8BAAsbaiEDCyADCyIDIAFHDQACQCABIAJGDQAgAS0AAEEuRw0AQQgQMSEDIAAoAiQiBCgCBCEFIANBlLQBNgIAIAMgBTYCBCAEIAM2AgQMAgsgACABIAIQ4wIhAwsCQAJAIAEgA0cNACACIANGDQACQAJAIAEsAAAiA0Ekaw4FAwYGBgEACyADQd4ARw0FQQwQMSEDIAAoAgwhBCAAKAIkIgUoAgQhBiADQeSoATYCACADIAY2AgQgAyAEQfAPcUGADEY6AAggBSADNgIEDAMLAkAgAC0ADEECcQRAIAAoAhAhBAwBC0EMEDEhAyAAIAAoAhBBAWoiBDYCECAAKAIkIgUoAgQhBiADIAQ2AgggA0GwsAE2AgAgAyAGNgIEIAUgAzYCBCAAIAAoAiQoAgQ2AiQLIAAgACgCGEEBajYCGCAAIAFBAWogAhCGAiIFIAJGDQUgBS0AAEEpRw0FIAAtAAxBAnFFBEBBDBAxIQMgACgCJCIGKAIEIQkgAyAENgIIIANBgLEBNgIAIAMgCTYCBCAGIAM2AgQgACAAKAIkKAIENgIkCyAAIAAoAhhBAWs2AhggBUEBaiEDCyABIANHDQIMAwtBDBAxIQMgACgCDCEEIAAoAiQiBSgCBCEGIANBrKkBNgIAIAMgBjYCBCADIARB8A9xQYAMRjoACCAFIAM2AgQLIAAgACgCJCgCBDYCJCABQQFqIQMLIAAgAyACIAggB0EBaiAAKAIQQQFqEOQCIQELIAEPCxCDAgALsQIBBH8gACgCJCEGAkAgACABIAIQhQIiAyABRg0AA0AgACADIgQgAhCFAiIDIARHDQALIAEgBEYNACACIARHBEADQCAELQAAQfwARwRAIAQPCyAAKAIkIQUgACAEQQFqIgEgAhCFAiIDIAFGDQIDQCAAIAMiBCACEIUCIgMgBEcNAAsgASAERg0CQQwQMSEDIAYoAgQhASADIAUoAgQ2AgggAyABNgIEIANBjLMBNgIAIAYgAzYCBCAFQQA2AgRBCBAxIQMgACgCJCgCBCEBIANBuKcBNgIAIAMgATYCBCAFIAM2AgQgACgCJEEANgIEQQgQMSEDIAUoAgQhASADQcyzATYCACADIAE2AgQgACgCJCADNgIEIAAgBSgCBDYCJCACIARHDQALCyACDwsQxgQAC64CAQR/IAAoAgAiAwRAIAMhAiADIAAoAgQiBEcEQANAIARBDGsiAigCACIFBEAgBEEIayAFNgIAIAUQLwsgAiIEIANHDQALIAAoAgAhAgsgACADNgIEIAIQLyAAQQA2AgggAEIANwIACyAAIAEoAgA2AgAgACABKAIENgIEIAAgASgCCDYCCCABQQA2AgggAUIANwIAIAAoAgwiAwRAIAMhAiADIAAoAhAiBEcEQANAIARBDGsiAigCACIFBEAgBEEIayAFNgIAIAUQLwsgAiIEIANHDQALIAAoAgwhAgsgACADNgIQIAIQLyAAQQA2AhQgAEIANwIMCyAAIAEoAgw2AgwgACABKAIQNgIQIAAgASgCFDYCFCABQQA2AhQgAUIANwIMIAAgASkCGDcCGAvwAQIEfwF+IwBBQGoiAiQAIAIgAULA/BV/IgY+AgAgAiAGQoCjpH5+IAFCCn58IgFC4NQDfyIGPgIEIAIgBkKgq3x+IAF8IgFC6Ad/IgY+AgggAiAGQpj4//8PfiABfD4CECACQffJADYCDCACQSBqIgRBIEG+JSACEMYCGiAEEGkiA0Hw////B0kEQAJAIANBCk0EQCAAIAM6AAsMAQsgA0EPckEBaiIFEDEhBCAAIAVBgICAgHhyNgIIIAAgBDYCACAAIAM2AgQgBCEACyAAIAJBIGogA/wKAAAgACADakEAOgAAIAJBQGskAA8LEE0AC+tBBBl/BX0DfAF+IwBBgAFrIgYkAAJAAkAgACgCAEEB/h4CACIUIAAoAgQoAgBIBEAgBkHcAGohESAGQdAAaiESA0ACQCAAKAIIKAIAIBRB2BRsaiIILQCxAg0AIAgtALACDQACQAJAAkACQAJAAkAgACgCDCIBKAIADgIAAQYLIAAoAhQoAgAiCygC/AEhAiALKALAASEKIAAoAhAqAgBDvTeGNV1FDQFEAAAAAAAAAAAhH0EAIQRBACEDRAAAAAAAAAAAISAgAiAKTg0DIAogAmsiAUEBcSELIAgoArQCIQcgAkEBaiAKRgRAIAIhAQwDCyABQX5xIQwgAiEBQQAhBQNAAn8CQCAHIAFBAnRqKgIAIhpDAACA/1sNACAgIBq7IiGgISAgHyAhY0UNACABDAELIB8hISADCyEJAkAgByABQQFqIgNBAnRqKgIAIhpDAACA/1wEQCAgIBq7Ih+gISAgHyAhZA0BCyAJIQMgISEfCyABQQJqIQEgDCAFQQJqIgVHDQALDAILIAEoAnQhDQJAIAAoAhQoAgAiEygCwAEiDCAIKALcAiICIAgoAtgCIgRrQQR1IgFLBEBBACEKQQAhBwJAIAwgAWsiASAIKALgAiIFIAJrQQR1TQRAAkAgAUUNACACIQMgAUEHcSIEBEBBACEFA0AgA0EANgIIIANCADcDACADQRBqIQMgBUEBaiIFIARHDQALCyABQQR0IAJqIQIgAUEBa0H/////AHFBB0kNAANAIANCADcDcCADQgA3A2AgA0IANwNQIANCADcDQCADQgA3AzAgA0IANwMgIANCADcDECADQQA2AgggA0IANwMAIANBADYCeCADQQA2AmggA0EANgJYIANBADYCSCADQQA2AjggA0EANgIoIANBADYCGCADQYABaiIDIAJHDQALCyAIIAI2AtwCDAELAkAgAiAIKALYAiIEa0EEdSILIAFqIgNBgICAgAFJBEBB/////wAgBSAEayIFQQN1IgkgAyADIAlJGyAFQfD///8HTxsiCQRAIAlBgICAgAFPDQIgCUEEdBAxIQcLIAcgC0EEdGoiBSEDIAFBB3EiCwRAA0AgA0EANgIIIANCADcDACADQRBqIQMgCkEBaiIKIAtHDQALCyABQQR0IAVqIQogAUEBa0H/////AHFBB08EQANAIANCADcDcCADQgA3A2AgA0IANwNQIANCADcDQCADQgA3AzAgA0IANwMgIANCADcDECADQQA2AgggA0IANwMAIANBADYCeCADQQA2AmggA0EANgJYIANBADYCSCADQQA2AjggA0EANgIoIANBADYCGCADQYABaiIDIApHDQALCyACIARHBEADQCAFQRBrIgUgAkEQayICKQMANwMAIAUgAigCCDYCCCACIARHDQALCyAIIAcgCUEEdGo2AuACIAggCjYC3AIgCCgC2AIhASAIIAU2AtgCIAEEQCABEC8LDAILDAwLEEgACyAIKALYAiEEDAELIAEgDE0NACAIIAQgDEEEdGo2AtwCCwJAIAxBAEwNACAIKALAAiECQQAhASAMQQFHBEAgDEF+cSEFQQAhCwNAIAIgAUECdGoqAgAhGiAEIAFBBHRqIgMgATYCCCADIBq7OQMAIAIgAUEBciIDQQJ0aioCACEaIAQgA0EEdGoiCSADNgIIIAkgGrs5AwAgAUECaiEBIAtBAmoiCyAFRw0ACwsgDEEBcUUNACACIAFBAnRqKgIAIRogBCABQQR0aiICIAE2AgggAiAauzkDAAsgBgJ/IA1FBEBBACEJQQAMAQsgBCANQQR0Ig5qIQcgCCgC3AIhECAOQQR1IQ8CQCAOQRFIIhUNACAPQQJrQQF2IgohASAOQSBJDQADQAJAIAogASIJSA0AIAQgAUEEdGohAyAEIAFBAXQiAkEBciIFQQR0aiEBAkAgDyACQQJqIgJMBEAgBSECDAELIAErAwAgASsDEGRFBEAgBSECDAELIAFBEGohAQsgAysDACIfIAErAwBjDQAgAygCCCELA0ACQCADIgUgASIDKQMANwMAIAUgASgCCDYCCCACIApKDQAgBCACQQF0IgJBAXIiBUEEdGohAQJAIA8gAkECaiICTARAIAUhAgwBCyABKwMAIAErAxBkRQRAIAUhAgwBCyABQRBqIQELIAErAwAgH2RFDQELCyADIAs2AgggAyAfOQMACyAJQQFrIQEgCUEASg0ACwsCQCAHIBBGDQAgByEBIA5BH0oEQCAEQSBqIQsgBEEQaiEJIA9BAmtBAXYh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QYCAAgwHC0GAgAQMBgtB/////wcMBQsQGgwECxAZQRB2DAMLQQAMAgsgASEACyAACyIAQQAgAEEAShsLIwEBfwJAIAAoAgAiAQRAIAEQkwRFDQELEEcACyAAQQA2AgALHQAgACABQcCEPW4iABCqASABIABBwIQ9bGsQoAILHQAgACABQZDOAG4iABCqASABIABBkM4AbGsQoQILGwAgACABQeQAbiIAEKoBIAEgAEHkAGxrEKoBC/sBAQN/IwBBEGsiAiQAIAIgATYCDAJAAkACfyAALQALIgNBB3YiBEUEQEEBIQEgA0H/AHEMAQsgACgCCEH/////B3FBAWshASAAKAIECyIDIAFGBEAgACABQQEgASABEIYDAn8gAC0AC0EHdgRAIAAoAgAMAQtBAAsaDAELAn8gAC0AC0EHdgRAIAAoAgAMAQtBAAsaIAQNACAAIgEgA0EBaiAALQALQYABcXI6AAsgACAALQALQf8AcToACwwBCyAAKAIAIQEgACADQQFqNgIECyABIANBAnRqIgAgAigCDDYCACACQQA2AgggACACKAIINgIEIAJBEGokAAv4AQEDfyMAQRBrIgIkACACIAE6AA8CQAJAAn8gAC0ACyIDQQd2IgRFBEBBCiEBIANB/wBxDAELIAAoAghB/////wdxQQFrIQEgACgCBAsiAyABRgRAIAAgAUEBIAEgARCmAgJ/IAAtAAtBB3YEQCAAKAIADAELQQALGgwBCwJ/IAAtAAtBB3YEQCAAKAIADAELQQALGiAEDQAgACIBIANBAWogAC0AC0GAAXFyOgALIAAgAC0AC0H/AHE6AAsMAQsgACgCACEBIAAgA0EBajYCBAsgASADaiIAIAItAA86AAAgAkEAOgAOIAAgAi0ADjoAASACQRBqJAALWgEEfyABKAKIASEFIAAgASgCACABKAIMIAFBEGpBAEEAEEoiAkEmNgJAIAUEQCAAIAIoAgAgAigCDCACQRBqQQBBABBKIQMLIAIgATYCjAEgAiADNgKIASACCz0BAX8jAEEQayIDJAAgAyACOgAPA0AgAQRAIAAgAy0ADzoAACABQQFrIQEgAEEBaiEADAELCyADQRBqJAALwwIBBX8jAEEQayIFJAAgAkHv////ByABa00EQAJ/IAAtAAtBB3YEQCAAKAIADAELIAALIQYgBUEEaiIH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IAEgAzYCDCAEIAIgAyACayIC/AoAACABIAIgBGo2AgggACABKAIMNgIAIAAgASgCCDYCBCABQRBqJAALNgEBfyMAQRBrIgMkACADIAE2AgwgAyACNgIIIAAgAygCDDYCACAAIAMoAgg2AgQgA0EQaiQACzsBAX8gAEHgyQIoAgAiATYCACAAIAFBDGsoAgBqQezJAigCADYCACAAQQhqEPIBGiAAQewAahDBAiAACwwAIABBCGoQwQIgAAsIACAAELsCGgvSAwICfgJ/IwBBIGsiBCQAAkAgAUL///////////8AgyIDQoCAgICAgMCAPH0gA0KAgICAgIDA/8MAfVQEQCABQgSGIABCPIiEIQMgAEL//////////w+DIgBCgYCAgICAgIAIWgRAIANCgYCAgICAgIDAAHwhAgwCCyADQoCAgICAgICAQH0hAiAAQoCAgICAgICACFINASACIANCAYN8IQIMAQsgAFAgA0KAgICAgIDA//8AVCADQoCAgICAgMD//wBRG0UEQCABQgSGIABCPIiEQv////////8Dg0KAgICAgICA/P8AhCECDAELQoCAgICAgID4/wAhAiADQv///////7//wwBWDQBCACECIANCMIinIgVBkfcASQ0AIARBEGogACABQv///////z+DQoCAgICAgMAAhCICIAVBgfcAaxBnIAQgACACQYH4ACAFaxCwASAEKQMIQgSGIAQpAwAiAEI8iIQhAiAEKQMQIAQpAxiEQgBSrSAAQv//////////D4OEIgBCgYCAgICAgIAIWgRAIAJCAXwhAgwBCyAAQoCAgICAgICACFINACACQgGDIAJ8IQILIARBIGokACACIAFCgICAgICAgICAf4OEvwuIAgACQCAABH8gAUH/AE0NAQJAIwMoAmAoAgBFBEAgAUGAf3FBgL8DRg0DDAELIAFB/w9NBEAgACABQT9xQYABcjoAASAAIAFBBnZBwAFyOgAAQQIPCyABQYBAcUGAwANHIAFBgLADT3FFBEAgACABQT9xQYABcjoAAiAAIAFBDHZB4AFyOgAAIAAgAUEGdkE/cUGAAXI6AAFBAw8LIAFBgIAEa0H//z9NBEAgACABQT9xQYABcjoAAyAAIAFBEnZB8AFyOgAAIAAgAUEGdkE/cUGAAXI6AAIgACABQQx2QT9xQYABcjoAAUEE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Ig1B/w9xIg9BvghrIhBB/35LIAC9IghCNIinIgtB/w9rQYJwT3ENACAJQgGGIgpCgICAgICAgBB8QoGAgICAgIAQVARARAAAAAAAAPA/IQIgCEKAgICAgICA+D9RDQIgClANAiAKQoGAgICAgIBwVCAIQgGGIghCgICAgICAgHBYcUUEQCAAIAGgIQIMAwsgCEKAgICAgICA8P8AUQ0CRAAAAAAAAAAAIAEgAaIgCEL/////////7/8AViAJQgBZcxshAgwCCyAIQgGGQoCAgICAgIAQfEKBgICAgICAEFQEQCAAIACiIQIgCEIAUwRAIAKaIAIgCRCkBEEBRhshAgsgCUIAWQ0CIwBBEGsiC0QAAAAAAADwPyACozkDCCALKwMIIQIMAgsgCEIAUwRAIAkQpAQiDEUEQCAAIAChIgAgAKMhAgwDCyALQf8PcSELIAxBAUZBEnQhDCAIQv///////////wCDIQgLIBBB/35NBEBEAAAAAAAA8D8hAiAIQoCAgICAgID4P1ENAiAPQb0HTQRAIAEgAZogCEKAgICAgICA+D9WG0QAAAAAAADwP6AhAgwDCyANQYAQSSAIQoGAgICAgID4P1RHBEAjAEEQayILRAAAAAAAAABwOQMIIAsrAwhEAAAAAAAAAHCiIQIMAwsjAEEQayILRAAAAAAAAAAQOQMIIAsrAwhEAAAAAAAAABCiIQIMAgsgCw0AIABEAAAAAAAAMEOivUL///////////8Ag0KAgICAgICAoAN9IQgLAnwgCUKAgIBAg78iBSEHIA4gCEKAgICA0Kql8z99IglCNIentyIDQcCfAisDAKIgCUItiKdB/wBxQQV0IgtBmKACaisDAKAgCCAJQoCAgICAgIB4g30iCEKAgICACHxCgICAgHCDvyIAIAtBgKACaisDACIEokQAAAAAAADwv6AiAiAIvyAAoSAEoiIEoCIAIANBuJ8CKwMAoiALQZCgAmorAwCgIgMgACADoCIDoaCgIAQgAEHInwIrAwAiBKIiBiACIASiIgSgoqAgAiAEoiICIAMgAyACoCICoaCgIAAgACAGoiIDoiADIAMgAEH4nwIrAwCiQfCfAisDAKCiIABB6J8CKwMAokHgnwIrAwCgoKIgAEHYnwIrAwCiQdCfAisDAKCgoqAiACACIAIgAKAiAqGgOQMIIAcgAr1CgICAQIO/IgOiIQAgASAFoSADoiAOKwMIIAIgA6GgIAGioCEBAkAgAL1CNIinQf8PcSILQckHa0E/SQ0AIAtByQdJBEAgAEQAAAAAAADwP6AiAJogACAMGwwCCyALQYkISSERQQAhCyARDQAgAL1CAFMEQCMAQRBrIgtEAAAAAAAAAJBEAAAAAAAAABAgDBs5AwggCysDCEQAAAAAAAAAEKIMAgsjAEEQayILRAAAAAAAAADwRAAAAAAAAABwIAwbOQMIIAsrAwhEAAAAAAAAAHCiDAELQYjaASsDACAAokGQ2gErAwAiAqAiAyACoSICQaDaASsDAKIgAkGY2gErAwCiIACgoCABoCIAIACiIgEgAaIgAEHA2gErAwCiQbjaASsDAKCiIAEgAEGw2gErAwCiQajaASsDAKCiIAO9IgmnQQR0QfAPcSINQfjaAWorAwAgAKCgoCEAIA1BgNsBaikDACAJIAytfEIthnwhCCALRQRAAnwgCUKAgICACINQBEAgCEKAgICAgICAiD99vyIBIACiIAGgRAAAAAAAAAB/ogwBCyAIQoCAgICAgIDwP3wiCL8iASAAoiIDIAGgIgCZRAAAAAAAAPA/YwR8IwBBEGsiCyESIAtEAAAAAAAAEAA5AwggEiALKwMIRAAAAAAAABAAojkDCCAIQoCAgICAgICAgH+DvyAARAAAAAAAAPC/RAAAAAAAAPA/IABEAAAAAAAAAABjGyICoCIFIAMgASAAoaAgACACIAWhoKCgIAKhIgAgAEQAAAAAAAAAAGEbBSAAC0QAAAAAAAAQAKILDAELIAi/IgEgAKIgAaALIQILIA5BEGokACACC8EBAQN/AkAgASACKAIQIgMEfyADBSACENMCDQEgAigCEAsgAigCFCIFa0sEQCACIAAgASACKAIkEQMADwsCQCACKAJQQQBIBEBBACEDDAELIAEhBANAIAQiA0UEQEEAIQMMAgsgACADQQFrIgRqLQAAQQpHDQALIAIgACADIAIoAiQRAwAiBCADSQ0BIAAgA2ohACABIANrIQEgAigCFCEFCyAFIAAgARB6GiACIAIoAhQgAWo2AhQgASADaiEECyAECzYBAn8gACgCTEEASARAIAAgASACEKkEDwsgABCAASEEIAAgASACEKkEIQIgBARAIAAQfwsgAgt8AQJ/IAAgACgCSCIBQQFrIAFyNgJIIAAoAhQgACgCHEcEQCAAQQBBACAAKAIkEQMAGgsgAEEANgIcIABCADcDECAAKAIAIgFBBHEEQCAAIAFBIHI2AgBBfw8LIAAgACgCLCAAKAIwaiICNgIIIAAgAjYCBCABQRt0QR91C40BAQJ/IwBBEGsiACQAIABBCjoADwJAAkBBmLkDKAIAIgEEfyABBUGIuQMQ0wINAkGYuQMoAgALQZy5AygCACIBRg0AQdi5AygCAEEKRg0AQZy5AyABQQFqNgIAIAFBCjoAAAwBC0GIuQMgAEEPakEBQay5AygCABEDAEEBRw0AIAAtAA8aCyAAQRBqJAALWQEBfyAAIAAoAkgiAUEBayABcjYCSCAAKAIAIgFBCHEEQCAAIAFBIHI2AgBBfw8LIABCADcCBCAAIAAoAiwiATYCHCAAIAE2AhQgACABIAAoAjBqNgIQQQAL0wECAX8CfCACKwMgIQUCfwJAIAErAyAiBiAAKwMgZEUEQEEAIAUgBmRFDQIaIAEgAhA+QQEgASsDICAAKwMgZEUNAhogACABED4MAQsgBSAGZARAIAAgAhA+QQEMAgsgACABED5BASACKwMgIAErAyBkRQ0BGiABIAIQPgtBAgshBCADKwMgIAIrAyBkBH8gAiADED4gAisDICABKwMgZEUEQCAEQQFqDwsgASACED4gASsDICAAKwMgZEUEQCAEQQJqDwsgACABED4gBEEDagUgBAsLfgEBfyAAIAEgAiADENQCIQUgBCsDICADKwMgZAR/IAMgBBA+IAMrAyAgAisDIGRFBEAgBUEBag8LIAIgAxA+IAIrAyAgASsDIGRFBEAgBUECag8LIAEgAhA+IAErAyAgACsDIGRFBEAgBUEDag8LIAAgARA+IAVBBGoFIAULC0gBAX8gAEGwsgE2AgAgACgCCCIBBEAgASABKAIAKAIEEQAACyAAQcyoATYCACAAKAIEIgEEQCABIAEoAgAoAgQRAAALIAAQLwuLCQEKfwJAAkACQAJAAkACQCAALQBZBEAgACgCDCIDIAEgAygCACgCFBEEACEFIAAoAgwiASACIAEoAgAoAhQRBAAhCCAAKAI8IgMgAEFAaygCACIESQRAIAMgBUH/AXEgCEEIdHI7AAAMBwsgAyAAKAI4IgFrIgJBfUwNAkH/////ByAEIAFrIgQgAkEBdSIJQQFqIgcgBCAHSxsgBEH+////B08bIgcEfyAHQQBIDQQgB0EBdBAxBUEACyEGIAYgCUEBdGoiBCAFQf8BcSAIQQh0cjsAACAEQQJqIQggASADRwRAAkACQCACQQJrIgVBHkkNACADIAJBfnEgBmprQRBJDQAgBEEQayEJIANBEGshCiAEIAVBAXZBAWoiC0F4cSIFQQF0IgJrIQQgAyACayEDQQAhAgNAIAkgAkEBdCIMayAKIAxr/QAAAP0LAAAgAkEIaiICIAVHDQALIAUgC0YNAQsDQCAEQQJrIgQgA0ECayIDLwAAOwAAIAEgA0cNAAsLIAAoAjghAwsgACAGIAdBAXRqNgJAIAAgCDYCPCAAIAQ2AjggA0UNASADEC8PCyAAQUBrKAIAIQQgACgCPCEDAkAgAC0AWgRAIAMgBEkNBiADIAAoAjgiB2siBkF9TA0FQf////8HIAQgB2siBCAGQQF1IglBAWoiBSAEIAVLGyAEQf7///8HTxsiBQR/IAVBAEgNBSAFQQF0EDEFQQALIQggCCAJQQF0aiIEIAFB/wFxIAJBCHRyOwAAIARBAmohCSADIAdHBEACQAJAIAZBAmsiAUEeSQ0AIAMgBkF+cSAIamtBEEkNACAEQRBrIQYgA0EQayEKIAQgAUEBdkEBaiILQXhxIgFBAXQiAmshBCADIAJrIQNBACECA0AgBiACQQF0IgxrIAogDGv9AAAA/QsAACACQQhqIgIgAUcNAAsgASALRg0BCwNAIARBAmsiBCADQQJrIgMvAAA7AAAgAyAHRw0ACwsgACgCOCEDCyAAIAggBUEBdGo2AkAgACAJNgI8IAAgBDYCOCADDQEMAgsgAyAESQ0FIAMgACgCOCIHayIGQX1MDQRB/////wcgBCAHayIEIAZBAXUiCUEBaiIFIAQgBUsbIARB/v///wdPGyIFBH8gBUEASA0EIAVBAXQQMQVBAAshCCAIIAlBAXRqIgQgAUH/AXEgAkEIdHI7AAAgBEECaiEJIAMgB0cEQAJAAkAgBkECayIBQR5JDQAgAyAGQX5xIAhqa0EQSQ0AIARBEGshBiADQRBrIQogBCABQQF2QQFqIgtBeHEiAUEBdCICayEEIAMgAmshA0EAIQIDQCAGIAJBAXQiDGsgCiAMa/0AAAD9CwAAIAJBCGoiAiABRw0ACyABIAtGDQELA0AgBEECayIEIANBAmsiAy8AADsAACADIAdHDQALCyAAKAI4IQMLIAAgCCAFQQF0ajYCQCAAIAk2AjwgACAENgI4IANFDQELIAMQLwsPCxA2AAsQSAALEDYACyADIAFB/wFxIAJBCHRyOwAACyAAIANBAmo2AjwL6wMBA38CQAJAIAEgAkYNAAJAAkACQAJAAkACQAJAAkACQCABLAAAIgRBImsOVQAICAgICAgICAgICAgACAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgACAgICAECCAgIAwgICAgICAgECAgIBQgGCAcICwJAIAMEQCADIAQQWwwBCyAAIAQQWgsMCQsCQCADBEAgA0EHEFsMAQsgAEEHEFoLDAgLAkAgAwRAIANBCBBbDAELIABBCBBaCwwHCwJAIAMEQCADQQwQWwwBCyAAQQwQWgsMBgsCQCADBEAgA0EKEFsMAQsgAEEKEFoLDAULAkAgAwRAIANBDRBbDAELIABBDRBaCwwECwJAIAMEQCADQQkQWwwBCyAAQQkQWgsMAwsCQCADBEAgA0ELEFsMAQsgAEELEFoLDAILIARBeHFBMEcNACAEQTBrIQUCQCABQQFqIgQgAkYNACAELQAAIgZB+AFxQTBHBEAgBCECDAELIAVBA3QgBmpBMGshBSABQQJqIgQgAkYNACAELQAAIgZB+AFxQTBHBEAgBCECDAELIAFBA2ohAiAFQQN0IAZqQTBrIQULIAMEQCADIAXAEFsgAg8LIAAgBcAQWiACDwsQgAIACyABQQFqC8sCAQR/IwBBEGsiBCQAIAMgAmsiBUHw////B0kEQAJAIAVBCk0EQCAEIAU6AA8gBEEEaiEGDAELIAVBD3JBAWoiBxAxIQYgBCAHQYCAgIB4cjYCDCAEIAY2AgQgBCAFNgIICyACIANHBH8gBiACIAX8CgAAIAUgBmoFIAYLQQA6AAAgACABKAIIIgEgBCgCBCAEQQRqIAQtAA8iAsBBAEgiAxsiBSAFIAQoAgggAiADG2ogASgCACgCEBEGAAJAAkACQCAAKAIEIAAtAAsiASABwCIBQQBIIgIbQQFrDgwCAQEBAQEBAQEBAQABCyAAKAIAIAAgAhsiACAALQADOgALDAELIAFBAEgEQCAAKAIAQQA6AAAgAEEANgIEDAELIABBADoACyAAQQA6AAALIAQsAA9BAEgEQCAEKAIEEC8LIARBEGokAA8LEE0AC/gFAQh/IwBBIGsiBCQAIAMgAmsiBUHw////B0kEQAJAIAVBCk0EQCAEIAU6AB8gBEEUaiEGDAELIAVBD3JBAWoiBxAxIQYgBCAHQYCAgIB4cjYCHCAEIAY2AhQgBCAFNgIYCyACIANHBH8gBiACIAX8CgAAIAUgBmoFIAYLQQA6AAAgAEEANgIIIABCADcCAAJAAkAgBCgCGCAELQAfIgIgAsBBAEgiAhtFDQAgBCgCFCAEQRRqIgogAhshByMAQRBrIgYkACAGIAc2AgwgBkEMaiELIwBBEGsiAyQAQbCgAyECQe8AIQUDQCAFBEAgAyACNgIMIAMgAygCDCAFQQF2IglBA3RqNgIMIAMoAgwiCEEIaiACIAggCxCMAyIIGyECIAUgCUF/c2ogCSAIGyEFDAELCyADQRBqJAAjAEEQayIFJAAgBEEIaiIDQgA3AgAgA0EANgIIIAVBEGokAAJAIAJBqKcDRg0AIAcgAigCABCfAQ0AIAMgAiwABBBbCyAGQRBqJAAgACAEKAIQNgIIIAAgBCkCCDcCACAAKAIEIAAtAAsiAiACwCICQQBIGw0AIAQoAhggBC0AHyIFIAXAQQBIIgUbIgZBAksNACADIAEoAggiASAEKAIUIAogBRsiAyADIAZqIAEoAgAoAhARBgAgAkEASARAIAAoAgAQLwsgACAEKQIINwIAIAAgBCgCEDYCCAJAAkAgACgCBCAALQALIgEgAcAiAUEASBtBAWsODAABAQEBAQEBAQEBAAELIARBFGogAEYNASAELQAfIgPAIQIgAUEATgRAIAJBAE4EQCAAIAQpAhQ3AgAgACAEKAIcNgIIDAQLIAAgBCgCFCAEKAIYEN4BDAILIAAgBCgCFCAEQRRqIAJBAEgiABsgBCgCGCADIAAbEN8BDAELIAFBAEgEQCAAKAIAQQA6AAAgAEEANgIEDAELIABBADoACyAAQQA6AAALIAQsAB9BAE4NACAEKAIUEC8LIARBIGokAA8LEE0AC5MCAgN/AX4CQCAAKAIMIgJBAXEEQEEYEDEhAiAAKAIkKAIEIQMgAkHkrQE2AgAgAiADNgIEIAJBCGogACgCACIDNgIAIANBBGpBAf4eAgAaIAApAgQhBSACIAE2AhQgAiAFNwIMIAAoAiQgAjYCBAwBCyACQQhxBEBBGBAxIQIgACgCJCgCBCEDIAJBvK4BNgIAIAIgAzYCBCACQQhqIAAoAgAiAzYCACADQQRqQQH+HgIAGiAAKQIEIQUgAiABNgIUIAIgBTcCDCAAKAIkIAI2AgQMAQtBDBAxIQIgACgCJCIDKAIEIQQgAiABNgIIIAJBmK8BNgIAIAIgBDYCBCADIAI2AgQLIAAgACgCJCgCBDYCJAsUAEEMEGBBEBBxQcCoA0HRABACAAsUAEEMEGBBDBBxQcCoA0HRABACAAvaAwIJfwF7IAH9AAIAIQsgAEEANgIYIABCADcCECAAIAv9CwIAIAEoAhQiBSABKAIQIgJrIgRBDG0hAwJAAkACQAJAAkACQCACIAVHBEAgA0HWqtWqAU8NASAAIAQQMSICNgIUIAAgAjYCECAAIAIgA0EMbGo2AhggASgCECIDIAEoAhQiBEcEQANAIAIgAykCADcCACACIAMoAgg2AgggAkEMaiECIANBDGoiAyAERw0ACwsgACACNgIUCyAAQgA3AhwgAEEANgIkIAEoAiAiAiABKAIcIgRGDQUgAiAEayICQQBIDQEgACACEDEiBDYCICAAIAQ2AhwgACAEIAJBeHFqNgIkIAEoAhwiBSABKAIgIgdGBEAgBCECDAULIAcgBWtBCGsiAkEYSQ0CIAQgBWtBEEkNAiAEIAJBA3ZBAWoiCUH+////A3EiCEEDdCIDaiECIAMgBWohAwNAIAQgBkEDdCIKaiAFIApq/QACAP0LAgAgBkECaiIGIAhHDQALIAggCUYNBAwDCxA2AAsQNgALIAUhAyAEIQILA0AgAiADKQIANwIAIAJBCGohAiADQQhqIgMgB0cNAAsLIAAgAjYCIAsgACABKQIoNwIoIAAgAS0AMDoAMCAAC5ACAQd/IAEgACgCCCIDIAAoAgQiAmtBA3VNBEAgACABBH8gAkEAIAFBA3QiAPwLACAAIAJqBSACCzYCBA8LAkAgAiAAKAIAIgVrQQN1IgcgAWoiBEGAgICAAkkEQEH/////ASADIAVrIgNBAnUiCCAEIAQgCEkbIANB+P///wdPGyIDBEAgA0GAgICAAk8NAiADQQN0EDEhBgsgB0EDdCAGaiIEQQAgAUEDdCIB/AsAIAEgBGohASACIAVHBEADQCAEQQhrIgQgAkEIayICKQIANwIAIAIgBUcNAAsgACgCACECCyAAIAYgA0EDdGo2AgggACABNgIEIAAgBDYCACACBEAgAhAvCw8LEDYACxBIAAvoCwEJfyMAQdAAayIGJAAgBkEANgJMIAZCADcCRAJAAkACQCAAKAIcIgtFDQAgBkEAOgBAIAYgAjYCPCAGIAI2AjggBv0MAAAAAAAAAAAAAAAAAAAAAP0LAyAgBv0MAAAAAAAAAAAAAAAAAAAAAP0LAxAgBv0MAAAAAAAAAAAAAAAAAAAAAP0LAwAgBkHEAGogBhCBAiAGKAIcIgcEQCAGIAc2AiAgBxAvCyAGKAIQIgcEQCAGIAc2AhQgBxAvCyAGKAJIIgdBNGsiCEEANgIAIAggAjYCDCAIIAE2AgggCCABNgIEAkAgACgCECIJIAgoAhQgCEEQaiIMKAIAIg1rQQxtIgpLBEAgDCAJIAprIAZBOGoQwAQgBigCSCEHDAELIAkgCk8NACAIIA0gCUEMbGo2AhQLAkAgACgCFCIAIAdBNGsiCCIJKAIgIAhBHGoiCigCACIMa0EDdSIISwRAIAogACAIaxDfAiAGKAJIIQcMAQsgACAITw0AIAkgDCAAQQN0ajYCIAsgC0EARyEIIAdBNGsiACAFOgAwIAAgBDYCLCAAIAs2AiggBEGAIHEhCSAEQSBxIQsgAiABayEKQQAhAAJAA0AgAEEBaiIAQf8fcUUgAEEMdiAKTnENAyAHQTRrIgQoAigiBQRAIAUgBCAFKAIAKAIIEQIACwJAAkACQAJAIAQoAgBB6AdqDgoACAgICAMDAgEDCAsgB0EsaygCACEEAkAgC0UNACABIARHDQAgBigCSCIEQRhrKAIAIgUEQCAEQRRrIAU2AgAgBRAvCyAEQSRrKAIAIgUEQCAEQSBrIAU2AgAgBRAvCyAGIARBNGs2AkgMAwsCQCAJRQ0AIAIgBEYNACAGKAJIIgRBGGsoAgAiBQRAIARBFGsgBTYCACAFEC8LIARBJGsoAgAiBQRAIARBIGsgBTYCACAFEC8LIAYgBEE0azYCSAwDCyADKAIAIgBBAToACCAAIAQ2AgQgACABNgIAAkAgB0E0ayIBKAIUIgMgASgCECICRg0AQQEgAyACa0EMbSIDIANBAU0bIgRBAXEhDkEAIQEgA0ECTwRAIARBfnEhCUEAIQUDQCAAIAFBAXJBDGwiC2oiAyACIAFBDGwiCmoiBCgCADYCACADIAQoAgQ2AgQgAyAELQAIOgAIIAAgCmoiAyACIAtqIgQoAgA2AhggAyAEKAIENgIcIAMgBC0ACDoAICABQQJqIQEgBUECaiIFIAlHDQALCyAORQ0AIAFBDGwiASAAaiIAIAEgAmoiASgCADYCDCAAIAEoAgQ2AhAgACABLQAIOgAUCyAGKAJEIQQMBAsgBiAEEN4CIQUgBCgCKCIHQQEgBCAHKAIAKAIMEQUAIAYoAigiBEEAIAUgBCgCACgCDBEFAAJAIAYoAkgiBCAGKAJMSQRAIAQgBf0AAgD9CwIAIAT9DAAAAAAAAAAAAAAAAAAAAAD9CwIQIAQgBigCEDYCECAEIAYoAhQ2AhQgBCAGKAIYNgIYIAZBADYCECAEQgA3AiAgBCAGKAIcNgIcIAQgBigCIDYCICAEIAYoAiQ2AiQgBv0MAAAAAAAAAAAAAAAAAAAAAP0LAhggBCAGLQAwOgAwIAQgBikCKDcCKCAGIARBNGo2AkgMAQsgBkHEAGogBRCBAiAGKAIcIgRFDQAgBiAENgIgIAQQLwsgBigCECIERQ0BIAYgBDYCFCAEEC8MAQsgBigCSCIEQRhrKAIAIgUEQCAEQRRrIAU2AgAgBRAvCyAEQSRrKAIAIgUEQCAEQSBrIAU2AgAgBRAvCyAGIARBNGs2AkgLIAYoAkQiBCAGKAJIIgdHDQALQQAhCAsgBEUNACAEIQAgBCAGKAJIIgFHBEADQCABQTRrIgAoAhwiAgRAIAFBFGsgAjYCACACEC8LIAFBJGsoAgAiAgRAIAFBIGsgAjYCACACEC8LIAAiASAERw0ACyAGKAJEIQALIAYgBDYCSCAAEC8LIAZB0ABqJAAgCA8LEN0CAAsQ3AIAC8IBAQR/QQgQMSEHIAAoAiQiBSgCBCEGIAdBuKcBNgIAIAcgBjYCBCAFQQA2AgRBJBAxIQUgACgCFCEGIAIoAgQhCCAFIAc2AgggBSAINgIEIAVBADoAICAFIAQ2AhwgBSADNgIYIAUgBjYCFCAFQX82AhAgBSABNgIMIAVBzLEBNgIAIAJBADYCBEEIEDEiAUHIsgE2AgAgASAFNgIEIAAoAiQgATYCBCAAIAUoAgg2AiQgAiAFNgIEIAAgBkEBajYCFAvCAQEEf0EIEDEhCCAAKAIkIgYoAgQhByAIQbinATYCACAIIAc2AgQgBkEANgIEQSQQMSEGIAAoAhQhByADKAIEIQkgBiAINgIIIAYgCTYCBCAGQQA6ACAgBiAFNgIcIAYgBDYCGCAGIAc2AhQgBiACNgIQIAYgATYCDCAGQcyxATYCACADQQA2AgRBCBAxIgFByLIBNgIAIAEgBjYCBCAAKAIkIAE2AgQgACAGKAIINgIkIAMgBjYCBCAAIAdBAWo2AhQLqx8CEH8BfgJAAkAgASACRg0AIAEtAABB2wBHDQAgAUEBaiIKIAJGDQEgAS0AASEDQdwAEDEgACAAKAIkKAIEIANB3gBGIgMgACgCDCIFQQFxIAVBCHFBA3YQtQEhCSAAKAIkIAk2AgQgACAJNgIkIAFBAmogCiADGyIDIAJGDQECQCAAKAIMQfAHcUGABEYNACADLQAAQd0ARw0AIAlB3QAQowEgA0EBaiEDCyACIANGDQEDQEEAIQ4jAEFAaiIHJAACQAJAIAMiASACIgpGDQAgAy0AACIFQd0ARg0AIAdBADYCOCAHQgA3AzACQAJAAkACQAJAIANBAWogCkYNACAFQdsARw0AAkACQCADLQABQS5rDhADAgICAgICAgICAgIBAgIAAgsCfyMAQSBrIggkAAJAAkAgCiIGIANBAmoiBGsiCkECSA0AIAQgCmpBAWshCyAEIQoDQCAKQQFqIQUgCi0AAEE9RgRAIAUtAABB3QBHBEAgBSIKIAtHDQIMAwsgBiAKRg0CIAhBFGoiBSAAIAQgChDaAiAIKAIYIAgtAB8iBCAEwEEASCIEGyIGRQ0DIAhBCGogACAIKAIUIAUgBBsiBSAFIAZqENkCAkACQCAIKAIMIgQgCC0AEyIFIAXAIgZBAEgbBEAgCSgCSCIFIAkoAkxGDQECQCAGQQBOBEAgBSAIKQIINwIAIAUgCCgCEDYCCAwBCyAFIAgoAgggBBBsCyAJIAVBDGo2AkgMAgsCQAJAIAgoAhggCC0AHyIFIAXAQQBIIgUbQQFrDgIAAQcLIAkgCCgCFCAIQRRqIAUbLAAAEKMBDAILIAkgCCgCFCAIQRRqIAUbIgUsAAAgBSwAARDXAgwBC0EAIQsCQAJAAkAgCSgCSCIFIAkoAkQiBmtBDG0iDEEBaiIEQdaq1aoBSQRAQdWq1aoBIAkoAkwgBmtBDG0iDUEBdCIPIAQgBCAPSRsgDUGq1arVAE8bIgQEQCAEQdaq1aoBTw0CIARBDGwQMSELCyAEQQxsIQ0gCyAMQQxsaiEEAkAgCCwAE0EATgRAIAQgCCkCCDcCACAEIAgoAhA2AggMAQsgBCAIKAIIIAgoAgwQbCAJKAJEIQYgCSgCSCEFCyALIA1qIQsgBEEMaiEMIAUgBkYNAgNAIARBDGsiBCAFQQxrIgUpAgA3AgAgBCAFKAIINgIIIAVCADcCACAFQQA2AgggBSAGRw0ACyAJIAs2AkwgCSgCSCEFIAkgDDYCSCAJKAJEIQYgCSAENgJEIAUgBkYNAwNAIAVBDGshBCAFQQFrLAAAQQBIBEAgBCgCABAvCyAEIgUgBkcNAAsMAwsQNgALEEgACyAJIAs2AkwgCSAMNgJIIAkgBDYCRAsgBgRAIAYQLwsLIAgsABNBAEgEQCAIKAIIEC8LIAgsAB9BAEgEQCAIKAIUEC8LIAhBIGokACAKQQJqDAQLIAUiCiALRw0ACwsQ/gEACxC7BAALIQoMBQsCfwJAAkAgCiIGIANBAmoiBGsiCkECSA0AIAQgCmpBAWshCCAEIQoDQCAKQQFqIQUgCi0AAEE6RgRAIAUtAABB3QBHBEAgBSIKIAhHDQIMAwsgBiAKRg0CAn8gACgCDEEBcSERIwBBEGsiBSQAIAogBGsiBkHw////B0kEQAJAIAZBCk0EQCAFIAY6AA8gBUEEaiEIDAELIAZBD3JBAWoiCxAxIQggBSALQYCAgIB4cjYCDCAFIAg2AgQgBSAGNgIICyAEIApHBH8gCCAEIAb8CgAAIAYgCGoFIAgLQQA6AAAgACgCBCIEIAUoAgQgBUEEaiIGIAUtAA8iCMBBAEgiCxsiDCAMIAUoAgggCCALG2ogBCgCACgCGBEDABogBSgCBCAGIAUsAA9BAEgbIQ1BACEIIwBBEGsiDCQAIAwgDTYCDCAMQQxqIRIjAEEQayIGJABBsKcDIQRBDyELA0AgCwRAIAYgBDYCDCAGIAYoAgwgC0EBdiIPQQN0ajYCDCAGKAIMIhBBCGogBCAQIBIQjAMiEBshBCALIA9Bf3NqIA8gEBshCwwBCwsgBkEQaiQAAkAgBEGoqANGDQAgDSAEKAIAEJ8BDQBB+AggBCgCBCIEIARBgAhGIgYbIQggBg0AIBFFDQAgBEEgciAEIARBGHEbIQgLIAxBEGokACAFLAAPQQBIBEAgBSgCBBAvCyAFQRBqJAAgCAwBCxBNAAsiBUUNAyAJIAkoAlAgBXI2AlAgCkECagwECyAFIgogCEcNAAsLEP4BAAtBDBBgQQIQcUHAqANB0QAQAgALIQoMBAsgACgCDEHwB3EhBAwBCyAAIANBAmogCiAHQTBqEL0EIQMgACgCDEHwB3EhBCAHKAI0IActADsiBSAFwEEASBsNAQsCQAJAIARBwABGDQAgBEGABEYNACADLQAAIQ4MAQsgAy0AACIOQdwARw0AIANBAWohAyAEQYAERgRAIAAgAyAKIAdBMGogCRC8BCEDQYAEIQQMAgsgACADIAogB0EwahDYAiEDDAELIAdBMGogDsAQWyADQQFqIQMLAkACQAJAAkAgAyAKRg0AIAMtAAAiBUHdAEYNAEEBIQ4CQCADQQFqIApGDQAgBUEtRw0AIAMtAAFB3QBGDQAgB0EANgIoIAdCADcDIAJAIANBAmoiBSAKRg0AIAMtAAFB2wBHDQAgBS0AAEEuRw0AIAAgA0EDaiAKIAdBIGoQvQQhBQwECwJAIARBwABGDQAgBEGABEYNACADLQABIQMMAwsgAy0AASIDQdwARw0CIARBgARGBEAgACAFIAogB0EgaiAJELwEIQUMBAsgACAFIAogB0EgahDYAiEFDAMLAkACQCAHKAI0IActADsiBSAFwEEASCIFGw4CBgABCyAJIAcoAjAgB0EwaiAFGywAABCjAQwECyAJIAcoAjAgB0EwaiAFGyIKLAAAIAosAAEQ1wIMAwtBASEOAkACQCAHKAI0IActADsiBSAFwEEASCIFGw4CBQABCyAJIAcoAjAgB0EwaiAFGywAABCjAQwDCyAJIAcoAjAgB0EwaiAFGyIKLAAAIAosAAEQ1wIMAgsgB0EgaiADwBBbCyAHIAcoAjg2AhggB0EANgI4IAcoAighCiAHQQA2AiggByAKNgIIIAcgBykDMDcDECAHQgA3AzAgBykDICETIAdCADcDICAHIBM3AwAgB0EQaiEEIwBB0ABrIgMkAAJAAkACQAJAAkAgCS0AWgRAAkAgCS0AWUUNACAEKAIEIAQtAAsiBiAGwEEASCIIGwRAQQAhBgNAIAkoAgwiCyAEKAIAIAQgCEEBcRsgBmosAAAgCygCACgCFBEEACEIIAQoAgAgBCAELAALQQBIGyAGaiAIOgAAIAZBAWoiBiAEKAIEIAQtAAsiCCAIwEEASCIIG0kNAAsLIAcoAgQgBy0ACyIGIAbAQQBIIggbRQ0AQQAhBgNAIAkoAgwiCyAHKAIAIAcgCEEBcRsgBmosAAAgCygCACgCFBEEACEIIAcoAgAgByAHLAALQQBIGyAGaiAIOgAAIAZBAWoiBiAHKAIEIActAAsiCCAIwEEASCIIG0kNAAsLIAQoAgQgBC0ACyIGIAbAQQBIIgsbIgZB8P///wdPDQIgBCgCACEMAn8CQCAGQQtPBEAgBkEPckEBaiINEDEhCCADIA1BgICAgHhyNgIwIAMgCDYCKCADIAY2AiwMAQsgAyAGOgAzIANBKGoiCCAGRQ0BGgsgCCAMIAQgCxsgBvwKAAAgBiAIagtBADoAACADQRhqIAkoAhAiBCADKAIoIANBKGogAy0AMyIGwEEASCIIGyILIAsgAygCLCAGIAgbaiAEKAIAKAIQEQYAIAMsADNBAEgEQCADKAIoEC8LIAcoAgQgBy0ACyIEIATAQQBIIggbIgRB8P///wdPDQMgBygCACELAn8CQCAEQQtPBEAgBEEPckEBaiIMEDEhBiADIAxBgICAgHhyNgJMIAMgBjYCRCADIAQ2AkgMAQsgAyAEOgBPIANBxABqIgYgBEUNARoLIAYgCyAHIAgbIAT8CgAAIAQgBmoLQQA6AAAgA0EIaiAJKAIQIgQgAygCRCADQcQAaiADLQBPIgbAQQBIIggbIgsgCyADKAJIIAYgCBtqIAQoAgAoAhARBgAgAywAT0EASARAIAMoAkQQLwsgAygCICEEIANBADYCICADIAQ2AjAgAygCECEEIANBADYCECADIAQ2AjwgAykDGCETIANCADcDGCADIBM3AyggAykDCCETIANCADcDCCADIBM3AjQCQCAJKAIwIgQgCSgCNEkEQCAEIAMpAyg3AgAgBCADKAIwNgIIIANBADYCMCADQgA3AyggBCADKAI8NgIUIAQgAykCNDcCDCADQgA3AjQgA0EANgI8IAkgBEEYajYCMAwBCyAJQSxqIANBKGoQugQgAywAP0EATg0AIAMoAjQQLwsgAywAM0EASARAIAMoAigQLwsgAywAE0EASARAIAMoAggQLwsgAywAI0EATg0BIAMoAhgQLwwBCyAEKAIEIAQtAAsiBiAGwCIGQQBIG0EBRw0DIAcoAgQgBy0ACyIIIAjAQQBIG0EBRw0DIAktAFkEQCAJKAIMIgggBCgCACAEIAZBAEgbLAAAIAgoAgAoAhQRBAAhBiAEKAIAIAQgBCwAC0EASBsgBjoAACAJKAIMIgYgBygCACAHIAcsAAtBAEgbLAAAIAYoAgAoAhQRBAAhBiAHKAIAIAcgBywAC0EASBsgBjoAAAsgAyAEKAIINgIwIAMgBCkCADcDKCAEQgA3AgAgBEEANgIIIAMgBygCCDYCPCADIAcpAgA3AjQgB0IANwIAIAdBADYCCAJAIAkoAjAiBCAJKAI0SQRAIAQgAykDKDcCACAEIAMoAjA2AgggA0EANgIwIANCADcDKCAEIAMoAjw2AhQgBCADKQI0NwIMIANCADcCNCADQQA2AjwgCSAEQRhqNgIwDAELIAlBLGogA0EoahC6BCADLAA/QQBODQAgAygCNBAvCyADLAAzQQBODQAgAygCKBAvCyADQdAAaiQADAMLEE0ACxBNAAtBDBBgQQkQcUHAqANB0QAQAgALIAcsAAtBAEgEQCAHKAIAEC8LIAcsABtBAEgEQCAHKAIQEC8LIAcsACtBAEgEQCAHKAIgEC8LIAUhAwsLIAcsADtBAEgEQCAHKAIwEC8LIA5FDQELIAMhCgsgB0FAayQAIAEgCiIDRw0ACyABIAJGDQEgAS0AAEEtRgRAIAlBLRCjASABQQFqIQELIAEgAkYNASABLQAAQd0ARw0BIAFBAWohAQsgAQ8LEP4BAAvcDQEFfwJAAkACQAJAAkAgASACRg0AIAAoAgxB8AdxIQYCQAJAAkACQCABLAAAIgdBKmsOFgMCBAQEBAQEBAQEBAQEBAQEBAQEBAEACyAHQfsARw0DIAFBAWoiCCACRg0EIAgtAAAiB0H4AXFBMEcgB0H+AXFBOEdxDQQgB0EwayEHAkAgAiABQQJqIgFHBEADQCABLQAAIglB+AFxQTBHIAlB/gFxQThHcQ0CIAdBzJmz5gBODQcgB0EKbCAJakEwayEHIAFBAWoiASACRw0ACwsgAiEBCyABIAhGDQQCQCABIAJGDQAgASwAACIIQSxHBEAgCEH9AEcNBiABQQFqIQgCQCAGQYAERw0AIAIgCEYNACAILQAAQT9HDQAgACAHIAcgAyAEIAUQ4gIMCAtBCBAxIQIgACgCJCIBKAIEIQYgAkG4pwE2AgAgAiAGNgIEIAFBADYCBEEkEDEhASAAKAIUIQYgAygCBCEJIAEgAjYCCCABIAk2AgQgAUEBOgAgIAEgBTYCHCABIAQ2AhggASAGNgIUIAEgBzYCEAwICyABQQFqIgkgAkYNBSAJLQAAIghB/QBGBEAgAUECaiEIAkAgBkGABEcNACACIAhGDQAgCC0AAEE/Rw0AIAAgByADIAQgBRDhAiABQQNqDwtBCBAxIQIgACgCJCIBKAIEIQYgAkG4pwE2AgAgAiAGNgIEIAFBADYCBEEkEDEhASAAKAIUIQYgAygCBCEJIAEgAjYCCCABIAk2AgQgAUEBOgAgIAEgBTYCHCABIAQ2AhggASAGNgIUIAFBfzYCEAwICyAIQfgBcUEwRyAIQf4BcUE4R3ENACAIQTBrIQgCQCACIAFBAmoiAUcEQANAIAEtAAAiCkH4AXFBMEcgCkH+AXFBOEdxDQIgCEHMmbPmAE4NCCAIQQpsIApqQTBrIQggAUEBaiIBIAJHDQALCyACIQELIAEgCUYNACABIAJGDQAgAS0AAEH9AEcNACAHIAhKDQUgAUEBaiEJAkAgBkGABEcNACACIAlGDQAgCS0AAEE/Rw0AIAAgByAIIAMgBCAFEOICDAcLQQgQMSECIAAoAiQiASgCBCEGIAJBuKcBNgIAIAIgBjYCBCABQQA2AgRBJBAxIQEgACgCFCEGIAMoAgQhCiABIAI2AgggASAKNgIEIAFBAToAICABIAU2AhwgASAENgIYIAEgBjYCFCABIAg2AhAgASAHNgIMIAFBzLEBNgIAIANBADYCBEEIEDEiAkHIsgE2AgAgAiABNgIEIAAoAiQgAjYCBCAAIAEoAgg2AiQgAyABNgIEIAAgBkEBajYCFCAJDwsQwgQACyABQQFqIQcCQCAGQYAERw0AIAIgB0YNACAHLQAAQT9HDQAgAEEAQQEgAyAEIAUQ4gIMBQtBCBAxIQIgACgCJCIBKAIEIQYgAkG4pwE2AgAgAiAGNgIEIAFBADYCBEEkEDEhASAAKAIUIQYgAygCBCEIIAEgAjYCCCABIAg2AgQgAUEBOgAgIAEgBTYCHCABIAQ2AhggASAGNgIUIAFCgICAgBA3AgwMBgsgAUEBaiEHAkAgBkGABEcNACACIAdGDQAgBy0AAEE/Rw0AIABBASADIAQgBRDhAgwEC0EIEDEhAiAAKAIkIgEoAgQhBiACQbinATYCACACIAY2AgQgAUEANgIEQSQQMSEBIAAoAhQhBiADKAIEIQggASACNgIIIAEgCDYCBCABQQE6ACAgASAFNgIcIAEgBDYCGCABIAY2AhQgAUKBgICAcDcCDAwFCyABQQFqIQcCQCAGQYAERw0AIAIgB0YNACAHLQAAQT9HDQAgAEEAIAMgBCAFEOECDAMLQQgQMSECIAAoAiQiASgCBCEGIAJBuKcBNgIAIAIgBjYCBCABQQA2AgRBJBAxIQEgACgCFCEGIAMoAgQhCCABIAI2AgggASAINgIEIAFBAToAICABIAU2AhwgASAENgIYIAEgBjYCFCABQoCAgIBwNwIMIAFBzLEBNgIAIANBADYCBEEIEDEiAkHIsgE2AgAgAiABNgIEIAAoAiQgAjYCBCAAIAEoAgg2AiQgAyABNgIEIAAgBkEBajYCFCAHIQELIAEPCxDBBAALIAFBAmoPCyABIAc2AgwgAUHMsQE2AgAgA0EANgIEQQgQMSICQciyATYCACACIAE2AgQgACgCJCACNgIEIAAgASgCCDYCJCADIAE2AgQgACAGQQFqNgIUIAgPCyABQcyxATYCACADQQA2AgRBCBAxIgJByLIBNgIAIAIgATYCBCAAKAIkIAI2AgQgACABKAIINgIkIAMgATYCBCAAIAZBAWo2AhQgBwuzAgEEfyABIAJGBEAgAQ8LIAEtAABB3gBGBEBBDBAxIQMgACgCDCEEIAAoAiQiBSgCBCEGIANB5KgBNgIAIAMgBjYCBCADIARB8A9xQYAMRjoACCAFIAM2AgQgACAAKAIkKAIENgIkIAFBAWohAQsCQCABIAJGDQADQCABIgMgAkYiBA0BIAAoAhAhASAAKAIkIQUgAyAAIAMgAhDIBCIGRwRAIAAgBiACIAUgAUEBaiAAKAIQQQFqEMcEIgEgA0cNAQsLAkAgA0EBaiACRw0AIAMtAABBJEcNAEEMEDEhASAAKAIMIQMgACgCJCIEKAIEIQUgAUGsqQE2AgAgASAFNgIEIAEgA0HwD3FBgAxGOgAIIAQgATYCBCAAIAAoAiQoAgQ2AiQMAQsgBA0AEMYEAAsgAguFBAEGfyAAKAIkIQcgASEDA0ACQCADIgQgACADIAIQygQiA0YEQCAAKAIQIQMgACgCJCEFIAAgBCACEMkEIgYgBEYNASAAIAYgAiAFIANBAWogACgCEEEBahDkAiEDCyADIARHDQELCyABIARGBEBBCBAxIQEgACgCJCIDKAIEIQUgAUG4pwE2AgAgASAFNgIEIAMgATYCBCAAIAAoAiQoAgQ2AiQLIAIgBEcEQANAIAQtAABB/ABHBEAgBA8LIAAoAiQhASAEQQFqIgUhAwNAAkAgAyIEIAAgAyACEMoEIgNGBEAgACgCECEDIAAoAiQhBiAAIAQgAhDJBCIIIARGDQEgACAIIAIgBiADQQFqIAAoAhBBAWoQ5AIhAwsgAyAERw0BCwsgBCAFRgRAQQgQMSEDIAAoAiQiBSgCBCEGIANBuKcBNgIAIAMgBjYCBCAFIAM2AgQgACAAKAIkKAIENgIkC0EMEDEhAyAHKAIEIQUgAyABKAIENgIIIAMgBTYCBCADQYyzATYCACAHIAM2AgQgAUEANgIEQQgQMSEDIAAoAiQoAgQhBSADQbinATYCACADIAU2AgQgASADNgIEIAAoAiRBADYCBEEIEDEhAyABKAIEIQUgA0HMswE2AgAgAyAFNgIEIAAoAiQgAzYCBCAAIAEoAgQ2AiQgAiAERw0ACwsgAgudGQMXfwl7Bn0jAEEwayIIJAACQCAAKAIEIAAoAgAiAmtBAXUiBiABKAIEIAEoAgAiB2tBAnUiA0sEQCABIAYgA2sQbyAAKAIAIQIMAQsgAyAGTQ0AIAEgByAGQQJ0ajYCBAsCQCAAKAIEIAJrIglBBEYEQCACKgIAISIgASgCACIAQQA2AgQgACAiOAIADAELIAlBAnUiDUGBgICAeHFBAUYEQAJAIAlBAXUiAiABKAIEIAEoAgAiA2tBAnUiBksEQCABIAIgBmsQbwwBCyACIAZPDQAgASADIAJBAnRqNgIEC0GQAyANbiEGIAlBAEwNASABKAIAIQEgACgCACEAQQAhAwNAIAMgBmwhB0MAAAAAISJBACECQwAAAAAhIwNAICIgACACQQJ0aioCACIkIAIgB2xBkANvQQJ0IgRB0NY0aioCAJSTISIgJCAEQZDjNGoqAgCUICOSISMgAkEBaiICIA1HDQALIAEgA0EDdGoiAiAjOAIAIAIgIjgCBCADQQFqIgMgDUcNAAsMAQtBACECIAhBADYCLCAIQgA3AiQgCEEANgIcIA1BAm0hFAJAAkACfyANQQFqQQNJBEBBACEGQQAMAQsgFEGAgICABE8NASAIIBRBAnQiAxAxIgY2AiggAyAGaiEMQQAgDUEBakEDSQ0AGiAIIAMQMSICNgIcIAIgA2oLIQsgCUEATARAIAYhByACIQMMAgtBASANIA1BAUwbIRUgAiEDIAYhBwNAIAAoAgAgDkECdGohCgJAAkACQAJAAkAgDkEBcUUEQCAGIAxHBEAgBiAKKgIAOAIAIAggBkEEaiIGNgIoDAYLIAYgB2siBUECdSIQQQFqIgRBgICAgARPDQFB/////wMgBUEBdSIMIAQgBCAMSRsgBUH8////B08bIgwEfyAMQYCAgIAETw0DIAxBAnQQMQVBAAsiESAQQQJ0aiIEIAoqAgA4AgAgDEECdCEXIARBBGohCgJAIAYgB0YNAAJAIAVBBGsiDEH8AUkNACAFIBFqIg9BBGsiEiAGQQRrIgUgB2tBfHEiE2sgEksNACAFIBNrIAVLDQAgBiAPa0EQSQ0AIARBEGshDyAGQRBrIRIgBiAMQQJ2QQFqIhNB/P///wdxIgxBAnQiBWshBiAEIAVrIQRBACEFA0AgDyAFQQJ0IhZrIBIgFmv9AAIA/QsCACAFQQRqIgUgDEcNAAsgDCATRg0BCwNAIARBBGsiBCAGQQRrIgYqAgA4AgAgBiAHRw0ACwsgFyARaiEMIAggCjYCKCAHRQ0EIAcQLwwECyACIAtHBEAgAiAKKgIAOAIAIAggAkEEaiICNgIcDAULIAIgA2siBUECdSIQQQFqIgRBgICAgARPDQJB/////wMgBUEBdSILIAQgBCALSRsgBUH8////B08bIgsEfyALQYCAgIAETw0CIAtBAnQQMQVBAAsiESAQQQJ0aiIEIAoqAgA4AgAgC0ECdCEYIARBBGohCgJAIAIgA0YNAAJAIAVBBGsiC0H8AUkNACAFIBFqIg9BBGsiEiACQQRrIgUgA2tBfHEiE2sgEksNACAFIBNrIAVLDQAgAiAPa0EQSQ0AIARBEGshDyACQRBrIRIgAiALQQJ2QQFqIhNB/P///wdxIgtBAnQiBWshAiAEIAVrIQRBACEFA0AgDyAFQQJ0IhZrIBIgFmv9AAIA/QsCACAFQQRqIgUgC0cNAAsgCyATRg0BCwNAIARBBGsiBCACQQRrIgIqAgA4AgAgAiADRw0ACwsgGCARaiELIAggCjYCHCADBEAgAxAvCyAKIQIgBCEDDAQLIAggBzYCJCAIIAY2AiwQNgALEEgACyAIIAM2AhggCCACNgIgIAggDDYCLCAIIAc2AiQQNgALIAohBiAEIQcLIBUgDkEBaiIORw0ACwwBCxA2AAsgCCADNgIYIAggCzYCICAIIAw2AiwgCCAHNgIkQQAhBiAIQQA2AhQgCEIANwIMIAhBADYCCCAIQgA3AgBBkAMgDW0hFiAIQSRqIAhBDGoQ5wIgCEEYaiAIEOcCIAgoAgAhAgJAAkAgCUEFTgRAIAEoAgAhACAIKAIMIQECQEEBIBQgFEEBTBsiDEEgSQ0AIAAgFEEDdCIHaiIDIAxBAWsiBEEDdCIKaiADSQ0AIBZBAUcNACADQQRqIgMgCmogA0kNACAEQf////8BSw0AIAAgACAMQQN0IglqIgRJIABBBGoiCiAAIAlBBGsiD2oiDUlxDQAgACAAIAcgCWpqIgNJIAAgB2oiB0EEaiIFIA1JcQ0AIAAgDEECdCIOQZDjNGoiC0kgDUGQ4zRLcQ0AIAAgDkHQ1jRqIg5JIA1B0NY0S3ENACACIA1JIAAgAiAPaiIRSXENACAAIAIgCWoiFUkgAkEEaiIQIA1JcQ0AIAEgDUkgACABIA9qIg9JcQ0AIAAgASAJaiISSSABQQRqIhMgDUlxDQAgACADQQRrIglJIAcgDUlxDQAgAyAKSyAEIAVLcQ0AIAogC0kgBEGQ4zRLcQ0AIAogDkkgBEHQ1jRLcQ0AIAIgBEkgCiARSXENACAKIBVJIAQgEEtxDQAgCiAPSSABIARJcQ0AIAogEkkgBCATS3ENACAJIApLIAQgB0txDQAgBSALSSADQZDjNEtxDQAgBSAOSSADQdDWNEtxDQAgAiADSSAFIBFJcQ0AIAUgFUkgAyAQS3ENACAFIA9JIAEgA0lxDQAgBSASSSADIBNLcQ0AIAUgCUkgAyAHS3ENACAHIAtJIAlBkOM0S3ENACAHIA5JIAlB0NY0S3ENACACIAlJIAcgEUlxDQAgByAVSSAJIBBLcQ0AIAEgCUkgByAPSXENACAHIBJJIAkgE0txDQAgDEH8////B3EhBiAU/REhHv0MAAAAAAEAAAACAAAAAwAAACEbQQAhAwNAIAAgG0EB/asBIhn9GwBBAnQiB2ogA0ECdCIJQdDWNGr9AAQAIhwgAiAZ/QwBAAAAAQAAAAEAAAABAAAA/VAiGv0bAEECdCIEav0JAgAgAiAa/RsBQQJ0IgpqKgIA/SABIAIgGv0bAkECdCINaioCAP0gAiACIBr9GwNBAnQiBWoqAgD9IAMiGv3mASIfIAlBkOM0av0ABAAiHSACIAdq/QkCACACIBn9GwFBAnQiCWoqAgD9IAEgAiAZ/RsCQQJ0IgtqKgIA/SACIAIgGf0bA0ECdCIOaioCAP0gAyIg/eYBIiEgASAHaiIH/QkCACABIAlqIhEqAgD9IAEgASALaiIVKgIA/SACIAEgDmoiECoCAP0gA/3kAf3kASIZ/R8AOAIAIAAgCWogGf0fATgCACAAIAtqIBn9HwI4AgAgACAOaiAZ/R8DOAIAIAAgBGogHSAa/eYBIh0gASAEaiIE/QkCACABIApqIgkqAgD9IAEgASANaiILKgIA/SACIAEgBWoiDioCAP0gA/3kASAcICD95gEiHP3lASIZ/R8AOAIAIAAgCmogGf0fATgCACAAIA1qIBn9HwI4AgAgACAFaiAZ/R8DOAIAIAAgGyAe/a4BQQH9qwEiGf0bAEECdGogB/0JAgAgESoCAP0gASAVKgIA/SACIBAqAgD9IAMgIf3lASAf/eUBIhr9HwA4AgAgACAZ/RsBQQJ0aiAa/R8BOAIAIAAgGf0bAkECdGogGv0fAjgCACAAIBn9GwNBAnRqIBr9HwM4AgAgACAZ/QwBAAAAAQAAAAEAAAABAAAA/VAiGf0bAEECdGogHCAE/QkCACAJKgIA/SABIAsqAgD9IAIgDioCAP0gAyAd/eUB/eQBIhr9HwA4AgAgACAZ/RsBQQJ0aiAa/R8BOAIAIAAgGf0bAkECdGogGv0fAjgCACAAIBn9GwNBAnRqIBr9HwM4AgAgG/0MBAAAAAQAAAAEAAAABAAAAP2uASEbIANBBGoiAyAGRw0ACyAGIAxGDQILA0AgACAGQQN0IgNqIAYgFmxBAnQiBEHQ1jRqKgIAIiIgAiADQQRyIgdqKgIAIiOUIiQgBEGQ4zRqKgIAIiUgAiADaioCACImlCInIAEgA2oiAyoCAJKSOAIAIAAgB2ogJSAjlCIjIAEgB2oiByoCAJIgIiAmlCIikzgCACAAIAYgFGpBA3RqIgQgAyoCACAnkyAkkzgCACAEICIgByoCACAjk5I4AgQgBkEBaiIGIAxHDQALDAELIAJFDQELIAggAjYCBCACEC8LIAgoAgwiAARAIAggADYCECAAEC8LIAgoAhgiAARAIAAQLwsgCCgCJCIARQ0AIAggADYCKCAAEC8LIAhBMGokAAv8AwEEfwJAAkACQCAAKAIEIAAoAgAiAmtBMG0iBUEBaiIDQdaq1SpJBEBB1arVKiAAKAIIIAJrQTBtIgJBAXQiBCADIAMgBEkbIAJBqtWqFU8bIgNB1qrVKk8NASADQTBsIgMQMSIEIAVBMGxqIgIgAf0AAwD9CwMAIAIgASgCGDYCGCACIAEpAxA3AxAgAUEANgIYIAFCADcDECACIAEoAhw2AhwgAiABKAIgNgIgIAIgASgCJDYCJCABQQA2AiQgAUIANwIcIAIgAS0AKDoAKCADIARqIQMgAkEwaiEFIAAoAgQiASAAKAIAIgRGDQIDQCACQTBrIgIgAUEwayIB/QADAP0LAwAgAiABKAIYNgIYIAIgASkDEDcDECABQQA2AhggAUIANwMQIAIgASgCHDYCHCACIAEoAiA2AiAgAiABKAIkNgIkIAFBADYCJCABQgA3AhwgAiABLQAoOgAoIAEgBEcNAAsgACADNgIIIAAoAgQhAyAAIAU2AgQgACgCACEBIAAgAjYCACABIANGDQMDQCADQTBrIgAoAhwiAgRAIANBEGsgAjYCACACEC8LIANBFWssAABBAEgEQCADQSBrKAIAEC8LIAAiAyABRw0ACwwDCxA2AAsQSAALIAAgAzYCCCAAIAU2AgQgACACNgIACyABBEAgARAvCwsfACABBEAgACABKAIAEOkCIAAgASgCBBDpAiABEC8LC/8rAxV/AnwBfiMAQfAAayIIJAADQCABQcgAayEKIAFB6ABrIQkDQCAAIQcDQAJAAkACQAJAAkACQAJAAkAgASAHayINQegAbSIQDgYHBwABBAIDCyABQcgAaysDACAHKwMgZEUNBiAHIAFB6ABrED4MBgsgB0HoAGohAiABQegAayIAKwMgIRkgBysDiAEiGCAHKwMgZEUEQCAYIBljRQ0GIAIgABA+IAcrA4gBIAcrAyBkRQ0GIAcgAhA+DAYLIBggGWMEQCAHIAAQPgwGCyAHIAIQPiAAKwMgIAcrA4gBZEUNBSACIAAQPgwFCyAHIAdB6ABqIAdB0AFqIAdBuAJqIAFB6ABrENUCGgwECyANQdcFTARAIAdB6ABqIQIgB0HQAWohACAHKwPwASEZAkAgBysDiAEiGCAHKwMgZEUEQCAYIBljRQ0BIAIgABA+IAcrA4gBIAcrAyBkRQ0BIAcgAhA+DAELIBggGWMEQCAHIAAQPgwBCyAHIAIQPiAHKwPwASAHKwOIAWRFDQAgAiAAED4LIAdBuAJqIgMgAUYNBANAIAMrAyAiGCAAKwMgZARAIAggAy0ACDoASCAIIAMpAwA3A0AgAygCFCERIAMoAhAhEiADQgA3AxAgAygCGCETIANBADYCGCADKAIcIQ8gCCAD/QACOP0LAxAgCCAD/QACKP0LAwAgAygCXCEUIAMoAlghFSADQgA3A1ggAygCTCEOIAMoAlAhCiADKAJUIQkgAygCSCELIAP9DAAAAAAAAAAAAAAAAAAAAAD9CwNIIAMpA2AhGiADIQUDQAJAIAUgACICKQMANwMAIAUgAi0ACDoACCAFKAIQIgAEQCAFIAA2AhQgABAvIAVBADYCGAsgBSACKAIQNgIQIAUgAigCFDYCFCAFIAIoAhg2AhggAkEANgIYIAJCADcDECAFIAIoAkQ2AkQgBSACKQI8NwI8IAUgAv0AAiz9CwIsIAUgAv0AAhz9CwIcIAUoAkgiBARAIAUoAkwiBiAEIgBHBEADQCAGQQxrIgAoAgAiDARAIAZBCGsgDDYCACAMEC8LIAAiBiAERw0ACyAFKAJIIQALIAUgBDYCTCAAEC8gBUEANgJQCyAFIAIoAkg2AkggBSACKAJMNgJMIAUgAigCUDYCUCACQQA2AlAgAkIANwJIIAUoAlQiBARAIAUoAlgiBiAEIgBHBEADQCAGQQxrIgAoAgAiDARAIAZBCGsgDDYCACAMEC8LIAAiBiAERw0ACyAFKAJUIQALIAUgBDYCWCAAEC8gBUEANgJcCyAFIAIoAlQ2AlQgBSACKAJYNgJYIAUgAigCXDYCXCACQQA2AlwgAkIANwJUIAUgAikCYDcCYCACIAdGBEAgByEFDAELIBggAiIFQegAayIAKwMgZA0BCwsgBSAIKQNANwMAIAUgCC0ASDoACCAFKAIQIgAEQCAFIAA2AhQgABAvCyAFIBM2AhggBSARNgIUIAUgEjYCECACIA82AhwgBSAYOQIgIAUgCP0AAxD9CwI4IAUgCP0AAwD9CwIoIAIoAkgiBARAIAUoAkwiBiAEIgBHBEADQCAGQQxrIgAoAgAiDwRAIAZBCGsgDzYCACAPEC8LIAAiBiAERw0ACyACKAJIIQALIAUgBDYCTCAAEC8LIAIgCzYCSCAFIAo2AlAgBSAONgJMIAUoAlQiAgRAIAUoAlgiBiACIgBHBEADQCAGQQxrIgAoAgAiBARAIAZBCGsgBDYCACAEEC8LIAAiBiACRw0ACyAFKAJUIQALIAUgAjYCWCAAEC8LIAUgGjcCYCAFIBQ2AlwgBSAVNgJYIAUgCTYCVAsgAyIAQegAaiICIQMgASACRw0ACwwECyACRQRAIAEgB0YNBCAQQQJrQQF2IgwhAANAAkAgDCAAIgRIDQAgByAAQegAbGohACAHIARBAXQiBkEBciICQegAbGohAwJAIBAgBkECaiIFTARAIAIhBQwBCyADKwMgIAMrA4gBZEUEQCACIQUMAQsgA0HoAGohAwsgACsDICIYIAMrAyBjDQAgCCAALQAIOgBIIAggACkDADcDQCAAKAIYIREgAEEANgIYIAAoAhAhEiAAKAIUIRMgAEIANwMQIAAoAhwhDyAIIAD9AAI4/QsDECAIIAD9AAIo/QsDACAAKAJUIRQgACgCUCEVIAAoAkwhDiAAKAJIIQogAP0MAAAAAAAAAAAAAAAAAAAAAP0LA0ggACgCXCEJIAAoAlghCyAAQgA3A1ggACkDYCEaA0AgACICIAMiACkDADcDACACIAAtAAg6AAggAigCECIDBEAgAiADNgIUIAMQLyACQQA2AhggAkIANwMQCyACIAAoAhA2AhAgAiAAKAIUNgIUIAIgACgCGDYCGCAAQQA2AhggAEIANwMQIAIgACgCRDYCRCACIAApAjw3AjwgAiAA/QACLP0LAiwgAiAA/QACHP0LAhwgAkHIAGogAEHIAGoQhwIgBSAMTARAIAcgBUEBdCIGQQFyIgJB6ABsaiEDAkAgECAGQQJqIgVMBEAgAiEFDAELIAMrAyAgAysDiAFkRQRAIAIhBQwBCyADQegAaiEDCyADKwMgIBhkRQ0BCwsgACAIKQNANwMAIAAgCC0ASDoACCAAKAIQIgIEQCAAIAI2AhQgAhAvCyAAIA82AhwgACARNgIYIAAgEzYCFCAAIBI2AhAgACAYOQIgIAAgCP0AAwD9CwIoIAAgCP0AAxD9CwI4IAAoAkgiBQRAIAAoAkwiAyAFIgZHBEADQCADQQxrIgIoAgAiBgRAIANBCGsgBjYCACAGEC8LIAIiAyAFRw0ACyAAKAJIIQYLIAAgBTYCTCAGEC8LIAAgCjYCSCAAIBU2AlAgACAONgJMIAAoAlQiBQRAIAAoAlgiAyAFIgZHBEADQCADQQxrIgIoAgAiBgRAIANBCGsgBjYCACAGEC8LIAIiAyAFRw0ACyAAKAJUIQYLIAAgBTYCWCAGEC8LIAAgFDYCVCAAIBo3AmAgACAJNgJcIAAgCzYCWAsgBEEBayEAIAQNAAsgDUHoAG4hAANAIAEhCSAIIActAAg6ADggCCAHKQMANwMwIAcoAhAhECAHKAIUIQ0gB0IANwMQIAcoAhghDCAHQQA2AhggCCAHKAJENgIoIAggBykCPDcDICAIIAf9AAIs/QsDECAIIAf9AAIc/QsDACAHKAJIIREgBygCTCESIAcoAlAhEyAHKAJUIQ8gB/0MAAAAAAAAAAAAAAAAAAAAAP0LA0ggBygCWCEUIAcoAlwhFSAHQgA3A1ggACILQQJrQQF2IQogBykDYCEaIAchA0EAIQEDQCABQQF0IgJBAXIhACABQegAbCADakHoAGohBAJAIAsgAkECaiIBTARAIAAhAQwBCyAEKwMgIAQrA4gBZEUEQCAAIQEMAQsgBEHoAGohBAsgAyAEKQMANwMAIAMgBC0ACDoACCADKAIQIgAEQCADIAA2AhQgABAvIANBADYCGCADQgA3AxALIAMgBCgCEDYCECADIAQoAhQ2AhQgAyAEKAIYNgIYIARBADYCGCAEQgA3AxAgAyAEKAJENgJEIAMgBCkCPDcCPCADIAT9AAIs/QsCLCADIAT9AAIc/QsCHCAEQcgAaiEWIAMoAkgiAgRAIAMoAkwiBiACIgBHBEADQCAGQQxrIgAoAgAiBQRAIAZBCGsgBTYCACAFEC8LIAAiBiACRw0ACyADKAJIIQALIAMgAjYCTCAAEC8gA0EANgJQIANCADcCSAsgAyAWKAIANgJIIAMgBCICKAJMNgJMIAMgAigCUDYCUCACQQA2AlAgFkIANwIAIAMoAlQiBQRAIAMoAlgiBiAFIgBHBEADQCAGQQxrIgAoAgAiDgRAIAZBCGsgDjYCACAOEC8LIAAiBiAFRw0ACyADKAJUIQALIAMgBTYCWCAAEC8gA0EANgJcIANCADcCVAsgAyACKAJUNgJUIAMgAigCWDYCWCADIAIoAlw2AlwgAkEANgJcIAJCADcCVCADIAIpAmA3AmAgAiEDIAEgCkwNAAsCQCAJQegAayIBIARGBEAgBCAIKQMwNwMAIAQgCC0AODoACCAEKAIQIgAEQCAEIAA2AhQgABAvCyAEIAw2AhggBCANNgIUIAQgEDYCECAEIAgoAig2AkQgBCAIKQMgNwI8IAQgCP0AAxD9CwIsIAQgCP0AAwD9CwIcIBYoAgAiBgRAIAIoAkwiBCAGIgNHBEADQCAEQQxrIgAoAgAiAwRAIARBCGsgAzYCACADEC8LIAAiBCAGRw0ACyAWKAIAIQMLIAIgBjYCTCADEC8LIAIgEzYCUCACIBI2AkwgFiARNgIAIAIoAlQiBgRAIAIoAlgiBCAGIgNHBEADQCAEQQxrIgAoAgAiAwRAIARBCGsgAzYCACADEC8LIAAiBCAGRw0ACyACKAJUIQMLIAIgBjYCWCADEC8LIAIgGjcCYCACIBU2AlwgAiAUNgJYIAIgDzYCVAwBCyAEIAEpAwA3AwAgBCABLQAIOgAIIAQoAhAiAARAIAQgADYCFCAAEC8gBEEANgIYIARCADcDEAsgBCABKAIQNgIQIAQgASgCFDYCFCAEIAEoAhg2AhggAUEANgIYIAFCADcDECAEIAEoAkQ2AkQgBCABKQI8NwI8IAQgAf0AAiz9CwIsIAQgAf0AAhz9CwIcIBYgCUEgayIOEIcCIAEgCC0AODoACCABIAgpAzA3AwAgASgCECIABEAgASAANgIUIAAQLwsgASAQNgIQIAEgDTYCFCABIAw2AhggASAIKAIoNgJEIAEgCCkDIDcCPCABIAj9AAMQ/QsCLCABIAj9AAMA/QsCHCAOKAIAIgYEQCAJQRxrIgooAgAiBSAGIgNHBEADQCAFQQxrIgAoAgAiAwRAIAVBCGsgAzYCACADEC8LIAAiBSAGRw0ACyAOKAIAIQMLIAogBjYCACADEC8LIA4gETYCACAJQegAayIKIBM2AlAgCiASNgJMIAooAlQiBgRAIAlBEGsiCSgCACIFIAYiA0cEQANAIAVBDGsiACgCACIDBEAgBUEIayADNgIAIAMQLwsgACIFIAZHDQALIAooAlQhAwsgCSAGNgIAIAMQLwsgCiAPNgJUIAogGjcCYCAKIBU2AlwgCiAUNgJYIARB6ABqIAdrIgBB6QBIDQAgBCsDICIYIAcgAEHoAG5BAmtBAXYiBUHoAGxqIgMrAyBjRQ0AIAggBC0ACDoAaCAIIAQpAwA3A2AgBCgCECEMIAQoAhQhESAEQgA3AxAgBCgCGCESIARBADYCGCAEKAIcIRMgCCAE/QACOP0LA1AgCCAE/QACKP0LA0AgAigCXCEPIAIoAlghFCACQgA3A1ggFigCACEVIAIoAkwhDiACKAJQIQogAigCVCEJIBb9DAAAAAAAAAAAAAAAAAAAAAD9CwMAIAIpA2AhGgNAIAQgAyICKQMANwMAIAQgAi0ACDoACCAEKAIQIgAEQCAEIAA2AhQgABAvIARBADYCGCAEQgA3AxALIAQgAigCEDYCECAEIAIoAhQ2AhQgBCACKAIYNgIYIAJBADYCGCACQgA3AxAgBCACKAJENgJEIAQgAikCPDcCPCAEIAL9AAIs/QsCLCAEIAL9AAIc/QsCHCAEKAJIIgMEQCAEKAJMIgYgAyIARwRAA0AgBkEMayIAKAIAIg0EQCAGQQhrIA02AgAgDRAvCyAAIgYgA0cNAAsgBCgCSCEACyAEIAM2AkwgABAvIARBADYCUCAEQgA3AkgLIAQgAigCSDYCSCAEIAIoAkw2AkwgBCACKAJQNgJQIAJBADYCUCACQgA3AkggBCgCVCIDBEAgBCgCWCIGIAMiAEcEQANAIAZBDGsiACgCACINBEAgBkEIayANNgIAIA0QLwsgACIGIANHDQALIAQoAlQhAAsgBCADNgJYIAAQLyAEQQA2AlwgBEIANwJUCyAEIAIoAlQ2AlQgBCACKAJYNgJYIAQgAigCXDYCXCACQQA2AlwgAkIANwJUIAQgAikCYDcCYCAFBEAgAiEEIAcgBUEBa0EBdiIFQegAbGoiAysDICAYZA0BCwsgAiAIKQNgNwMAIAIgCC0AaDoACCACKAIQIgAEQCACIAA2AhQgABAvCyACIBM2AhwgAiASNgIYIAIgETYCFCACIAw2AhAgAiAYOQIgIAIgCP0AA0D9CwIoIAIgCP0AA1D9CwI4IAIoAkgiAwRAIAIoAkwiBiADIgBHBEADQCAGQQxrIgAoAgAiBQRAIAZBCGsgBTYCACAFEC8LIAAiBiADRw0ACyACKAJIIQALIAIgAzYCTCAAEC8LIAIgCjYCUCACIA42AkwgAiAVNgJIIAIoAlQiAwRAIAIoAlgiBiADIgBHBEADQCAGQQxrIgAoAgAiBQRAIAZBCGsgBTYCACAFEC8LIAAiBiADRw0ACyACKAJUIQALIAIgAzYCWCAAEC8LIAIgGjcCYCACIA82AlwgAiAUNgJYIAIgCTYCVAsgC0EBayEAIAtBAkoNAAsMBAsgByAQQQF2QegAbGohBQJ/IA1B2asGTwRAIAcgByAQQQJ2QegAbCIAaiAFIAAgBWogCRDVAgwBCyAKKwMAIRkCQCAFKwMgIhggBysDIGRFBEBBACAYIBljRQ0CGiAFIAkQPkEBIAUrAyAgBysDIGRFDQIaIAcgBRA+DAELIBggGWMEQCAHIAkQPkEBDAILIAcgBRA+QQEgCisDACAFKwMgZEUNARogBSAJED4LQQILIQQgAkEBayECIAkhBgJAIAciCysDICIZIAUrAyAiGGQEQCAGIQAMAQsDQCAGQegAayIAIAtGBEAgC0HoAGohBiAZIAorAwBkDQUgBiAJRg0GA0AgBisDICAZYwRAIAYgCRA+IAZB6ABqIQYMBwsgBkHoAGoiBiAJRw0ACwwGCyAGQcgAayEXIAAhBiAXKwMAIBhkRQ0ACyALIAAQPiAEQQFqIQQLIAtB6ABqIgMgAE8NAQNAIAUrAyAhGANAIAMiBkHoAGohAyAGKwMgIBhkDQALA0AgAEHoAGsiACsDICAYZEUNAAsgACAGSQRAIAYhAwwDBSAGIAAQPiAAIAUgBSAGRhshBSAEQQFqIQQMAQsACwALIAcgB0HoAGogB0HQAWogAUHoAGsQ1AIaDAILAkAgAyAFRg0AIAUrAyAgAysDIGRFDQAgAyAFED4gBEEBaiEECyAERQRAIAsgAxCxBCEGIANB6ABqIgAgARCxBARAIAshACADIQEgBkUNBgwDCyAGDQQLIAMgC2tB6ABtIAEgA2tB6ABtSARAIAsgAyACEOoCIANB6ABqIQAMBAsgA0HoAGogASACEOoCIAshACADIQEMBAsgCSIAIAZGDQADQCALKwMgIRgDQCAGIgdB6ABqIQYgGCAHKwMgZEUNAAsDQCAYIABB6ABrIgArAyBkDQALIAAgB00NAiAHIAAQPgwACwALCwsLIAhB8ABqJAALpgcBDH8gACgCACIGIAEgBmsiDEF8cWohDQJAAkACQAJAAkACQCADIAJrIghBAEwNACAIQQJ1IgogACgCCCIHIAAoAgQiC2tBAnVMBEACQCALIA1rIghBAnUiASAKTgRAIAshBCADIQcMAQsgCyEEAkAgAiABQQJ0aiIHIANGDQAgByEBAkAgAyACIAhqIgVrQQRrIglBHEkNACAEIAVrQRBJDQAgBCAJQQJ2QQFqIg5B/P///wdxIglBAnQiBWohBCABIAVqIQFBACEFA0AgCyAFQQJ0Ig9qIAcgD2r9AAIA/QsCACAFQQRqIgUgCUcNAAsgCSAORg0BCwNAIAQgASgCADYCACAEQQRqIQQgAUEEaiIBIANHDQALCyAAIAQ2AgQgCEEATA0CCyAEIA0gCkECdCIDamsiCEECdSEJIAQhASAEIANrIgogC08NBiAGQX9zIAsgDEF8cSIBIAhqIgMgBmpBBGoiBSAFIAtJG2ogA2siA0EsSQ0EIAQgASAGaiAIamtBEEkNBCAEIANBAnZBAWoiDEH8////B3EiBkECdCIDaiEBIAMgCmohBUEAIQMDQCAEIANBAnQiDmogCiAOav0AAgD9CwIAIANBBGoiAyAGRw0ACyAGIAxGDQYMBQsgCyAGa0ECdSAKaiIEQYCAgIAETw0BQf////8DIAcgBmsiB0EBdSIFIAQgBCAFSRsgB0H8////B08bIgUEfyAFQYCAgIAETw0DIAVBAnQQMQVBAAsiCSAMQXxxaiIEIQcgAiADRwRAIAQgAiAIQXxx/AoAACAEIApBAnRqIQcLIAVBAnQgCWohBQJAIAEgBkYNACANIQECQCAMQQRrIgJBPEkNACAMQXxxIgMgBmogAyAJamtBEEkNACAEQRBrIQogAUEQayEMIAEgAkECdkEBaiIIQfz///8HcSICQQJ0IgNrIQEgBCADayEEQQAhAwNAIAogA0ECdCIJayAMIAlr/QACAP0LAgAgA0EEaiIDIAJHDQALIAIgCEYNAQsDQCAEQQRrIgQgAUEEayIBKAIANgIAIAEgBkcNAAsLIAcgDSALIA1rIgH8CgAAIAAgBTYCCCAAIAEgB2o2AgQgACAENgIAIAYEQCAGEC8LCw8LEDYACxBIAAsgCiEFIAQhAQsDQCABIAUoAgA2AgAgAUEEaiEBIAVBBGoiBSALSQ0ACwsgACABNgIEIAQgCUECdGsgDSAI/AoAACANIAIgByACa/wKAAAL6RoCCX8DfCMAQRBrIgMkAANAIAFBEGshBwNAIAAhBANAAkACQAJAAkACQAJAAkACQCABIARrIghBBHUiCQ4GBwcAAQQCAwsgAUEQayIAKwMAIAQrAwBkRQ0GIAMgBP0AAwD9CwMAIAQgACgCCDYCCCAEIAApAwA3AwAgACADKAIINgIIIAAgAykDADcDAAwGCyAEQRBqIQAgAUEQayIBKwMAIQwgBCsDECINIAQrAwBkRQRAIAwgDWRFDQYgAyAA/QADAP0LAwAgACABKAIINgIIIAAgASkDADcDACABIAMoAgg2AgggASADKQMANwMAIAQrAxAgBCsDAGRFDQYgAyAE/QADAP0LAwAgBCAAKAIINgIIIAQgACkDADcDACAAIAMoAgg2AgggACADKQMANwMADAYLIAwgDWQEQCADIAT9AAMA/QsDACAEIAEoAgg2AgggBCABKQMANwMAIAEgAygCCDYCCCABIAMpAwA3AwAMBgsgAyAE/QADAP0LAwAgBCAAKAIINgIIIAQgACkDADcDACAAIAMoAgg2AgggACADKQMANwMAIAErAwAgBCsDEGRFDQUgAyAA/QADAP0LAwAgACABKAIINgIIIAAgASkDADcDACABIAMoAgg2AgggASADKQMANwMADAULIAQgBEEQaiICIARBIGoiACAEQTBqIgUQ2QEaIAFBEGsiASsDACAEKwMwZEUNBCADIAX9AAMA/QsDACAFIAEoAgg2AgggBSABKQMANwMAIAEgAygCCDYCCCABIAMpAwA3AwAgBSsDACAAKwMAZEUNBCADIAD9AAMA/QsDACAAIAUoAgg2AgggACAFKQMANwMAIAUgAygCCDYCCCAFIAMpAwA3AwAgACsDACACKwMAZEUNBCADIAL9AAMA/QsDACACIAAoAgg2AgggAiAAKQMANwMAIAAgAygCCDYCCCAAIAMpAwA3AwAgBCsDECAEKwMAZEUNBCADIAT9AAMA/QsDACAEIAIoAgg2AgggBCACKQMANwMAIAIgAygCCDYCCCACIAMpAwA3AwAMBAsgCEHvA0wEQCAEQRBqIQAgBEEgaiEFIAQrAyAhDAJAIAQrAxAiDSAEKwMAIg5kRQRAIAwgDWRFDQEgAyAA/QADAP0LAwAgACAFQQhqKAIANgII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KAIAIgEEQCAAQZynAWogATYCACABEC8LIABBuJIBahClASAAQeD9AGoQpQEgAEGI6QBqEKUBIABBsNQAahClASAAQdg/ahClASAAQYArahClASAAQagWahClASAAQdABahClASAAKAKoASIBBEAgACABNgKsASABEC8LIAAoAoABIgMEQCAAKAKEASICIAMiAUcEQANAIAJBDGsgAkEQayICKAIIEJUBIAIgA0cNAAsgACgCgAEhAQsgACADNgKEASABEC8LIAAoAlgiAwRAIAAoAlwiAiADIgFHBEADQCACQQxrIAJBEGsiAigCCBCVASACIANHDQALIAAoAlghAQsgACADNgJcIAEQLwsgAAtDACABBEAgACABKAIAEPQCIAAgASgCBBD0AiABLAArQQBIBEAgASgCIBAvCyABLAAbQQBIBEAgASgCEBAvCyABEC8LCzEAIAEEQCAAIAEoAgAQ9QIgACABKAIEEPUCIAEsAB9BAEgEQCABKAIUEC8LIAEQLwsLx0cEF34XfwR7AX0jAEGQAWsiIyQAAkACQAJAAkACQAJAAkACQAJAAkACQAJAIAEoAjAiHSABKAIAIhpBJGwiG0GYmgFqKAIARyImDQAgATUCNCIDIAEpAxAgHa1+IBtBlJoBajQCAH9SDQAgATUCOCIFIAEpAxggA35SDQAgATUCPCABKQMgIAV+Ug0AIAIoAjAiGyACKAIAIhxBJGwiIkGYmgFqKAIARw0AIAI1AjQiAyACKQMQIButfiAiQZSaAWo0AgB/Ug0AIAI1AjgiBSACKQMYIAN+Ug0AIBogHEcNACACNQI8IAIpAyAgBX5RDQELAkACQAJAIBoOAgIAAQsgAikDKCIRIAIpAyAiDyACKQMYIhAgAikDECIMfn5+IAEpAygiDSABKQMgIgcgASkDGCIOIAEpAxAiCX5+flEEQAJAIAAoAgAOAw0ADQALIAIoAjwhISACKAI4IR8gAigCNCElIAEoAjwhKCABKAI4ISQgASgCNCEiIAAoAgghGyAAKAIEIScgAigCMCEaAkAgJg0AICKtIgMgCSAdrX5SDQAgJK0iBSADIA5+Ug0AICitIAUgB35SDQAgGiACKAIAIhxBJGwiHkGYmgFqKAIARw0AICWtIgMgDCAarX4gHkGUmgFqNAIAf1INACAfrSIFIAMgEH5SDQAgIa0g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ACAhrSIFIAwgGq1+ICZBlJoBajQCACILf1INACAgrSIJIAUgEH5SDQAgJK0gCSAPflINACAdQQRGBEAgAEUEQCAOQgBXDQogDUIAVw0KIBsgHE4NCiACKALAASEdIBsgB6dBAnQiAGwhISAfIBxrIABsIR8gGyAibCElIBwgG2tBAXEhJkEAIQIgHCAbQQFqIidGISkDQCAeIAinbCEkQgAhAwNAIAIgIWohGiAoIAOnbCEgICYEfyAaIB1qIAEoAsABICVqICBqICRqIAD8CgAAIAAgGmohGiAnBSAbCyECIClFBEADQCAaIB1qIAEoAsABIAIgImxqICBqICRqIAD8CgAAIB0gACAaaiIaaiABKALAASACQQFqICJsaiAgaiAkaiAA/AoAACAAIBpqIRogAkECaiICIBxHDQALCyAaIB9qIQIgA0IBfCIDIA1SDQALIA4gCEIBfCIIUg0ACwwKC0GxgBwgAHZBAXFFBEAgByALfyEDIA5CAFcNCiANQgBXDQogGyAcTg0KIABBJGxBpJoBaigCACEdIAIoAsABISQgGiADp2wiGiAbbCElIBogHyAca2whJiAHpyEgIBtBAWohJyAbICJsISkgHCAbayIqQQFxIStBACEAA0AgHiAIp2whIUIAIQMDQCAAICVqIQIgKCADp2whHyArBH8gASgCwAEgKWogH2ogIWogAiAkaiAgIB0RBQAgAiAaaiECICcFIBsLIQAgKkEBRwRAA0AgASgCwAEgACAibGogH2ogIWogAiAkaiAgIB0RBQAgASgCwAEgAEEBaiAibGogH2ogIWogJCACIBpqIgJqICAgHREFACACIBpqIQIgAEECaiIAIBxHDQALCyACICZqIQAgA0IBfCIDIA1SDQALIA4gCEIBfCIIUg0ACwwKCyAjQf4gNgJYICNByzM2AlQgI0HHJjYCUEGowgIoAgAiAEGl4wAgI0HQAGoQMAwKCwJAAkACQCAADgIAAQILIA5CAFcNCiANQgBXDQogGyAcTg0KIAdCAFcNCiAbIAenIgBsISYgAyAcrX0gB36nISkgHUEBRiAHQgtWcSEqIAdCA4MhCSACKALAASIgIABBAnRqISsgB0J8gyILpyEtICIgJWwgJ2wiAq0hBiAAIAJqQQNqrSEKICitIQwgHq0hEiABKALAASEhQQAhAUIAIQUDQCAF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ACgCACgCJBEBAAs2AgAgCkEQaiQACwoAIABBgIg1EHkLCgAgAEGIiDUQeQsfAQF/IAEoAgAQ+wMhAiAAIAEoAgA2AgQgACACNgIAC8AYAQl/IwBBkARrIgskACALIAo2AogEIAsgATYCjAQCQCAAIAtBjARqEEIEQCAFIAUoAgBBBHI2AgBBACEADAELIAtB9gE2AkggCyALQegAaiALQfAAaiALQcgAaiIPEFEiESgCACIBNgJkIAsgAUGQA2o2AmAjAEEQayIBJAAgD0IANwIAIA9BADYCCCABQRBqJAAjAEEQayIBJAAgC0E8aiIOQgA3AgAgDkEANgIIIAFBEGokACMAQRBrIgEkACALQTBqIg1CADcCACANQQA2AgggAUEQaiQAIwBBEGsiASQAIAtBJGoiDEIANwIAIAxBADYCCCABQRBqJAAjAEEQayIBJAAgC0EYaiIQQgA3AgAgEEEANgIIIAFBEGokACMAQRBrIgokACALAn8gAgRAIApBBGoiAiADELsDIgEgASgCACgCLBECACALIAooAgQ2AFwgAiABIAEoAgAoAiARAgAgDCACEIUBIAIQUBogAiABIAEoAgAoAhwRAgAgDSACEIUBIAIQUBogCyABIAEoAgAoAgwRAQA2AlggCyABIAEoAgAoAhARAQA2AlQgAiABIAEoAgAoAhQRAgAgDyACEGYgAhAyGiACIAEgASgCACgCGBECACAOIAIQhQEgAhBQGiABIAEoAgAoAiQRAQAMAQsgCkEEaiICIAMQugMiASABKAIAKAIsEQIAIAsgCigCBDYAXCACIAEgASgCACgCIBECACAMIAIQhQEgAhBQGiACIAEgASgCACgCHBECACANIAIQhQEgAhBQGiALIAEgASgCACgCDBEBADYCWCALIAEgASgCACgCEBEBADYCVCACIAEgASgCACgCFBECACAPIAIQZiACEDIaIAIgASABKAIAKAIYEQIAIA4gAhCFASACEFAaIAEgASgCACgCJBEBAAs2AhQgCkEQaiQAIAkgCCgCADYCACAEQYAEcSESQQAhA0EAIQEDQCABIQICQAJAAkACQCADQQRGDQAgACALQYwEahBCDQBBACEKAkACQAJAAkACQAJAIAtB3ABqIANqLAAADgUBAAQDBQkLIANBA0YNByAHQQECfyAAKAIAIgEoAgwiBCAB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AgggAkEQaiQAIAEgAS0AC0EHdgR/IAEoAghB/////wdxQQFrBUEKCxA6IAACfyABLQALQQd2BEAgASgCAAwBCyABCyICNgK0ASAAIABBEGo2AgwgAEEANgIIA0ACQCAAQcwCaiAAQcgCahBCDQAgACgCtAECfyABLQALQQd2BEAgASgCBAwBCyABLQALQf8AcQsgAmpGBEACfyABLQALQQd2BEAgASgCBAwBCyABLQALQf8AcQshAyABAn8gAS0AC0EHdgRAIAEoAgQMAQsgAS0AC0H/AHELQQF0EDogASABLQALQQd2BH8gASgCCEH/////B3FBAWsFQQoLEDogACADAn8gAS0AC0EHdgRAIAEoAgAMAQsgAQsiAmo2ArQBCwJ/IABBzAJqIggoAgAiAygCDCIJIAMoAhBGBEAgAyADKAIAKAIkEQEADAELIAkoAgALIAYgAiAAQbQBaiAAQQhqIAAoAsQCIABBxAFqIABBEGogAEEMaiAHEL4BDQAgCBBdGgwBCwsCQAJ/IAAtAM8BQQd2BEAgACgCyAEMAQsgAC0AzwFB/wBxC0UNACAAKAIMIgMgAEEQamtBnwFKDQAgACADQQRqNgIMIAMgACgCCDYCAAsgBSACIAAoArQBIAQgBhDZAzYCACAAQcQBaiAAQRBqIAAoAgwgBBBlIABBzAJqIABByAJqEEIEQCAEIAQoAgBBAnI2AgALIAAoAswCIQogARAyGiAAQcQBahAyGiAAQdACaiQAIAoLRQECfyMAQRBrIgMkACADIAE2AgwgAyACNgIIIANBBGogA0EMahB9IQQgAEHcFSADKAIIEOYDIQAgBBB8IANBEGokACAAC64CAgR+Bn8jAEEgayIIJAACQAJAAkAgASACRwRAIwNBHGoiDCgCACENIAxBADYCACMAQRBrIgkkABBEGiMAQRBrIgokACMAQRBrIgskACALIAEgCEEcakECELgCIAspAwAhBCAKIAspAwg3AwggCiAENwMAIAtBEGokACAKKQMAIQQgCSAKKQMINwMIIAkgBDcDACAKQRBqJAAgCSkDACEEIAggCSkDCDcDECAIIAQ3AwggCUEQaiQAIAgpAxAhBCAIKQMIIQUgDCgCACIBRQ0BIAgoAhwgAkcNAiAFIQYgBCEHIAFBxABHDQMMAgsgA0EENgIADAILIAwgDTYCACAI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AAwBCyADED8LIgAgBmotACEEQCAEIAhqIAA6AAAgBEEBaiEEDAEFQQAhBSAIIgAhCgwDCwALAAsDQAJ/IAMoAgQiACADKAJoRwRAIAMgAEEBajYCBCAALQAADAELIAMQPwsgBmotACENAAtBACEAQQAhCkEAIQULIAMoAgQhAiADKQNwQgBZBEAgAyACQQFrIgI2AgQLIAMpA3ggAiADKAIsa6x8IhVQDQIgCSAUIBVRckUNAiAMBEAgCCAANgIACwJAIAtB4wBGDQAgBQRAIAUgBEECdGpBADYCAAsgCkUEQEEAIQoMAQsgBCAKakEAOgAACyAFIQALIAMoAgQgAygCLGusIAMpA3ggFnx8IRYgDiAIQQBHaiEOCyABQQFqIQQgAS0AASIBDQEMCAsLIAUhAAwBC0EBIQdBACEKQQAhAAwCCyAMIQcMAwsgDCEHCyAODQELQX8hDgsgB0UNACAKEC8gABAvCyARBEAgAxB/CyAGQbACaiQAIANBkAFqJAAgDgtDAAJAIABFDQACQAJAAkACQCABQQJqDgYAAQICBAMECyAAIAI8AAAPCyAAIAI9AQAPCyAAIAI+AgAPCyAAIAI3AwALC7UDAgN/AX4jAEEgayIDJAACQCABQv///////////wCDIgVCgICAgICAwMA/fSAFQoCAgICAgMC/wAB9VARAIAFCGYinIQQgAFAgAUL///8PgyIFQoCAgAhUIAVCgICACFEbRQRAIARBgYCAgARqIQIMAgsgBEGAgICABGohAiAAIAVCgICACIWEQgBSDQEgAiAEQQFxaiECDAELIABQIAVCgICAgICAwP//AFQgBUKAgICAgIDA//8AURtFBEAgAUIZiKdB////AXFBgICA/gdyIQIMAQtBgICA/AchAiAFQv///////7+/wABWDQBBACECIAVCMIinIgRBkf4ASQ0AIANBEGogACABQv///////z+DQoCAgICAgMAAhCIFIARBgf4AaxBnIAMgACAFQYH/ACAEaxCwASADKQMIIgBCGYinIQIgAykDACADKQMQIAMpAxiEQgBSrYQiBVAgAEL///8PgyIAQoCAgAhUIABCgICACFEbRQRAIAJBAWohAgwBCyAFIABCgICACIWEQgBSDQAgAkEBcSACaiECCyADQSBqJAAgAiABQiCIp0GAgICAeHFyvguNBAIF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ASACQv///////////wCDIgsgAyAEQv///////////wCDIgoQrwFBAEwEQCABIAsgAyAKEK8BBEAgASEEDAILIAVB8ABqIAEgAkIAQgAQSyAFKQN4IQIgBSkDcCEEDAELIARCMIinQf//AXEhBiAHBH4gAQUgBUHgAGogASALQgBCgICAgICAwLvAABBLIAUpA2giC0IwiKdB+ABrIQcgBSkDYAshBCAGRQRAIAVB0ABqIAMgCkIAQoCAgICAgMC7wAAQSyAFKQNYIgpCMIinQfgAayEGIAUpA1AhAwsgCkL///////8/g0KAgICAgIDAAIQhDCALQv///////z+DQoCAgICAgMAAhCELIAYgB0gEQANAAn4gCyAMfSADIARWrX0iCkIAWQRAIAogBCADfSIEhFAEQCAFQSBqIAEgAkIAQgAQSyAFKQMoIQIgBSkDICEEDAULIApCAYYgBEI/iIQMAQsgC0IBhiAEQj+IhAshCyAEQgGGIQQgB0EBayIHIAZKDQALIAYhBwsCQCALIAx9IAMgBFatfSIKQgBTBEAgCyEKDAELIAogBCADfSIEhEIAUg0AIAVBMGogASACQgBCABBLIAUpAzghAiAFKQMwIQQMAQsgCkL///////8/WARAA0AgBEI/iCENIAdBAWshByAEQgGGIQQgDSAKQgGGhCIKQoCAgICAgMAAVA0ACwsgCEGAgAJxIQYgB0EATARAIAVBQGsgBCAKQv///////z+DIAdB+ABqIAZyrUIwhoRCAEKAgICAgIDAwz8QSyAFKQNIIQIgBSkDQCEEDAELIApC////////P4MgBiAHcq1CMIaEIQILIAAgBDcDACAAIAI3AwggBUGAAWokAAuqDwIFfw9+IwBB0AJrIgUkACAEQv///////z+DIQsgAkL///////8/gyEKIAIgBIVCgICAgICAgICAf4MhDSAEQjCIp0H//wFxIQgCQAJAIAJCMIinQf//AXEiCUH//wFrQYKAfk8EQCAIQf//AWtBgYB+Sw0BCyABUCACQv///////////wCDIgxCgICAgICAwP//AFQgDEKAgICAgIDA//8AURtFBEAgAkKAgICAgIAghCENDAILIANQIARC////////////AIMiAkKAgICAgIDA//8AVCACQoCAgICAgMD//wBRG0UEQCAEQoCAgICAgCCE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IQMMAgsgBEEQaiABIAJCAEKAgICAgICA//8AEEtB/f8CIAMgA0H9/wJOG0H+/wFrIQMgBCkDGCECIAQpAxAhAQwBCyADQYGAf0oNACAEQUBrIAEgAkIAQoCAgICAgIA5EEsgBCkDSCECIAQpA0AhASADQfSAfksEQCADQY3/AGohAwwBCyAEQTBqIAEgAkIAQoCAgICAgIA5EEtB6IF9IAMgA0HogX1MG0Ga/gFqIQMgBCkDOCECIAQpAzAhAQsgBCABIAJCACADQf//AGqtQjCGEEsgACAEKQMINwMIIAAgBCkDADcDACAEQdAAaiQACzUAIAAgATcDACAAIAJC////////P4MgBEIwiKdBgIACcSACQjCIp0H//wFxcq1CMIaENwMIC8ABAgF/An5BfyEDAkAgAEIAUiABQv///////////wCDIgRCgICAgICAwP//AFYgBEKAgICAgIDA//8AURsNACACQv///////////wCDIgVCgICAgICAwP//AFYgBUKAgICAgIDA//8AUnENACAAIAQgBYSEUARAQQAPCyABIAKDQgBZBEAgASACUiABIAJTcQ0BIAAgASAChYRCAFIPCyAAQgBSIAEgAlUgASACURsNACAAIAEgAoWEQgBSIQMLIAMLSwECfyAAKAIAIgEEQAJ/IAEoAgwiAiABKAIQRgRAIAEgASgCACgCJBEBAAwBCyACKAIAC0F/RwRAIAAoAgBFDwsgAEEANgIAC0EBC0sBAn8gACgCACIBBEACfyABKAIMIgIgASgCEEYEQCABIAEoAgAoAiQRAQAMAQsgAi0AAAtBf0cEQCAAKAIARQ8LIABBADYCAAtBAQukAQEDfyABQQhLBEBBBCABIAFBBE0bIQFBASAAIABBAU0bIQADQAJAIAAgAWpBAWtBACABa3EiAiAAIAAgAkkbIQNBACEEIwBBEGsiAiQAAkAgAUEDcQ0AIAMgAXANACACQQxqIAEgAxCDBCEDQQAgAigCDCADGyEECyACQRBqJAAgBCICDQBB/Jc1/hACACIDRQ0AIAMRCQAMAQsLIAIPCyAAEDELCQAgAUEBEPIDCxMAIAFBCEsEQCAAEC8PCyAAEC8LhgEBA38jAEEQayIEJAAjAEEgayIDJAAgA0EYaiAAIAEQvgIgA0EQaiADQQxqIAMoAhggAygCHCACEL0CIAMg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NwIAQbyCNUKAoICAgIAENwIAQYyGNUECNgIAIAFBDGoiAkEANgIAIwBBIGsiAEIANwMYIABCADcDECAAQgA3AwhBkIY1IAApAwg3AgBBoIY1IAApAxg3AgBBmIY1IAApAxA3AgAgAgRAQZCGNSACKAIANgIAC0G4gjUgAUEIakFwcUHYqtWqBXM2AgALQcCGNRBSGiABQRBqJAALEgAgAEUEQEEADwsgACABEMMCCxAAIAAgASACQQBBABDEAhoLvAIAAkACQAJAAkACQAJAAkACQAJAAkACQCABQQlrDhIACAkKCAkBAgMECgkKCggJBQYHCyACIAIoAgAiAUEEajYCACAAIAEoAgA2AgAPCyACIAIoAgAiAUEEajYCACAAIAEyAQA3AwAPCyACIAIoAgAiAUEEajYCACAAIAEzAQA3AwAPCyACIAIoAgAiAUEEajYCACAAIAEwAAA3AwAPCyACIAIoAgAiAUEEajYCACAAIAExAAA3AwAPCyACIAIoAgBBB2pBeHEiAUEIajYCACAAIAErAwA5AwAPCyAAIAIgAxECAAsPCyACIAIoAgAiAUEEajYCACAAIAE0AgA3AwAPCyACIAIoAgAiAUEEajYCACAAIAE1AgA3AwAPCyACIAIoAgBBB2pBeHEiAUEIajYCACAAIAEpAwA3AwALcgEDfyAAKAIALAAAQTBrQQpPBEBBAA8LA0AgACgCACEDQX8hASACQcyZs+YATQRAQX8gAywAAEEwayIBIAJBCmwiAmogASACQf////8Hc0obIQELIAAgA0EBajYCACABIQIgAywAAUEwa0EKSQ0ACyACC5kTAhZ/AX4jAEHQAGsiCCQAIAggATYCTCAIQTdqIRggCEE4aiESAkACQAJAA0BBACEHA0AgASENIAcgEUH/////B3NKDQIgByARaiERAkACQAJAIAEiBy0AACIJBEADQAJAAkAgCUH/AXEiAUUEQCAHIQEMAQsgAUElRw0BIAchCQNAIAktAAFBJUcEQCAJIQEMAgsgB0EBaiEHIAktAAIhGiAJQQJqIgEhCSAaQSVGDQALCyAHIA1rIgcgEUH/////B3MiGUoNCCAABEAgACANIAcQYwsgBw0GIAggATYCTCABQQFqIQdBfyEOAkAgASwAAUEwayILQQpPDQAgAS0AAkEkRw0AIAFBA2ohByALIQ5B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BCIcQQR2ciEWIBNBBGstAABBAnZBMHEgHEEPcXIhEwsgAyATs5QiBEMAAAAAXARAIAJBBXQiEyAUQeABaiIYaiAbKgIAIBazlP0TIiAgACACQQd0av0AAgD95AEgBP0TIiH95wH9DAAAQEsAAEBLAABASwAAQEv95AH9DP//fwD//38A//9/AP//fwD9Tv0MDwBAAA8AQAAPAEAADwBAAP22Af0MAABAAAAAQAAAAEAAAABAAP24Af0MAABASwAAQEsAAEBLAABAS/0NAAQIDAAAAAAAAAAAAAAAAP1aAgAAIBggE0EEciIWaiAgIAAgFkECdGr9AAIA/eQBICH95wH9DAAAQEsAAEBLAABASwAAQEv95AH9DP//fwD//38A//9/AP//fwD9Tv0MDwBAAA8AQAAPAEAADwBAAP22Af0MAABAAAAAQAAAAEAAAABAAP24Af0MAABASwAAQEsAAEBLAABAS/0NAAQIDAAAAAAAAAAAAAAAAP1aAgAAIBggE0EIciIWaiAgIAAgFkECdGr9AAIA/eQBICH95wH9DAAAQEsAAEBLAABASwAAQEv95AH9DP//fwD//38A//9/AP//fwD9Tv0MDwBAAA8AQAAPAEAADwBAAP22Af0MAABAAAAAQAAAAEAAAABAAP24Af0MAABASwAAQEsAAEBLAABAS/0NAAQIDAAAAAAAAAAAAAAAAP1aAgAAIBggE0EMciIWaiAgIAAgFkECdGr9AAIA/eQBICH95wH9DAAAQEsAAEBLAABASwAAQEv95AH9DP//fwD//38A//9/AP//fwD9Tv0MDwBAAA8AQAAPAEAADwBAAP22Af0MAABAAAAAQAAAAEAAAABAAP24Af0MAABASwAAQEsAAEBLAABAS/0NAAQIDAAAAAAAAAAAAAAAAP1aAgAAIBggE0EQciIWaiAgIAAgFkECdGr9AAIA/eQBICH95wH9DAAAQEsAAEBLAABASwAAQEv95AH9DP//fwD//38A//9/AP//fwD9Tv0MDwBAAA8AQAAPAEAADwBAAP22Af0MAABAAAAAQAAAAEAAAABAAP24Af0MAABASwAAQEsAAEBLAABAS/0NAAQIDAAAAAAAAAAAAAAAAP1aAgAAIBggE0EUciIWaiAgIAAgFkECdGr9AAIA/eQBICH95wH9DAAAQEsAAEBLAABASwAAQEv9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Rw0ACyAHKAJIIQILIAMgCDYCTCACEC8LIAcgETYCSCADIA82AlAgAyAONgJMIAMoAlQiBwRAIAMoAlgiBSAHIgJHBEADQCAFQQxrIgIoAgAiCARAIAVBCGsgCDYCACAIEC8LIAIiBSAHRw0ACyADKAJUIQILIAMgBzYCWCACEC8LIAMgEDYCVCADIBU3AmAgAyAMNgJcIAMgDTYCWCASQQFqIhJBCEcNACAEQegAaiABRiEDDAILIAQiBUHoAGoiAiEEIAEgAkcNAAtBASEDCyAGQTBqJAAgAwupCgIHfwN8IwBBEGsiAiQAQQEhBgJAAkACQAJAAkACQCABIABrQQR1DgYFBQABAgMECyABQRBrIgErAwAgACsDAGRFDQQgAiAA/QADAP0LAwAgACABKAIINgIIIAAgASkDADcDACABIAIoAgg2AgggASACKQMANwMADAQLIABBEGohAyABQRBrIgErAwAhCSAAKwMQIgogACsDAGRFBEAgCSAKZEUNBCACIAP9AAMA/QsDACADIAEoAgg2AgggAyABKQMANwMAIAEgAigCCDYCCCABIAIpAwA3AwAgACsDECAAKwMAZEUNBCACIAD9AAMA/QsDACAAIAMoAgg2AgggACADKQMANwMAIAMgAigCCDYCCCADIAIpAwA3AwAMBAsgCSAKZARAIAIgAP0AAwD9CwMAIAAgASgCCDYCCCAAIAEpAwA3AwAgASACKAIINgIIIAEgAikDADcDAAwECyACIAD9AAMA/QsDACAAIAMoAgg2AgggACADKQMANwMAIAMgAigCCDYCCCADIAIpAwA3AwAgASsDACAAKwMQZEUNAyACIAP9AAMA/QsDACADIAEoAgg2AgggAyABKQMANwMAIAEgAigCCDYCCCABIAIpAwA3AwAMAwsgACAAQRBqIABBIGogAUEQaxDZARoMAgsgACAAQRBqIgQgAEEgaiIDIABBMGoiBRDZARogAUEQayIBKwMAIAArAzBkRQ0BIAIgBf0AAwD9CwMAIAUgASgCCDYCCCAFIAEpAwA3AwAgASACKAIINgIIIAEgAikDADcDACAFKwMAIAMrAwBkRQ0BIAIgA/0AAwD9CwMAIAMgBSgCCDYCCCADIAUpAwA3AwAgBSACKAIINgIIIAUgAikDADcDACADKwMAIAQrAwBkRQ0BIAIgBP0AAwD9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/QwAACDBAAAgwQAAIMEAACDB/QsCACAEQQRqIgQgAUcNAAsgASIJIAJGDQELIAIgCUF/c2ohIyAFBEADQCADIAkgCmwgAGpBAnRqQYCAgIl8NgIAIAlBAWohCSALQQFqIgsgBUcNAAsLICNBA0kNAANAIAMgCSAKbCAAakECdGpBgICAiXw2AgAgAyAJQQFqIApsIABqQQJ0akGAgICJfDYCACADIAlBAmogCmwgAGpBAnRqQYCAgIl8NgIAIAMgCUEDaiAKbCAAakECdGpBgICAiXw2AgAgCUEEaiIJIAJHDQALCyAAIAZqIgAgCkgNAAsLIAwoAggiAARAIAwgADYCDCAAEC8LIA8EQCAPEC8LIAxBIGokAAvFBAEGfyAABEAgACgCqAEiAQRAIAEQrgELIAAoAqwBIgEEQCABEKcBCyAAKAKAAiIBBEAgASgCbCICBEAgAhCuASABKAJwEKcBIAFBADYCbAsgASgClAEiAgRAIAIQrgEgASgCmAEQpwEgAUEANgKUAQsgASgCyAEhBSABKALEASECIAEoAsABIQMgASgCvAEhBCABKAK4ASIGBEAgBhAvCyAEBEAgBBAvCyADBEAgAxAvCyACBEAgAigCACIDBEBBACEEA0AgAxAvIAIgBEEBaiIEQQJ0aigCACIDDQALCyACEC8LIAUEQCAFEC8LIAEoApSnASICBEAgAhCPASABQaSnAWooAgAQpwEgAUEANgKUpwELIAEoAqinASICBEAgAhCPASABQbinAWooAgAQpwEgAUEANgKopwELIAEoArynASICBEAgAhCPASABQcynAWooAgAQpwEgAUEANgK8pwELIAEoAtCnASICBEAgAhCPASABQeCnAWooAgAQpwEgAUEANgLQpwELIAEoApCnASICBEAgAiACKAIEEQAACyABEPMCEC8LIAAoAoQCIgEEQCABIAEoAgQRAAALIAAsAJMCQQBIBEAgACgCiAIQLwsgAEHQAWogACgC1AEQjwIgAEHEAWogACgCyAEQjgIgAEG0AWogACgCuAEQjQIgACgCnAEiAQRAIAAgATYCoAEgARAvCyAAKAKQASIBBEAgACABNgKUASABEC8LIAAoAlgiAQRAIAAgATYCXCABEC8LIAAQLwsLlgMBB38gAAJ/AkACQCABKAIEIgRFBEAgAUEEaiIGIQIMAQsg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IABB4A9qKAIANgIAIABBsBtqIAApAtgPNwMAIABBADoAyg8gAEHo6gE7AcgPIABBAjoA0w8gAEHED2oiAkHIGC0AADoAACAAQQk6AMcPIABBGzYCuA8gAEEAOgDFDyAAQcAYKQAAIhM3ArwPIABBxBtqIABB0A9qKAIANgIAIAAgACkCyA83ArwbIABByBtqQRs2AgAgAEHUG2ogAigCADYCACAAQcwbaiATNwIAIABBADoArg8gAEH0wgE7AawPIABBAjoAtw8gAEGkD2pBlxotAAA6AAAgAEEFOgCrDyAAQRw2ApwPIABBADoApQ8gAEGTGigAADYCoA8gAEHgG2ogAEG0D2ooAgA2AgAgACAAKQKsDzcD2BsgAEHkG2pBHDYCACAAQfAbaiAAQagPaigCADYCACAAQegbaiAAKQKgDzcDACAAQQA6AJIPIABB7t4BOwGQDyAAQQI6AJsPIABBjA9qIgJBoBktAAA6AAAgAEEJOgCPDyAAQR02AoAPIABBADoAjQ8gAEGYGSkAACITNwKEDyAAQfwbaiAAQZgPaigCADYCACAAIAApApAPNwL0GyAAQYAcakEdNgIAIABBjBxqIAIoAgA2AgAgAEGEHGogEzcCACAAQQA6APYOIABB9NABOwH0DiAAQQI6AP8OIABB7A5qQQA6AAAgAEEEOgDzDiAAQR42AuQOIABB9NCFywY2AugOIABBmBxqIABB/A5qKAIANgIAIAAgACkC9A43A5AcIABBnBxqQR42AgAgAEGoHGogAEHwDmooAgA2AgAgAEGgHGogACkC6A43AwAgAEEAOgDaDiAAQfXkATsB2A4gAEECOgDjDiAAQdAOakEAOgAAIABBBDoA1w4gAEEfNgLIDiAAQfXkkasHNgLMDiAAQbQcaiAAQeAOaigCADYCACAAIAApAtgONwKsHCAAQbgcakEfNgIAIABBxBxqIABB1A5qKAIANgIAIABBvBxqIAApAswONwIAIABBADoAvg4gAEHo5AE7AbwOIABBAjoAxw4gAEG4DmoiAkEAOgAAIABBCDoAuw4gAEEgNgKsDiAAQuPkvYvGrtqw7gA3ArAOIABB0BxqIABBxA5qKAIANgIAIAAgACkCvA43A8gcIABB1BxqQSA2AgAgAEHgHGogAigCADYCACAAQdgcakLj5L2Lxq7asO4ANwMAIABB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AoAJIABBADoAigkgAEHRHCgAADYChAkgAEGMImogAEGYCWooAgA2AgAgACAAKQKQCTcChCIgAEGQImpBOTYCACAAQZwiaiAAQYwJaigCADYCACAAQZQiaiAAKQKECTcCACAAQQA6APYIIABB8+IBOwH0CCAAQQI6AP8IIABB8AhqIgJBADoAACAAQQg6APMIIABBOjYC5AggAELh2ImL5q3asO4ANwLoCCAAQagiaiAAQfwIaigCADYCACAAIAApAvQINwOgIiAAQawiakE6NgIAIABBuCJqIAIoAgA2AgAgAEGwImpC4diJi+at2rDuADcDACAAQQA6ANoIIABB8+4BOwHYCCAAQQI6AOMIIABBzwhqQaIbKAAANgAAIABBBzoA1wggAEE7NgLICCAAQQA6ANMIIABBnxsoAAA2AswIIABBxCJqIABB4AhqKAIANgIAIAAgACkC2Ag3ArwiIABByCJqQTs2AgAgAEHUImogAEHUCGooAgA2AgAgAEHMImogACkCzAg3AgAgAEEAOgC+CCAAQefYATsBvAggAEECOgDHCCAAQbgIaiICQQA6AAAgAEEIOgC7CCAAQTw2AqwIIABC58Kxy7as2rDuADcCsAggAEHgImogAEHECGooAgA2AgAgACAAKQK8CDcD2CIgAEHkImpBPDYCACAAQfAiaiACKAIANgIAIABB6CJqQufCscu2rNqw7gA3AwAgAEEAOgCiCCAAQe3kATsBoAggAEECOgCrCCAAQZcIakHAGygAADYAACAAQQc6AJ8IIABBPTYCkAggAEEAOgCbCCAAQb0bKAAANgKUCCAAQfwiaiAAQagIaigCADYCACAAIAApAqAINwL0IiAAQYAjakE9NgIAIABBjCNqIABBnAhqKAIANgIAIABBhCNqIAApApQINwIAIABBADoAhgggAEHwwgE7AYQIIABBAjoAjwggAEHVGygAADYA+wcgAEEHOgCDCCAAQT42AvQHIABBADoA/wcgAEHSGygAADYC+AcgAEGYI2ogAEGMCGooAgA2AgAgACAAKQKECDcDkCMgAEGcI2pBPjYCACAAQagjaiAAQYAIaigCADYCACAAQaAjaiAAKQL4BzcDACAAQQA6AOoHIABB89IBOwHoByAAQQI6APMHIABB5SgoAAA2AN8HIABBBzoA5wcgAEE/NgLYByAAQQA6AOMHIABB4igoAAA2AtwHIABBtCNqIAAoAvAHNgIAIAAgACkC6Ac3AqwjIABBuCNqQT82AgAgAEHEI2ogACgC5Ac2AgAgAEG8I2ogACkC3Ac3AgAgAEEAOgDOByAAQevaATsBzAcgAEECOgDXByAAQaoULQAAOgDEByAAQQU6AMsHIABBwAA2ArwHIABBADoAxQcgAEGmFCgAADYCwAcgAEHQI2ogACgC1Ac2AgAgACAAKQLMBzcDyCMgAEHUI2pBwAA2AgAgAEHgI2ogACgCyAc2AgAgAEHYI2ogACkCwAc3AwAgAEEAOgCyByAAQfPcATsBsAcgAEECOgC7ByAAQdooLQAAOgCoByAAQQU6AK8HIABBwQA2AqAHIABBADoAqQcgAEHWKCgAADYCpAcgAEHsI2ogACgCuAc2AgAgACAAKQKwBzcC5CMgAEHwI2pBwQA2AgAgAEH8I2ogACgCrAc2AgAgAEH0I2ogACkCpAc3AgAgAEEAOgCWByAAQfneATsBlAcgAEECOgCfByAAQYQpLwAAOwGMByAAQQY6AJMHIABBwgA2AoQHIABBADoAjgcgAEGAKSgAADYCiAcgAEGIJGogACgCnAc2AgAgACAAKQKUBzcDgCQgAEGMJGpBwgA2AgAgAEGYJGogACgCkAc2AgAgAEGQJGogACkCiAc3AwAgAEEAOgD6BiAAQfPeATsB+AYgAEECOgCDByAAQbIbLwAAOwHwBiAAQQY6APcGIABBwwA2AugGIABBADoA8gYgAEGuGygAADYC7AYgAEGkJGogACgCgAc2AgAgACAAKQL4BjcCnCQgAEGoJGpBwwA2AgAgAEG0JGogACgC9AY2AgAgAEGsJGogACkC7AY3AgAgAEEAOgDeBiAAQeHMATsB3AYgAEECOgDnBiAAQcMQLQAAOgDYBiAAQQk6ANsGIABBxAA2AswGIABBADoA2QYgAEG7ECkAACITNwLQBiAAQcAkaiAAKALkBjYCACAAIAApAtwGNwO4JCAAQcQkakHEADYCACAAQdAkaiAAKALYBjYCACAAQcgkaiATNwMAIABBADoAwgYgAEHvxgE7AcAGIABBAjoAywYgAEHsFygAADYAtwYgAEEHOgC/BiAAQcUANgKwBiAAQQA6ALsGIABB6RcoAAA2ArQGIABB3CRqIAAoAsgGNgIAIAAgACkCwAY3AtQkIABB4CRqQcUANgIAIABB7CRqIAAoArwGNgIAIABB5CRqIAApArQGNwIAIABBADoApgYgAEHrwgE7AaQGIABBAjoArwYgAEEAOgCgBiAAQQg6AKMGIABBxgA2ApQGIABC58q9k/es2rDuADcCmAYgAEH4JGogACgCrAY2AgAgACAAKQKkBjcD8CQgAEH8JGpBxgA2AgAgAEGIJWogACgCoAY2AgAgAEGAJWpC58q9k/es2rDuADcDACAAQQA6AIoGIABB4soBOwGIBiAAQQI6AJMGIABBohgvAAA7AYQGIABBCjoAhwYgAEHHADYC+AUgAEEAOgCGBiAAQZoYKQAAIhM3AvwFIABBlCVqIAAoApAGNgIAIAAgACkCiAY3AowlIABBmCVqQccANgIAIABBpCVqIAAoAoQGNgIAIABBnCVqIBM3AgAgAEEAOgDuBSAAQfTOATsB7AUgAEECOgD3BSAAQfIaLQAAOgDkBSAAQQU6AOsFIABByAA2AtwFIABBADoA5QUgAEHuGigAADYC4AUgAEGwJWogACgC9AU2AgAgACAAKQLsBTcDqCUgAEG0JWpByAA2AgAgAEHAJWogACgC6AU2AgAgAEG4JWogACkC4AU3AwAgAEEAOgDSBSAAQfPIATsB0AUgAEECOgDbBSAAQckbLwAAOwHIBSAAQQY6AM8FIABByQA2AsAFIABBADoAygUgAEHFGygAADYCxAUgAEHMJWogACgC2AU2AgAgACAAKQLQBTcCxCUgAEHQJWpByQA2AgAgAEHcJWogACgCzAU2AgAgAEHUJWogACkCxAU3AgAgAEEAOgC2BSAAQefqATsBtAUgAEECOgC/BSAAQQA6ALAFIABBCDoAswUgAEHKADYCpAUgAELn6qmLpq6YuukANwKoBSAAQeglaiAAKAK8BTYCACAAIAApArQFNwPgJSAAQewlakHKADYCACAAQfglaiAAKAKwBTYCACAAQfAlakLn6qmLpq6YuukANwMAIABBADoAmgUgAEHh2gE7AZgFIABBAjoAowUgAEGtJigAADYAjwUgAEEHOgCXBSAAQcsANgKIBSAAQQA6AJMFIABBqiYoAAA2AowFIABBhCZqIAAoAqAFNgIAIAAgACkCmAU3AvwlIABBiCZqQcsANgIAIABBlCZqIAAoApQFNgIAIABBjCZqIAApAowF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wAI3AwAgAEEAOgCyAiAAQfTYATsBsAIgAEECOgC7AiAAQfgcKAAANgCnAiAAQQc6AK8CIABB2QA2AqACIABBADoAqwIgAEH1HCgAADYCpAIgAEGMKWogACgCuAI2AgAgACAAKQKwAjcChCkgAEGQKWpB2QA2AgAgAEGcKWogACgCrAI2AgAgAEGUKWogACkCpAI3AgAgAEEAOgCWAiAAQe3OATsBlAIgAEECOgCfAiAAQQA6AJACIABBCDoAkwIgAEHaADYChAIgAELtwrGL9qzYufkANwKIAiAAQagpaiAAKAKcAjYCACAAIAApApQCNwOgKSAAQawpakHaADYCACAAQbgpaiAAKAKQAjYCACAAQbApakLtwrGL9qzYufkANwMAIABBADoA+gEgAEHh5gE7AfgBIABBAjoAgwIgAEEAOgD0ASAAQQg6APcBIABB2wA2AugBIABC4ebNi9at2bnlADcC7AEgAEHEKWogACgCgAI2AgAgACAAKQL4ATcCvCkgAEHIKWpB2wA2AgAgAEHUKWogACgC9AE2AgAgAEHMKWpC4ebNi9at2bnlADcCACAAQQA6AN4BIABB9OgBOwHcASAAQQI6AOcBIABB2xQtAAA6ANQBIABBBToA2wEgAEHcADYCzAEgAEEAOgDVASAAQdcUKAAANgLQASAAQeApaiAAKALkATYCACAAIAApAtwBNwPYKSAAQeQpakHcADYCACAAQfApaiAAKALYATYCACAAQegpaiAAKQLQATcDACAAQQM6AMsBIABBADoAwwEgAEG8Ci0AADoAwgEgAEG6Ci8AADsBwAEgAEEAOgC8ASAAQQg6AL8BIABB3QA2ArABIABC6MLdi5at2rDuADcCtAEgAEH8KWogACgCyAE2AgAgACAAKQLAATcC9CkgAEGAKmpB3QA2AgAgAEGMKmogACgCvAE2AgAgAEGEKmpC6MLdi5at2rDuADcCACAAQQA6AKYBIABB7NwBOwGkASAAQQI6AK8BIABB7SgoAAA2AJsBIABBBzoAowEgAEHeADYClAEgAEEAOgCfASAAQeooKAAANgKYASAAQZgqaiAAKAKsATYCACAAIAApAqQBNwOQKiAAQZwqakHeADYCACAAQagqaiAAKAKgATYCACAAQaAqaiAAKQKYATcDACAAQQA6AIoBIABB6MIBOwGIASAAQQI6AJMBIABB1CgtAAA6AIABIABBBToAhwEgAEHfADYCeCAAQQA6AIEBIABB0CgoAAA2AnwgAEG0KmogACgCkAE2AgAgACAAKQKIATcCrCogAEG4KmpB3wA2AgAgAEHEKmogACgChAE2AgAgAEG8KmogACkCfDcCACAAQQA6AG4gAEHiwgE7AWwgAEECOgB3IABBlRQoAAA2AGMgAEEHOgBrIABB4AA2AlwgAEEAOgBnIABBkhQoAAA2AmAgAEHQKmogACgCdDYCACAAIAApAmw3A8gqIABB1CpqQeAANgIAIABB4CpqIAAoAmg2AgAgAEHYKmogACkCYDcDACAAQQA6AFIgAEHq7gE7AVAgAEECOgBbIABBADoATCAAQQg6AE8gAEHhADYCQCAAQurC2Yvmrdm55QA3AkQgAEHsKmogACgCWDYCACAAIAApAlA3AuQqIABB8CpqQeEANgIAIABB/CpqIAAoAkw2AgAgAEH0KmpC6sLZi+at2bnlADcCACAAQQA6ADYgAEHz6gE7ATQgAEECOgA/IABBuSEtAAA6ADAgAEEJOgAzIABB4gA2AiQgAEEAOgAxIABBsSEpAAAiEzcCKCAAQYgraiAAKAI8NgIAIAAgACkCNDcDgCsgAEGMK2pB4gA2AgAgAEGYK2ogACgCMDYCACAAQZAraiATNwMAIABBAzoAIyAAQQA6ABsgAEH5Hi0AADoAGiAAQfceLwAAOwEYIABBpyEtAAA6ABQgAEEJOgAXIABB4wA2AgggAEEAOgAVIABBnyEpAAAiEzcCDCAAQaQraiAAKAIgNgIAIAAgACkCGDcCnCsgAEGoK2pB4wA2AgAgAEG0K2ogACgCFDYCACAAQawraiATNwIAQaTWNEIANwIAQaDWNEGk1jQ2AgADQCMAQRBrIgkkACAAQbgraiIQAn8gAEHIFWogBEEcbGohBUGk1jQoAgAhBgJAAkACQEGk1jQiA0Gg1jQoAgBGDQACQCAGRQRAQaTWNCECA0AgAigCCCIDKAIAIAJGIRIgAyECIBINAAsMAQsgBiECA0AgAiIDKAIEIgINAAsLAkAgBSgCBCAFLQALIgIgAsAiDkEASCIIGyIHIAMoAhQgAy0AGyICIALAQQBIIgobIgIgAiAHSxsiDwRAIAMoAhAgA0EQaiAKGyAFKAIAIAUgCBsgDxBGIggNAQsgAiAHSQ0BDAILIAhBAE4NAQsgBkUNASAJIAM2AgwgA0EEagwCC0Gk1jQoAgAiAkUNACAFKAIAIAUgDkEASBshDkGk1jQhBgNAAkACQAJAAkACQAJAIAIiAygCFCACLQAbIgIgAsBBAEgiChsiAiAHIAIgB0kiDxsiCARAIA4gAygCECADQRBqIAobIgogCBBGIhFFBEAgAiAHSw0CDAMLIBFBAE4NAgwBCyACIAdNDQILIAMhBiADKAIAIgINBQwECyAKIA4gCBBGIgINAQsgDw0BDAILIAJBAE4NAQsgA0EEaiEGIAMoAgQiAg0BCwsgCSADNgIMIAYMAQsgCUGk1jQ2AgxBpNY0CyIGKAIAIgIEf0EABUEsEDEiAkEQaiEDAkAgBSwAC0EATgRAIAMgBSkCADcCACADIAUoAgg2AggMAQsgAyAFKAIAIAUoAgQQbAsgAiAFKAIMNgIcIAJBIGohAwJAIAUsABtBAE4EQCADIAUpAhA3AgAgAyAFKAIYNgIIDAELIAMgBSgCECAFKAIUEGwLIAIgCSgCDDYCCCACQgA3AgAgBiACNgIAIAIhA0Gg1jQoAgAoAgAiBQRAQaDWNCAFNgIAIAYoAgAhAwtBpNY0KAIAIAMQpAFBqNY0QajWNCgCAEEBajYCAEEBCzoABCAQIAI2AgAgCUEQaiQAIARBAWoiBEHkAEcNAAsgECEEA0AgBEEBaywAAEEASARAIARBDGsoAgAQLwsgBEEcayECIARBEWssAABBAEgEQCACKAIAEC8LIAIiBCAAQcgVakcNAAsgACwAF0EASARAIAAoAgwQLwsgACwAI0EASARAIAAoAhgQLwsgACwAM0EASARAIAAoAigQLwsgACwAP0EASARAIAAoAjQQLwsgACwAT0EASARAIAAoAkQQLwsgACwAW0EASARAIAAoAlAQLwsgACwAa0EASARAIAAoAmAQLwsgACwAd0EASARAIAAoAmwQLwsgACwAhwFBAEgEQCAAKAJ8EC8LIAAsAJMBQQBIBEAgACgCiAEQLwsgACwAowFBAEgEQCAAKAKYARAvCyAALACvAUEASARAIAAoAqQBEC8LIAAsAL8BQQBIBEAgACgCtAEQLwsgACwAywFBAEgEQCAAKALAARAvCyAALADbAUEASARAIAAoAtABEC8LIAAsAOcBQQBIBEAgACgC3AEQLwsgACwA9wFBAEgEQCAAKALsARAvCyAALACDAkEASARAIAAoAvgBEC8LIAAsAJMCQQBIBEAgACgCiAIQLwsgACwAnwJBAEgEQCAAKAKUAhAvCyAALACvAkEASARAIAAoAqQCEC8LIAAsALsCQQBIBEAgACgCsAIQLwsgACwAywJBAEgEQCAAKALAAhAvCyAALADXAkEASARAIAAoAswCEC8LIAAsAOcCQQBIBEAgACgC3AIQLwsgACwA8wJBAEgEQCAAKALoAhAvCyANEC8gACwA/wJBAEgEQCAAKAL0AhAvCyAALACPA0EASARAIAAoAoQDEC8LIAAsAJsDQQBIBEAgACgCkAMQLwsgACwAqwNBAEgEQCAAKAKgAxAvCyAALAC3A0EASARAIAAoAqwDEC8LIAAsAMcDQQBIBEAgACgCvAMQLwsgACwA0wNBAEgEQCAAKALIAxAvCyAALADjA0EASARAIAAoAtgDEC8LIAAsAO8DQQBIBEAgACgC5AMQLwsgACwA/wNBAEgEQCAAKAL0AxAvCyAALACLBEEASARAIAAoAoAEEC8LIAwQLyAALACXBEEASARAIAAoAowEEC8LIAAsAKcEQQBIBEAgACgCnAQQLwsgACwAswRBAEgEQCAAKAKoBBAvCyAALADDBEEASARAIAAoArgEEC8LIAAsAM8EQQBIBEAgACgCxAQQLwsgACwA3wRBAEgEQCAAKALUBBAvCyAALADrBEEASARAIAAoAuAEEC8LIAAsAPsEQQBIBEAgACgC8AQQLwsgACwAhwVBAEgEQCAAKAL8BBAvCyAALACXBUEASARAIAAoAowFEC8LIAAsAKMFQQBIBEAgACgCmAUQLwsgACwAswVBAEgEQCAAKAKoBRAvCyAALAC/BUEASARAIAAoArQFEC8LIAAsAM8FQQBIBEAgACgCxAUQLwsgACwA2wVBAEgEQCAAKALQBRAvCyAALADrBUEASARAIAAoAuAFEC8LIAAsAPcFQQBIBEAgACgC7AUQLwsgACwAhwZBAEgEQCAAKAL8BRAvCyAALACTBkEASARAIAAoAogGEC8LIAAsAKMGQQBIBEAgACgCmAYQLwsgACwArwZBAEgEQCAAKAKkBhAvCyAALAC/BkEASARAIAAoArQGEC8LIAAsAMsGQQBIBEAgACgCwAYQLwsgACwA2wZBAEgEQCAAKALQBhAvCyAALADnBkEASARAIAAoAtwGEC8LIAAsAPcGQQBIBEAgACgC7AYQLwsgACwAgwdBAEgEQCAAKAL4BhAvCyAALACTB0EASARAIAAoAogHEC8LIAAsAJ8HQQBIBEAgACgClAcQLwsgACwArwdBAEgEQCAAKAKkBxAvCyAALAC7B0EASARAIAAoArAHEC8LIAAsAMsHQQBIBEAgACgCwAcQLwsgACwA1wdBAEgEQCAAKALMBxAvCyAALADnB0EASARAIAAoAtwHEC8LIAAsAPMHQQBIBEAgACgC6AcQLwsgACwAgwhBAEgEQCAAKAL4BxAvCyAALACPCEEASARAIAAoAoQIEC8LIAAsAJ8IQQBIBEAgACgClAgQLwsgACwAqwhBAEgEQCAAKAKgCBAvCyAALAC7CEEASARAIAAoArAIEC8LIAAsAMcIQQBIBEAgACgCvAgQLwsgACwA1whBAEgEQCAAKALMCBAvCyAALADjCEEASARAIAAoAtgIEC8LIAAsAPMIQQBIBEAgACgC6AgQLwsgACwA/whBAEgEQCAAKAL0CBAvCyAALACPCUEASARAIAAoAoQJEC8LIAAsAJsJQQBIBEAgACgCkAkQLwsgACwAqwlBAEgEQCAAKAKgCRAvCyAALAC3CUEASARAIAAoAqwJEC8LIAAsAMcJQQBIBEAgACgCvAkQLwsgACwA0wlBAEgEQCAAKALICRAvCyAALADjCUEASARAIAAoAtgJEC8LIAAsAO8JQQBIBEAgACgC5AkQLwsgACwA/wlBAEgEQCAAKAL0CRAvCyAALACLCkEASARAIAAoAoAKEC8LIAAsAJsKQQBIBEAgACgCkAoQLwsgACwApwpBAEgEQCAAKAKcChAvCyAALAC3CkEASARAIAAoAqwKEC8LIAAsAMMKQQBIBEAgACgCuAoQLwsgACwA0wpBAEgEQCAAKALIChAvCyAALADfCkEASARAIAAoAtQKEC8LIAAsAO8KQQBIBEAgACgC5AoQLwsgACwA+wpBAEgEQCAAKALwChAvCyAALACLC0EASARAIAAoAoALEC8LIAAsAJcLQQBIBEAgACgCjAsQLwsgACwApwtBAEgEQCAAKAKcCxAvCyAALACzC0EASARAIAAoAqgLEC8LIAAsAMMLQQBIBEAgACgCuAsQLwsgACwAzwtBAEgEQCAAKALECxAvCyALEC8gACwA2wtBAEgEQCAAKALQCxAvCyAALADrC0EASARAIAAoAuALEC8LIAAsAPcLQQBIBEAgACgC7AsQLwsgACwAhwxBAEgEQCAAKAL8CxAvCyAALACTDEEASARAIAAoAogMEC8LIAAsAKMMQQBIBEAgACgCmAwQLwsgACwArwxBAEgEQCAAKAKkDBAvCyAALAC/DEEASARAIAAoArQMEC8LIAAsAMsMQQBIBEAgACgCwAwQLwsgACwA2wxBAEgEQCAAKALQDBAvCyAALADnDEEASARAIAAoAtwMEC8LIAAsAPcMQQBIBEAgACgC7AwQLwsgACwAgw1BAEgEQCAAKAL4DBAvCyAALACTDUEASARAIAAoAogNEC8LIAAsAJ8NQQBIBEAgACgClA0QLwsgACwArw1BAEgEQCAAKAKkDRAvCyAALAC7DUEASARAIAAoArANEC8LIAAsAMsNQQBIBEAgACgCwA0QLwsgACwA1w1BAEgEQCAAKALMDRAvCyAALADnDUEASARAIAAoAtwNEC8LIAAsAPMNQQBIBEAgACgC6A0QLwsgACwAgw5BAEgEQCAAKAL4DRAvCyAALACPDkEASARAIAAoAoQOEC8LIAAsAJ8OQQBIBEAgACgClA4QLwsgACwAqw5BAEgEQCAAKAKgDhAvCyAALAC7DkEASARAIAAoArAOEC8LIAAsAMcOQQBIBEAgACgCvA4QLwsgACwA1w5BAEgEQCAAKALMDhAvCyAALADjDkEASARAIAAoAtgOEC8LIAAsAPMOQQBIBEAgACgC6A4QLwsgACwA/w5BAEgEQCAAKAL0DhAvCyAALACPD0EASARAIAAoAoQPEC8LIAAsAJsPQQBIBEAgACgCkA8QLwsgACwAqw9BAEgEQCAAKAKgDxAvCyAALAC3D0EASARAIAAoAqwPEC8LIAAsAMcPQQBIBEAgACgCvA8QLwsgACwA0w9BAEgEQCAAKALIDxAvCyAALADjD0EASARAIAAoAtgPEC8LIAAsAO8PQQBIBEAgACgC5A8QLwsgACwA/w9BAEgEQCAAKAL0DxAvCyAALACLEEEASARAIAAoAoAQEC8LIAAsAJsQQQBIBEAgACgCkBAQLwsgACwApxBBAEgEQCAAKAKcEBAvCyAALAC3EEEASARAIAAoAqwQEC8LIAAsAMMQQQBIBEAgACgCuBAQLwsgACwA0xBBAEgEQCAAKALIEBAvCyAALADfEEEASARAIAAoAtQQEC8LIAAsAO8QQQBIBEAgACgC5BAQLwsgACwA+xBBAEgEQCAAKALwEBAvCyAALACLEUEASARAIAAoAoAREC8LIAAsAJcRQQBIBEAgACgCjBEQLwsgACwApxFBAEgEQCAAKAKcERAvCyAALACzEUEASARAIAAoAqgREC8LIAAsAMMRQQBIBEAgACgCuBEQLwsgACwAzxFBAEgEQCAAKALEERAvCyAALADfEUEASARAIAAoAtQREC8LIAAsAOsRQQBIBEAgACgC4BEQLwsgACwA+xFBAEgEQCAAKALwERAvCyAALACHEkEASARAIAAoAvwREC8LIAAsAJcSQQBIBEAgACgCjBIQLwsgACwAoxJBAEgEQCAAKAKYEhAvCyAALACzEkEASARAIAAoAqgSEC8LIAAsAL8SQQBIBEAgACgCtBIQLwsgACwAzxJBAEgEQCAAKALEEhAvCyAALADbEkEASARAIAAoAtASEC8LIAAsAOsSQQBIBEAgACgC4BIQLwsgACwA9xJBAEgEQCAAKALsEhAvCyAALACHE0EASARAIAAoAvwSEC8LIAAsAJMTQQBIBEAgACgCiBMQLwsgACwAoxNBAEgEQCAAKAKYExAvCyAALACvE0EASARAIAAoAqQTEC8LIAAsAL8TQQBIBEAgACgCtBMQLwsgACwAyxNBAEgEQCAAKALAExAvCyAALADbE0EASARAIAAoAtATEC8LIAAsAOcTQQBIBEAgACgC3BMQLwsgACwA9xNBAEgEQCAAKALsExAvCyAALACDFEEASARAIAAoAvgTEC8LIAAsAJMUQQBIBEAgACgCiBQQLwsgACwAnxRBAEgEQCAAKAKUFBAvCyAALACvFEEASARAIAAoAqQUEC8LIAAsALsUQQBIBEAgACgCsBQQLwsgACwAyxRBAEgEQCAAKALAFBAvCyAALADXFEEASARAIAAoAswUEC8LIAAsAOcUQQBIBEAgACgC3BQQLwsgACwA8xRBAEgEQCAAKALoFBAvCyAALACDFUEASARAIAAoAvgUEC8LIAAsAI8VQQBIBEAgACgChBUQLwsgACwAnxVBAEgEQCAAKAKUFRAvCyAALACrFUEASARAIAAoAqAVEC8LIAAsALsVQQBI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IgAkAAJAQbjWNP4SAABBAXENAEG41jQQVEUNAEGs1jRCADcCAEG01jRBADYCAEG41jQQUwsCf0G31jQsAABBAEgEQEGw1jRBADYCAEGs1jQoAgAMAQtBt9Y0QQA6AABBrNY0C0EAOgAAIABBBGoiAUEAEDkgACABQerfABA4IgEoAgg2AhggACABKQIANwMQIAFCADcCACABQQA2AgggACAAQRBqQebfABA3IgEoAgg2AiggACABKQIANwMgIAFCADcCACABQQA2AghBrNY0IAAoAiAgAEEgaiAALQArIgHAQQBIIgQbIAAoAiQgASAEGxBhGiAALAArQQBIBEAgACgCIBAvCyAALAAbQQBIBEAgACgCEBAvCyAALAAPQQBIBEAgACgCBBAvCyAAQQRqIgFBABA5IAAgAUHj4AAQOCIBKAIINgIYIAAgASkCADcDECABQgA3AgAgAUEANgIIIAAgAEEQakHm3wAQNyIBKAIINgIoIAAgASkCADcDICABQgA3AgAgAUEANgIIQazWNCAAKAIgIABBIGogAC0AKyIBwEEASCIEGyAAKAIkIAEgBBsQYRogACwAK0EASARAIAAoAiAQLwsgACwAG0EASARAIAAoAhAQLwsgACwAD0EASARAIAAoAgQQLwsgAEEEaiIBQQAQOSAAIAFB6+AAEDgiASgCCDYCGCAAIAEpAgA3AxAgAUIANwIAIAFBADYCCCAAIABBEGpB5t8AEDciASgCCDYCKCAAIAEpAgA3AyAgAUIANwIAIAFBADYCCEGs1jQgACgCICAAQSBqIAAtACsiAcBBAEgiBBsgACgCJCABIAQbEGEaIAAsACtBAEgEQCAAKAIgEC8LIAAsABtBAEgEQCAAKAIQEC8LIAAsAA9BAEgEQCAAKAIEEC8LIABBBGoiAUEAEDkgACABQcvgABA4IgEoAgg2AhggACABKQIANwMQIAFCADcCACABQQA2AgggACAAQRBqQebfABA3IgEoAgg2AiggACABKQIANwMgIAFCADcCACABQQA2AghBrNY0IAAoAiAgAEEgaiAALQArIgHAQQBIIgQbIAAoAiQgASAEGxBhGiAALAArQQBIBEAgACgCIBAvCyAALAAbQQBIBEAgACgCEBAvCyAALAAPQQBIBEAgACgCBBAvCyAAQQRqIgFBABA5IAAgAUGM4AAQOCIBKAIINgIYIAAgASkCADcDECABQgA3AgAgAUEANgIIIAAgAEEQakHm3wAQNyIBKAIINgIoIAAgASkCADcDICABQgA3AgAgAUEANgIIQazWNCAAKAIgIABBIGogAC0AKyIBwEEASCIEGyAAKAIkIAEgBBsQYRogACwAK0EASARAIAAoAiAQLwsgACwAG0EASARAIAAoAhAQLwsgACwAD0EASARAIAAoAgQQLwsgAEEEaiIBQQAQOSAAIAFBx+AAEDgiASgCCDYCGCAAIAEpAgA3AxAgAUIANwIAIAFBADYCCCAAIABBEGpB5t8AEDciASgCCDYCKCAAIAEpAgA3AyAgAUIANwIAIAFBADYCCEGs1jQgACgCICAAQSBqIAAtACsiAcBBAEgiBBsgACgCJCABIAQbEGEaIAAsACtBAEgEQCAAKAIgEC8LIAAsABtBAEgEQCAAKAIQEC8LIAAsAA9BAEgEQCAAKAIEEC8LIABBBGoiAUEAEDkgACABQZ7gABA4IgEoAgg2AhggACABKQIANwMQIAFCADcCACABQQA2AgggACAAQRBqQebfABA3IgEoAgg2AiggACABKQIANwMgIAFCADcCACABQQA2AghBrNY0IAAoAiAgAEEgaiAALQArIgHAQQBIIgQbIAAoAiQgASAEGxBhGiAALAArQQBIBEAgACgCIBAvCyAALAAbQQBIBEAgACgCEBAvCyAALAAPQQBIBEAgACgCBBAvCyAAQQRqIgFBABA5IAAgAUG04AAQOCIBKAIINgIYIAAgASkCADcDECABQgA3AgAgAUEANgIIIAAgAEEQakHm3wAQNyIBKAIINgIoIAAgASkCADcDICABQgA3AgAgAUEANgIIQazWNCAAKAIgIABBIGogAC0AKyIBwEEASCIEGyAAKAIkIAEgBBsQYRogACwAK0EASARAIAAoAiAQLwsgACwAG0EASARAIAAoAhAQLwsgACwAD0EASARAIAAoAgQQLwsgAEEEaiIBQQAQOSAAIAFBvOAAEDgiASgCCDYCGCAAIAEpAgA3AxAgAUIANwIAIAFBADYCCCAAIABBEGpB5t8AEDciASgCCDYCKCAAIAEpAgA3AyAgAUIANwIAIAFBADYCCEGs1jQgACgCICAAQSBqIAAtACsiAcBBAEgiBBsgACgCJCABIAQbEGEaIAAsACtBAEgEQCAAKAIgEC8LIAAsABtBAEgEQCAAKAIQEC8LIAAsAA9BAEgEQCAAKAIEEC8LIABBBGoiAUEBEDkgACABQafgABA4IgEoAgg2AhggACABKQIANwMQIAFCADcCACABQQA2AgggACAAQRBqQebfABA3IgEoAgg2AiggACABKQIANwMgIAFCADcCACABQQA2AghBrNY0IAAoAiAgAEEgaiAALQArIgHAQQBIIgQbIAAoAiQgASAEGxBhGiAALAArQQBIBEAgACgCIBAvCyAALAAbQQBIBEAgACgCEBAvCyAALAAPQQBIBEAgACgCBBAvCyAAQQRqIgFBABA5IAAgAUH43wAQOCIBKAIINgIYIAAgASkCADcDECABQgA3AgAgAUEANgIIIAAgAEEQakHm3wAQNyIBKAIINgIoIAAgASkCADcDICABQgA3AgAgAUEANgIIQazWNCAAKAIgIABBIGogAC0AKyIBwEEASCIEGyAAKAIkIAEgBBsQYRogACwAK0EASARAIAAoAiAQLwsgACwAG0EASARAIAAoAhAQLwsgACwAD0EASARAIAAoAgQQLwsgAEEEaiIBQQAQOSAAIAFB2+AAEDgiASgCCDYCGCAAIAEpAgA3AxAgAUIANwIAIAFBADYCCCAAIABBEGpB5t8AEDciASgCCDYCKCAAIAEpAgA3AyAgAUIANwIAIAFBADYCCEGs1jQgACgCICAAQSBqIAAtACsiAcBBAEgiBBsgACgCJCABIAQbEGEaIAAsACtBAEgEQCAAKAIgEC8LIAAsABtBAEgEQCAAKAIQEC8LIAAsAA9BAEgEQCAAKAIEEC8LIABBBGoiAUEAEDkgACABQdrgABA4IgEoAgg2AhggACABKQIANwMQIAFCADcCACABQQA2AgggACAAQRBqQebfABA3IgEoAgg2AiggACABKQIANwMgIAFCADcCACABQQA2AghBrNY0IAAoAiAgAEEgaiAALQArIgHAQQBIIgQbIAAoAiQgASAEGxBhGiAALAArQQBIBEAgACgCIBAvCyAALAAbQQBIBEAgACgCEBAvCyAALAAPQQBIBEAgACgCBBAvCyAAQQRqIgFBABA5IAAgAUHx3wAQOCIBKAIINgIYIAAgASkCADcDECABQgA3AgAgAUEANgIIIAAgAEEQakHm3wAQNyIBKAIINgIoIAAgASkCADcDICABQgA3AgAgAUEANgIIQazWNCAAKAIgIABBIGogAC0AKyIBwEEASCIEGyAAKAIkIAEgBBsQYRogACwAK0EASARAIAAoAiAQLwsgACwAG0EASARAIAAoAhAQLwsgACwAD0EASARAIAAoAgQQLwsgAEEEaiIBQQAQOSAAIAFB0uAAEDgiASgCCDYCGCAAIAEpAgA3AxAgAUIANwIAIAFBADYCCCAAIABBEGpB5t8AEDciASgCCDYCKCAAIAEpAgA3AyAgAUIANwIAIAFBADYCCEGs1jQgACgCICAAQSBqIAAtACsiAcBBAEgiBBsgACgCJCABIAQbEGEaIAAsACtBAEgEQCAAKAIgEC8LIAAsABtBAEgEQCAAKAIQEC8LIAAsAA9BAEgEQCAAKAIEEC8LIABBBGoiAUEAEDkgACABQZTgABA4IgEoAgg2AhggACABKQIANwMQIAFCADcCACABQQA2AgggACAAQRBqQebfABA3IgEoAgg2AiggACABKQIANwMgIAFCADcCACABQQA2AghBrNY0IAAoAiAgAEEgaiAALQArIgHAQQBIIgQbIAAoAiQgASAEGxBhGiAALAArQQBIBEAgACgCIBAvCyAALAAbQQBIBEAgACgCEBAvCyAALAAPQQBIBEAgACgCBBAvCyAAQQRqIgFBABA5IAAgAUGA4AAQOCIBKAIINgIYIAAgASkCADcDECABQgA3AgAgAUEANgIIIAAgAEEQakHm3wAQNyIBKAIINgIoIAAgASkCADcDICABQgA3AgAgAUEANgIIQazWNCAAKAIgIABBIGogAC0AKyIBwEEASCIEGyAAKAIkIAEgBBsQYRogACwAK0EASARAIAAoAiAQLwsgACwAG0EASARAIAAoAhAQLwsgACwAD0EASARAIAAoAgQQLwtBt9Y0LAAAIQFBrNY0KAIAIQQgAEEwaiQAIBJBrNY0IAQgAUEAThs2AugBIBIgAzYC5AEgEiACNgLgAUHj4gAgEkHgAWoQoAEQxwIgEkEBNgLUASASIBIoAogCNgLQASASIBIoAtACNgLYASASQfQgQcIjIBItAJgCGzYC3AEgEkH92gA2AsABIBIgEigC/AEgEigC+AFrQQJ1IgA2AsQBIBIgALNDAAB6RpW7OQPIAUG88AAgEkHAAWoQogQQxwJBACEAQbC6AygCACIBEGs3AwggASgC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Cmr9AAIA/QsCACABQQRqIgEgBEcNAAsgAiAERg0DCyACIARBf3NqITwgAkEDcSIKBEADQCAPIARBAnQiB2ogAyAHaigCADYCACAEQQFqIQQgE0EBaiITIApHDQALCyA8QQNJDQIDQCAPIARBAnQiAWogASADaigCADYCACAPIAFBBGoiCmogAyAKaigCADYCACAPIAFBCGoiCmogAyAKaigCADYCACAPIAFBDGoiAWogASADaigCADYCACAEQQRqIgQgAkcNAAsMAgsgCyAYNgIIIAsgBjYCBCALQeEeNgIAQQJBqfYAIAsQNEF/IQYLIANFDQELIAsgAzYCJCADEC8LIAtB4AFqJAAgBgwECwJAAkACQAJAAkAgCy0ATARAIAsoAkgiCCALKAJEIgNrIgpB8P///wdPDQECQCAKQQpNBEAgCyAKOgCzASALQagBaiECDAELIApBD3JBAWoiARAxIQIgCyABQYCAgIB4cjYCsAEgCyACNgKoASALIAo2AqwBCyADIAhGBEAgAkEAOgAADAYLIApBEEkNAiACIANrQRBJDQIgAyAKQXBxIgxqIQQgAiAMaiEBQQAhBgNAIAIgBmogAyAGav0AAAD9CwAAIAZBEGoiBiAMRw0ACyAKIAxGDQQMAwsgC0EANgKwASALQgA3A6gBDAQLEE0ACyACIQEgAyEECyAEQX9zIAhqIT1BACEGIAggBGtBB3EiAwRAA0AgASAELQAAOgAAIAFBAWohASAEQQFqIQQgBkEBaiIGIANHDQALCyA9QQdJDQADQCABIAQtAAA6AAAgASAELQABOgABIAEgBC0AAjoAAiABIAQtAAM6AAMgASAELQAEOgAEIAEgBC0ABToABSABIAQtAAY6AAYgASAELQAHOgAHIAFBCGohASAEQQhqIgQgCEcNAAsLIAFBADoAAAsgCywAmwFBAEgEQCALKAKQARAvCyALIAsoArABNgKYASALIAspA6gBNwOQAQwACwALQQwQYEEREHFBwKgDQdEAEAIACxBNAAsiAyAFKALMBiICIAUoAsgGIgFrQQJ1IgRLBEAgGSADIARrENcEIAUoAsgGIQEgBSgCzAYhAgwBCyADIARPDQAgBSABIANBAnRqIgI2AswGCyAQIAE2AkQgECACIAFrQQJ1IgI2AkgLIBdBnKgBaiEfIAFFDQIgAkEATA0C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QQBKBEBBACECA0AgAygCWCACQQR0aiIBQX82AgAgAUEEaiABQQhqIgQoAgAQlQEgASAENgIEIAFCADcCCCACQQFqIgIgAygCUEgNAAsgBSgCnBohAQsgA0EANgJMIAEgBSgCtAYgBSgCsAYiBmsiBEECdSIDNgK0AQJAIARBAEwNAEEAIQIgBkUEQCADQQFHBEAgA0F+cSEMQQAhCANAIAJBAnQiBiABKAK8AWogAjYCACABKALAASAGakEBNgIAIAEoAsQBIAZqKAIAQQA2AgAgASgCyAEgAmpBADoAACACQQFyIgZBAnQiByABKAK8AWogBjYCACABKALAASAHakEBNgIAIAEoAsQBIAdqKAIAQQA2AgAgASgCyAEgBmpBADoAACACQQJqIQIgCEECaiIIIAxHDQALCyAEQQRxRQ0BIAJBAnQiBCABKAK8AWogAjYCACABKALAASAEakEBNgIAIAEoAsQBIARqKAIAQQA2AgAgASgCyAEgAmpBADoAAAwBCwNAIAJBAnQiBCABKAK4AWogBCAGaigCADYCACABKAK8ASAEaiACNgIAIAEoAsABIARqQQE2AgAgASgCxAEgBGooAgBBADYCACABKALIASACakEAOgAAIAJBAWoiAiADRw0ACwsgAyABKALIAWpBAWtBAToAACAFKAKgGiAFKAKcGiIBIAFBtAFqIBAoAgQgECgClAEgECgCmAEQ7wJFDQoQayFOIAUoApwaIgEgBSgCtAYgBSgCsAZrQQJ1QQFrNgKoAiAFKgKgBiFPIAUoAqAaIT4gBUH8A2oiAyAQQbQB/AoAACA+IAEgAUHQAWogAyBPEIoCQQEhDCAFKAKcBkEBSgRAA0AgBSgCnBoiBkEANgJMIAYiAigCUCIPBEBBACEHA0AgBigCWCAHQQR0aiIIQQhqIgMhAiADKAIAIgQhAQJAIARFDQADQCACIAEgASgCEEEASCIJGyECIAFBBGogASAJGygCACIBDQALIAIgA0YNACACKAIQQQBKDQAgCCgCAEH+////B0sNAAJ/A0AgDCAEIgEoAhAiAkgEQCABKAIAIgQNASABDAILIAIgDE4NAiABKAIEIgQNAAsgAUEEagshAkEUEDEiAyABNgIIIANCADcCACADIAw2AhAgAiADNgIAIAgoAgQoAgAiAQRAIAggATYCBCACKAIAIQMLIAMgAyAIKAIIIglGIgE6AAwCQCABDQADQCADKAIIIgItAAwNAQJAIAIgAigCCCIBKAIAIgRGBEACQCABKAIEIgRFDQAgBC0ADA0ADAILAkAgAyACKAIARgRAIAIhAwwBCyACIAIoAgQiAygCACIENgIEIAMgBAR/IAQgAjYCCCACKAIIBSABCzYCCCACKAIIIgEgASgCACACR0ECdGogAzYCACADIAI2AgAgAiADNgIIIAMoAggiASgCACECCyADQQE6AAwgAUEAOgAMIAEgAigCBCIDNgIAIAMEQCADIAE2AggLIAIgASgCCDYCCCABKAIIIgMgAygCACABR0ECdGogAjYCACACIAE2AgQgASACNgIIDAMLAkAgBEUNACAELQAMDQAMAQsCQCADIAIoAgBHBEAgAiEDDAELIAIgAygCBCIENgIAIAMgBAR/IAQgAjYCCCACKAIIBSABCzYCCCACKAIIIgEgASgCACACR0ECdGogAzYCACADIAI2AgQgAiADNgIIIAMoAgghAQsgA0EBOgAMIAFBADoADCABIAEoAgQiAigCACIDNgIEIAMEQCADIAE2AggLIAIgASgCCDYCCCABKAIIIgMgAygCACABR0ECdGogAjYCACACIAE2AgAgASACNgIIDAILIAJBAToADCABIAEgCUY6AAwgBEEBOgAMIAkgASIDRw0ACwsgCCAIKAIMQQFqNgIMIAYoAlAhDwsgB0EBaiIHIA9JDQALIAUoApwaIQILIAYgDEHYFGxqIgEoArQCIgMgAigCtAIgASgCuAIgA2v8CgAAIAEoAsACIgIgBSgCnBooAsACIAEoAsQCIAJr/AoAACABKALMAiICIAUoApwaKALMAiABKALQAiACa/wKAAAgDEEBaiIMIAUoApwGSA0ACwsQayFNIAUoApwaIgEgASkDACBNIE59fDcDAAJAAkAgBSgCoBooAjQiAUEKSA0AIAFBAXZBBWshLkEAIQ4DQCAOIRUQayFOAkAgECgCAEEBRw0AIAUoAqQGIg8gBSgCqAYiDEYNAANAIA8oAgQiByAPKAIAIgZHBEADQCAHQegAayIEKAJUIgMEQCAHQRBrIgkoAgAiAiADIgFHBEADQCACQQxrIgEoAgAiCARAIAJBCGsgCDYCACAIEC8LIAEiAiADRw0ACyAEKAJUIQELIAkgAzYCACAB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KAKcGiICIAhB2BRsaiIDLQCxAg0AIAMtALACDQAgAkHMAGogCEF/EPACIAUoApwaIgZBADYCTCAIQQhqIQkgBigCUCIOBH9BACEMA0AgBigCWCAMQQR0aiIEQQhqIgMhAiADKAIAIgchAQJAIAdFDQADQCACIAEgASgCECAJSCINGyECIAFBBGogASANGygCACIBDQALIAIgA0YNACACKAIQIAlKDQAgBCgCAEH+////B0sNAAJ/A0AgCCAHIgEoAhAiAkgEQCABKAIAIgcNASABDAILIAIgCE4NAiABKAIEIgcNAAsgAUEEagshAkEUEDEiAyABNgIIIANCADcCACADIAg2AhAgAiADNgIAIAQoAgQoAgAiAQRAIAQgATYCBCACKAIAIQMLIAMgAyAEKAIIIg5GIgE6AAwCQCABDQADQCADKAIIIgItAAwNAQJAIAIgAigCCCIBKAIAIgdGBEACQCABKAIEIgdFDQAgBy0ADA0ADAILAkAgAyACKAIARgRAIAIhAwwBCyACIAIoAgQiAygCACIHNgIEIAMgBwR/IAcgAjYCCCACKAIIBSABCzYCCCACKAIIIgEgASgCACACR0ECdGogAzYCACADIAI2AgAgAiADNgIIIAMoAggiASgCACECCyADQQE6AAwgAUEAOgAMIAEgAigCBCIDNgIAIAMEQCADIAE2AggLIAIgASgCCDYCCCABKAIIIgMgAygCACABR0ECdGogAjYCACACIAE2AgQgASACNgIIDAMLAkAgB0UNACAHLQAMDQAMAQsCQCADIAIoAgBHBEAgAiEDDAELIAIgAygCBCIHNgIAIAMgBwR/IAcgAjYCCCACKAIIBSABCzYCCCACKAIIIgEgASgCACACR0ECdGogAzYCACADIAI2AgQgAiADNgIIIAMoAgghAQsgA0EBOgAMIAFBADoADCABIAEoAgQiAigCACIDNgIEIAMEQCADIAE2AggLIAIgASgCCDYCCCABKAIIIgMgAygCACABR0ECdGogAjYCACACIAE2AgAgASACNgIIDAILIAJBAToADCABIAEgDkY6AAwgB0EBOgAMIA4gASIDRw0ACwsgBCAEKAIMQQFqNgIMIAYoAlAhDgsgDEEBaiIMIA5JDQALIAUoApwaBSAGC0HMAGogCUF/EPACIAUoApwGIQELIAhBAWoiCCABSA0A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fyACLQALQQd2BEAgAigCAAwBCyACCyIBajYCtAELAn8gAEG8AmoiBygCACIGKAIMIgggBigCEEYEQCAGIAYoAgAoAiQRAQAMAQsgCCgCAAtBECABIABBtAFqIABBCGpBACADIABBEGogAEEMaiAAQdABahC+AQ0AIAcQXRoMAQsLIAIgACgCtAEgAWsQOgJ/IAItAAtBB3YEQCACKAIADAELIAILIQsQRCEJIAAgBTYCACALIAkgABDUA0EBRwRAIARBBDYCAAsgAEG8AmogAEG4AmoQQgRAIAQgBCgCAEECcjYCAAsgACgCvAIhCiACEDIaIAMQMhogAEHAAmokACAKC9AFAgN/AX4jAEGAA2siACQAIAAgAjYC+AIgACABNgL8AiAAQdwBaiADIABB8AFqIABB7AFqIABB6AFqELQCIwBBEGsiAiQAIABB0AFqIgFCADcCACABQQA2AgggAkEQaiQAIAEgAS0AC0EHdgR/IAEoAghB/////wdxQQFrBUEKCxA6IAACfyABLQALQQd2BEAgASgCAAwBCyABCyICNgLMASAAIABBIGo2AhwgAEEANgIYIABBAToAFyAAQcUAOgAWA0ACQCAAQfwCaiAAQfgCahBCDQAgACgCzAECfyABLQALQQd2BEAgASgCBAwBCyABLQALQf8AcQsgAmpGBEACfyABLQALQQd2BEAgASgCBAwBCyABLQALQf8AcQshAyABAn8gAS0AC0EHdgRAIAEoAgQMAQsgAS0AC0H/AHELQQF0EDogASABLQALQQd2BH8gASgCCEH/////B3FBAWsFQQoLEDogACADAn8gAS0AC0EHdgRAIAEoAgAMAQsgAQsiAmo2AswBCwJ/IABB/AJqIgYoAgAiAygCDCIHIAMoAhBGBEAgAyADKAIAKAIkEQEADAELIAcoAgALIABBF2ogAEEWaiACIABBzAFqIAAoAuwBIAAoAugBIABB3AFqIABBIGogAEEcaiAAQRhqIABB8AFqELMCDQAgBhBdGgwBCwsCQAJ/IAAtAOcBQQd2BEAgACgC4AEMAQsgAC0A5wFB/wBxC0UNACAALQAXRQ0AIAAoAhwiAyAAQSBqa0GfAUoNACAAIANBBGo2AhwgAyAAKAIYNgIACyAAIAIgACgCzAEgBBDVAyAAKQMAIQkgBSAAKQMINwMIIAUgCTcDACAAQdwBaiAAQSBqIAAoAhwgBBBlIABB/AJqIABB+AJqEEIEQCAEIAQoAgBBAnI2AgALIAAoAvwCIQggARAyGiAAQdwBahAyGiAAQYADaiQAIAgLuQUBA38jAEHwAmsiACQAIAAgAjYC6AIgACABNgLsAiAAQcwBaiADIABB4AFqIABB3AFqIABB2AFqELQCIwBBEGsiAiQAIABBwAFqIgFCADcCACABQQA2AgggAkEQaiQAIAEgAS0AC0EHdgR/IAEoAghB/////wdxQQFrBUEKCxA6IAACfyABLQALQQd2BEAgASgCAAwBCyABCyICNgK8ASAAIABBEGo2AgwgAEEANgIIIABBAToAByAAQcUAOgAGA0ACQCAAQewCaiAAQegCahBCDQAgACgCvAECfyABLQALQQd2BEAgASgCBAwBCyABLQALQf8AcQsgAmpGBEACfyABLQALQQd2BEAgASgCBAwBCyABLQALQf8AcQshAyABAn8gAS0AC0EHdgRAIAEoAgQMAQsgAS0AC0H/AHELQQF0EDogASABLQALQQd2BH8gASgCCEH/////B3FBAWsFQQoLEDogACADAn8gAS0AC0EHdgRAIAEoAgAMAQsgAQsiAmo2ArwBCwJ/IABB7AJqIgYoAgAiAygCDCIHIAMoAhBGBEAgAyADKAIAKAIkEQEADAELIAcoAgALIABBB2ogAEEGaiACIABBvAFqIAAoAtwBIAAoAtgBIABBzAFqIABBEGogAEEMaiAAQQhqIABB4AFqELMCDQAgBhBdGgwBCwsCQAJ/IAAtANcBQQd2BEAgACgC0AEMAQsgAC0A1wFB/wBxC0UNACAALQAHRQ0AIAAoAgwiAyAAQRBqa0GfAUoNACAAIANBBGo2AgwgAyAAKAIINgIACyAFIAIgACgCvAEgBBDWAzkDACAAQcwBaiAAQRBqIAAoAgwgBBBlIABB7AJqIABB6AJqEEIEQCAEIAQoAgBBAnI2AgALIAAoAuwCIQggARAyGiAAQcwBahAyGiAAQfACaiQAIAgLuQUBA38jAEHwAmsiACQAIAAgAjYC6AIgACABNgLsAiAAQcwBaiADIABB4AFqIABB3AFqIABB2AFqELQCIwBBEGsiAiQAIABBwAFqIgFCADcCACABQQA2AgggAkEQaiQAIAEgAS0AC0EHdgR/IAEoAghB/////wdxQQFrBUEKCxA6IAACfyABLQALQQd2BEAgASgCAAwBCyABCyICNgK8ASAAIABBEGo2AgwgAEEANgIIIABBAToAByAAQcUAOgAGA0ACQCAAQewCaiAAQegCahBCDQAgACgCvAECfyABLQALQQd2BEAgASgCBAwBCyABLQALQf8AcQsgAmpGBEACfyABLQALQQd2BEAgASgCBAwBCyABLQALQf8AcQshAyABAn8gAS0AC0EHdgRAIAEoAgQMAQsgAS0AC0H/AHELQQF0EDogASABLQALQQd2BH8gASgCCEH/////B3FBAWsFQQoLEDogACADAn8gAS0AC0EHdgRAIAEoAgAMAQsgAQsiAmo2ArwBCwJ/IABB7AJqIgYoAgAiAygCDCIHIAMoAhBGBEAgAyADKAIAKAIkEQEADAELIAcoAgALIABBB2ogAEEGaiACIABBvAFqIAAoAtwBIAAoAtgBIABBzAFqIABBEGogAEEMaiAAQQhqIABB4AFqELMCDQAgBhBdGgwBCwsCQAJ/IAAtANcBQQd2BEAgACgC0AEMAQsgAC0A1wFB/wBxC0UNACAALQAHRQ0AIAAoAgwiAyAAQRBqa0GfAUoNACAAIANBBGo2AgwgAyAAKAIINgIACyAFIAIgACgCvAEgBBDXAzgCACAAQcwBaiAAQRBqIAAoAgwgBBBlIABB7AJqIABB6AJqEEIEQCAEIAQoAgBBAnI2AgALIAAoAuwCIQggARAyGiAAQcwBahAyGiAAQfACaiQAIAgLmgUBBX8jAEHQAmsiACQAIAAgAjYCyAIgACABNgLMAiADEIkBIQYgAyAAQdABahDRASEHIABBxAFqIAMgAEHEAmoQ0AEjAEEQayICJAAgAEG4AWoiAUIANwIAIAFBADYCCCACQRBqJAAgASABLQALQQd2BH8gASgCCEH/////B3FBAWsFQQoLEDogAAJ/IAEtAAtBB3YEQCABKAIADAELIAELIgI2ArQBIAAgAEEQajYCDCAAQQA2AggDQAJAIABBzAJqIABByAJqEEINACAAKAK0AQJ/IAEtAAtBB3YEQCABKAIEDAELIAEtAAtB/wBxCyACakYEQAJ/IAEtAAtBB3YEQCABKAIEDAELIAEtAAtB/wBxCyEDIAECfyABLQALQQd2BEAgASgCBAwBCyABLQALQf8AcQtBAXQQOiABIAEt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AQF/QbC6AygCACIABEAgABDhBEGwugNBADYCAAsLwgUBBn8jAEGAAmsiACQAIAAgAjYC+AEgACABNgL8ASMAQRBrIgIkACAAQcQBaiIBQgA3AgAgAUEANgIIIAJBEGokACAAQRBqIgYgAygCHCICNgIAIAJBBGpBAf4eAgAaIAYQcyICQcDpAkHa6QIgAEHQAWogAigCACgCIBEIABogBigCACICQQRqQX/+HgIARQRAIAIgAigCACgCCBEAAAsgASEDIwBBEGsiASQAIABBuAFqIgJCADcCACACQQA2AgggAUEQaiQAIAIgAi0AC0EHdgR/IAIoAghB/////wdxQQFrBUEKCxA6IAACfyACLQALQQd2BEAgAigCAAwBCyACCyIBNgK0ASAAIAY2AgwgAEEANgIIA0ACQCAAQfwBaiAAQfgBahBDDQAgACgCtAECfyACLQALQQd2BEAgAigCBAwBCyACLQALQf8AcQsgAWpGBEACfyACLQALQQd2BEAgAigCBAwBCyACLQALQf8AcQshBiACAn8gAi0AC0EHdgRAIAIoAgQMAQsgAi0AC0H/AHELQQF0EDogAiACLQALQQd2BH8gAigCCEH/////B3FBAWsFQQoLEDogACAGAn8gAi0AC0EHdgRAIAIoAgAMAQsgAgsiAWo2ArQBCwJ/IABB/AFqIgcoAgAiBigCDCIIIAYoAhBGBEAgBiAGKAIAKAIkEQEADAELIAgtAAALwEEQIAEgAEG0AWogAEEIakEAIAMgAEEQaiAAQQxqIABB0AFqEMABDQAgBxBeGgwBCwsgAiAAKAK0ASABaxA6An8gAi0AC0EHdgRAIAIoAgAMAQsgAgshCxBEIQkgACAFNgIAIAsgCSAAENQDQQFHBEAgBEEENgIACyAAQfwBaiAAQfgBahBDBEAgBCAEKAIAQQJyNgIACyAAKAL8ASEKIAIQMhogAxAyGiAAQYACaiQAIAoL0QUCA38BfiMAQZACayIAJAAgACACNgKIAiAAIAE2AowCIABB0AFqIAMgAEHgAWogAEHfAWogAEHeAWoQtwIjAEEQayICJAAgAEHEAWoiAUIANwIAIAFBADYCCCACQRBqJAAgASABLQALQQd2BH8gASgCCEH/////B3FBAWsFQQoLEDogAAJ/IAEtAAtBB3YEQCABKAIADAELIAELIgI2AsABIAAgAEEgajYCHCAAQQA2AhggAEEBOgAXIABBxQA6ABYDQAJAIABBjAJqIABBiAJqEEMNACAAKALAAQJ/IAEtAAtBB3YEQCABKAIEDAELIAEtAAtB/wBxCyACakYEQAJ/IAEtAAtBB3YEQCABKAIEDAELIAEtAAtB/wBxCyEDIAECfyABLQALQQd2BEAgASgCBAwBCyABLQALQf8AcQtBAXQQOiABIAEtAAtBB3YEfyABKAIIQf////8HcUEBawVBCgsQOiAAIAMCfyABLQALQQd2BEAgASgCAAwBCyABCyICajYCwAELAn8gAEGMAmoiBigCACIDKAIMIgcgAygCEEYEQCADIAMoAgAoAiQRAQAMAQsgBy0AAAvAIABBF2ogAEEWaiACIABBwAFqIAAsAN8BIAAsAN4BIABB0AFqIABBIGogAEEcaiAAQRhqIABB4AFqELYCDQAgBhBeGgwBCwsCQAJ/IAAtANsBQQd2BEAgACgC1AEMAQsgAC0A2wFB/wBxC0UNACAALQAXRQ0AIAAoAhwiAyAAQSBqa0GfAUoNACAAIANBBGo2AhwgAyAAKAIYNgIACyAAIAIgACgCwAEgBBDVAyAAKQMAIQkgBSAAKQMINwMIIAUgCTcDACAAQdABaiAAQSBqIAAoAhwgBBBlIABBjAJqIABBiAJqEEMEQCAEIAQoAgBBAnI2AgALIAAoAowCIQggARAyGiAAQdABahAyGiAAQZACaiQAIAgLugUBA38jAEGAAmsiACQAIAAgAjYC+AEgACABNgL8ASAAQcABaiADIABB0AFqIABBzwFqIABBzgFqELcCIwBBEGsiAiQAIABBtAFqIgFCADcCACABQQA2AgggAkEQaiQAIAEgAS0AC0EHdgR/IAEoAghB/////wdxQQFrBUEKCxA6IAACfyABLQALQQd2BEAgASgCAAwBCyABCyICNgKwASAAIABBEGo2AgwgAEEANgIIIABBAToAByAAQcUAOgAGA0ACQCAAQfwBaiAAQfgBahBDDQAgACgCsAECfyABLQALQQd2BEAgASgCBAwBCyABLQALQf8AcQsgAmpGBEACfyABLQALQQd2BEAgASgCBAwBCyABLQALQf8AcQshAyABAn8gAS0AC0EHdgRAIAEoAgQMAQsgAS0AC0H/AHELQQF0EDogASABLQALQQd2BH8gASgC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AgAiBQ0BDAILIAIgBEwNAiAAKAIEIgUNAAsgAEEEaiEEC0EgEDEiBSACNgIQIAUgADYCCCAFQgA3AgAgBUIANwIUIAVBADYCHCAEIAU2AgAgBSEAIAMoAtABKAIAIgsEQCADIAs2AtABIAQoAgAhAAsgAygC1AEgABCkASADIAMoAtgBQQFqNgLYAQsCQCAFQRRqIgAgAUHwA2pGDQAgAS0A+wMiC8AhBCAFLAAfQQBOBEAgBEEATgRAIAAgASkD8AM3AgAgACABKAL4AzYCCAwCCyAAIAEoAvADIAEoAvQDEN4BDAELIAAgASgC8AMgAUHwA2ogBEEASCIAGyABKAL0AyALIAAbEN8BCyACQQFqIgIgASgCyAQiAEgNAAsLIAMgAygCICIENgLAASAEQZiVA0oEQCADIAMoAtwBQQFqNgLcASADIAMoAuABQQFqNgLgASADIAP9AALkASAEQZiVA2siBf0R/a4B/QsC5AEgAyADKAL0ASAFajYC9AEgAyADKAL4ASAFajYC+AEgAyADKAL8ASAFajYC/AELAkAgACAETg0AIAFBqyU2AuABIAEgBCAAazYC5AFBBEHt4QAgAUHgAWoQNCABKALIBCICIAMoAiBODQAgA0HUAWohBiADQcQBaiEQIAFB8ANqQQRyIQsDQAJAIAMoAvwBIgQgAkgEQCABQZQEaiIAIAIgBGsQOSABIABBlikQOCIAKAIINgKoBCABIAApAgA3A6AEIABCADcCACAAQQA2AgggAUGgBGpBiSoQNyIAKAIAIQQgASAAKAIENgLkAyABIAAoAAc2AOcDIABCADcCACAALQALIQUgAEEANgIIIAEsAPsDQQBIBEAgASgC8AMQLwsgASAENgLwAyALIAEoAOcDNgADIAsgASgC5AM2AgAgASAFOgD7AyABLACrBEEASARAIAEoAqAEEC8LIAEsAJ8EQQBODQEgASgClAQQLwwBCyADKALcASACRgRAAn8gASwA+wNBAEgEQCABQQc2AvQDIAEoAvADDAELIAFBBzoA+wMgAUHwA2oLIgBBADoAByAAQbcpKAAANgADIABBtCkoAAA2AAAMAQsgAygC4AEiACACRgRAAn8gASwA+wNBAEgEQCABQQc2AvQDIAEoAvADDAELIAFBBzoA+wMgAUHwA2oLIgBBADoAByAAQacpKAAANgADIABBpCkoAAA2AAAMAQsgAygC5AEgAkYEQCABQfADakHEKUENEMwBDAELIAMoAugBIAJGBEAgAUHwA2pB0ilBDhDMAQwBCyADKALsASACRgRAAn8gASwA+wNBAEgEQCABQQg2AvQDIAEoAvADDAELIAFBCDoA+wMgAUHwA2oLIgBBADoACCAAQtu+zfrEqdOv3QA3AAAMAQsgAygC8AEgAkYEQAJ/IAEsAPsDQQBIBEAgAUEINgL0AyABKALwAwwBCyABQQg6APsDIAFB8ANqCyIAQQA6AAggAELbvsGS1cjVr90ANwAADAELIAMoAvQBIAJGBEACfyABLAD7A0EASARAIAFBCDYC9AMgASgC8AMMAQsgAUEIOgD7AyABQfADagsiAEEAOgAIIABC2765+rSK1K/dADcAAAwBCyADKAL4ASACRgRAAn8gASwA+wNBAEgEQCABQQc2AvQDIAEoAvADDAELIAFBBzoA+wMgAUHwA2oLIgBBADoAByAAQa8pKAAANgADIABBrCkoAAA2AAAMAQsgAiAERgRAAn8gASwA+wNBAEgEQCABQQc2AvQDIAEoAvADDAELIAFBBzoA+wMgAUHwA2oLIgBBADoAByAAQb8pKAAANgADIABBvCkoAAA2AAAMAQsCQCAAIAJODQAgAiAAIAMoAsABIgRqIARBmJUDSmtBtZQDa0oNACACIABBf3NqIQlBACEFIwBBEGsiCCQAAkACQEGg1jQoAgAiBEGk1jRHBEADQCAEKAIcIAlGDQICQCAEKAIEIgAEQANAIAAiBCgCACIADQAMAgsACwNAIAQgBCgCCCIEKAIARw0ACwsgBEGk1jRHDQALCyAIIAk2AgQgCEGkEzYCAEECQZXqACAIEDQMAQsgBCgCECAEQRBqIAQsABtBAEgbIQULIAhBEGokACABIAFBlARqIAUQpgEiBEGcKRA4IgAoAgg2AqgEIAEgACkCADcDoAQgAEIANwIAIABBADYCCCABQaAEakGJKhA3IgAoAgAhBSABIAAoAgQ2AuQDIAEgACgABzYA5wMgAEIANwIAIAAtAAshCCAAQQA2AgggASwA+wNBAEgEQCABKALwAxAvCyABIAU2AvADIAsgASgA5wM2AAMgCyABKALkAzYCACABIAg6APsDIAEsAKsEQQBIBEAgASgCoAQQLwsgASwAnwRBAE4NASAEKAIAEC8MAQsgAUGUBGoiACACEDkgASAAQYcpEDgiACgCCDYCqAQgASAAKQIANwOgBCAAQgA3AgAgAEEANgIIIAFBoARqQYkqEDciACgCACEEIAEgACgCBDYC5AMgASAAKAAHNgDnAyAAQgA3AgAgAC0ACyEFIABBADYCCCABLAD7A0EASARAIAEoAvADEC8LIAEgBDYC8AMgCyABKADnAzYAAyALIAEoAuQDNgIAIAEgBToA+wMgASwAqwRBAEgEQCABKAKgBBAvCyABLACfBEEATg0AIAEoApQEEC8LIAEgAUHwA2oiADYClAQgAUGgBGogECAAIAFBlARqEOIEIAEoAqAEIAI2AhwCQAJAIAYiBCIAKAIAIgVFDQADQCAFIgAoAhAiBCACSgRAIAAiBCgCACIFDQEMAgsgAiAETA0CIAAoAgQiBQ0ACyAAQQRqIQQLQSAQMSIFIAI2AhAgBSAANgIIIAVCADcCACAFQgA3AhQgBUEANgIcIAQgBTYCACAFIQAgAygC0AEoAgAiCARAIAMgCDYC0AEgBCgCACEACyADKALUASAAEKQBIAMgAygC2AFBAWo2AtgBCwJAIAVBFGoiACABQfADakYNACABLQD7AyIIwCEEIAUsAB9BAE4EQCAEQQBOBEAgACABKQPwAzcCACAAIAEoAvgDNgIIDAILIAAgASgC8AMgASgC9AMQ3gEMAQsgACABKALwAyABQfADaiAEQQBIIgAbIAEoAvQDIAggABsQ3wELIAJBAWoiAiADKAIgSA0ACwsgAygCwAEhACABQaslNgLQASABIAAgAEGYlQNKa0G1lANrNgLUAUEEQaHsACABQdABahA0IAEoArAEIgAEQCABIAA2ArQEIAAQLwsgASwA+wNBAEgEQCABKALwAxAvCyADKAIQIQQgAygCMCEAIAMoAkAhBSABQQE6APgDIAEgASgC+AM2AsgBIAEgAEEPbCAFQRhsakEZakGsAmw2AvADQQAhACABQQA2AvQDIAEgASkC8AM3A8ABIAMgAUHAAWoQvQEiBTYCqAEgBUUEQCABQaslNgIAQQJBmOkAIAEQNAwBCyADNAJEIScgAygCQCELIAMoAjghECADNAI0ISggAygCKCETIAMoAiQhFCADNAIgISkCQCADKAIwIgggAygClAEiACADKAKQASIGa0E8bSIF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ahA8IAEoArAEIAU2AhwgASwA+wNBAEgEQCABKALwAxAvCyAIQQBKBEAgE0ECdKwhJ0EAIQUDQCADKAKQASAFQTxsaiIAIAMoAqgBQQAgJhBJNgIkIAAgAygCqAFBACAmEEk2AiggACADKAKoASAEICYgJxBVNgIsIAAgAygCqAFBACAnEEk2AjAgACADKAKoASAEICcgJhBVNgI0IAAgAygCqAFBACAmEEk2AjggACADKAKoAUEAICYQSTYCACAAIAMoAqgBQQAgJhBJNgIEIAAgAygCqAEgBCAmICYQVTYCECAAIAMoAqgBQQAgJhBJNgIUIAAgAygCqAEgBCAmICYQVTYCGCAAIAMoAqgBIAQgJiAmEFU2AhwgACADKAKoAUEAICYQSTYCICAAIAMoAqgBIAQgJiAmEFU2AgggACADKAKoAUEAICYQSTYCDCAAKAIkIQkgAUGgBGoiAiAFEDkgASACQfTBABA4IgIoAgg2ArgEIAEgAikCADcDsAQgAkIANwIAIAJBADYCCCABIAFBsARqQYwNEDciAigCCDYC+AMgASACKQIANwPwAyACQgA3AgAgAkEANgIIIAEgAUHwA2oiAjYC5AMgAUGUBGogBiACIAFB5ANqEDwgASgClAQgCTYCHCABLAD7A0EASARAIAEoAvADEC8LIAEsALsEQQBIBEAgASgCsAQQLwsgASwAqwRBAEgEQCABKAKgBBAvCyAAKAIoIQkgAUGgBGoiAiAFEDkgASACQfTBABA4IgIoAgg2ArgEIAEgAikCADcDsAQgAkIANwIAIAJBADYCCCABIAFBsARqQfcREDciAigCCDYC+AMgASACKQIANwPwAyACQgA3AgAgAkEANgIIIAEgAUHwA2oiAjYC5AMgAUGUBGogBiACIAFB5ANqEDwgASgClAQgCTYCHCABLAD7A0EASARAIAEoAvADEC8LIAEsALsEQQBIBEAgASgCsAQQLwsgASwAqwRBAEgEQCABKAKgBBAvCyAAKAIsIQkgAUGgBGoiAiAFEDkgASACQfTBABA4IgIoAgg2ArgEIAEgAikCADcDsAQgAkIANwIAIAJBADYCCCABIAFBsARqQdYOEDciAigCCDYC+AMgASACKQIANwPwAyACQgA3AgAgAkEANgIIIAEgAUHwA2oiAjYC5AMgAUGUBGogBiACIAFB5ANqEDwgASgClAQgCTYCHCABLAD7A0EASARAIAEoAvADEC8LIAEsALsEQQBIBEAgASgCsAQQLwsgASwAqwRBAEgEQCABKAKgBBAvCyAAKAIwIQkgAUGgBGoiAiAFEDkgASACQfTBABA4IgIoAgg2ArgEIAEgAikCADcDsAQgAkIANwIAIAJBADYCCCABIAFBsARqQZATEDciAigCCDYC+AMgASACKQIANwPwAyACQgA3AgAgAkEANgIIIAEgAUHwA2oiAjYC5AMgAUGUBGogBiACIAFB5ANqEDwgASgClAQgCTYCHCABLAD7A0EASARAIAEoAvADEC8LIAEsALsEQQBIBEAgASgCsAQQLwsgASwAqwRBAEgEQCABKAKgBBAvCyAAKAI0IQkgAUGgBGoiAiAFEDkgASACQfTBABA4IgIoAgg2ArgEIAEgAikCADcDsAQgAkIANwIAIAJBADYCCCABIAFBsARqQbMOEDciAigCCDYC+AMgASACKQIANwPwAyACQgA3AgAgAkEANgIIIAEgAUHwA2oiAjYC5AMgAUGUBGogBiACIAFB5ANqEDwgASgClAQgCTYCHCABLAD7A0EASARAIAEoAvADEC8LIAEsALsEQQBIBEAgASgCsAQQLwsgASwAqwRBAEgEQCABKAKgBBAvCyAAKAI4IQkgAUGgBGoiAiAFEDkgASACQfTBABA4IgIoAgg2ArgEIAEgAikCADcDsAQgAkIANwIAIAJBADYCCCABIAFBsARqQfESEDciAigCCDYC+AMgASACKQIANwPwAyACQgA3AgAgAkEANgIIIAEgAUHwA2oiAjYC5AMgAUGUBGogBiACIAFB5ANqEDwgASgClAQgCTYCHCABLAD7A0EASARAIAEoAvADEC8LIAEsALsEQQBIBEAgASgCsAQQLwsgASwAqwRBAEgEQCABKAKgBBAvCyAAKAIAIQkgAUGgBGoiAiAFEDkgASACQfTBABA4IgIoAgg2ArgEIAEgAikCADcDsAQgAkIANwIAIAJBADYCCCABIAFBsARqQbENEDciAigCCDYC+AMgASACKQIANwPwAyACQgA3AgAgAkEANgIIIAEgAUHwA2oiAjYC5AMgAUGUBGogBiACIAFB5ANqEDwgASgClAQgCTYCHCABLAD7A0EASARAIAEoAvADEC8LIAEsALsEQQBIBEAgASgCsAQQLwsgASwAqwRBAEgEQCABKAKgBBAvCyAAKAIEIQkgAUGgBGoiAiAFEDkgASACQfTBABA4IgIoAgg2ArgEIAEgAikCADcDsAQgAkIANwIAIAJBADYCCCABIAFBsARqQZgSEDciAigCCDYC+AMgASACKQIANwPwAyACQgA3AgAgAkEANgIIIAEgAUHwA2oiAjYC5AMgAUGUBGogBiACIAFB5ANqEDwgASgClAQgCTYCHCABLAD7A0EASARAIAEoAvADEC8LIAEsALsEQQBIBEAgASgCsAQQLwsgASwAqwRBAEgEQCABKAKgBBAvCyAAKAIQIQkgAUGgBGoiAiAFEDkgASACQfTBABA4IgIoAgg2ArgEIAEgAikCADcDsAQgAkIANwIAIAJBADYCCCABIAFBsARqQZIMEDciAigCCDYC+AMgASACKQIANwPwAyACQgA3AgAgAkEANgIIIAEgAUHwA2oiAjYC5AMgAUGUBGogBiACIAFB5ANqEDwgASgClAQgCTYCHCABLAD7A0EASARAIAEoAvADEC8LIAEsALsEQQBIBEAgASgCsAQQLwsgASwAqwRBAEgEQCABKAKgBBAvCyAAKAIUIQkgAUGgBGoiAiAFEDkgASACQfTBABA4IgIoAgg2ArgEIAEgAikCADcDsAQgAkIANwIAIAJBADYCCCABIAFBsARqQa0REDciAigCCDYC+AMgASACKQIANwPwAyACQgA3AgAgAkEANgIIIAEgAUHwA2oiAjYC5AMgAUGUBGogBiACIAFB5ANqEDwgASgClAQgCTYCHCABLAD7A0EASARAIAEoAvADEC8LIAEsALsEQQBIBEAgASgCsAQQLwsgASwAqwRBAEgEQCABKAKgBBAvCyAAKAIYIQkgAUGgBGoiAiAFEDkgASACQfTBABA4IgIoAgg2ArgEIAEgAikCADcDsAQgAkIANwIAIAJBADYCCCABIAFBsARqQbwMEDciAigCCDYC+AMgASACKQIANwPwAyACQgA3AgAgAkEANgIIIAEgAUHwA2oiAjYC5AMgAUGUBGogBiACIAFB5ANqEDwgASgClAQgCTYCHCABLAD7A0EASARAIAEoAvADEC8LIAEsALsEQQBIBEAgASgCsAQQLwsgASwAqwRBAEgEQCABKAKgBBAvCyAAKAIcIQkgAUGgBGoiAiAFEDkgASACQfTBABA4IgIoAgg2ArgEIAEgAikCADcDsAQgAkIANwIAIAJBADYCCCABIAFBsARqQYsOEDciAigCCDYC+AMgASACKQIANwPwAyACQgA3AgAgAkEANgIIIAEgAUHwA2oiAjYC5AMgAUGUBGogBiACIAFB5ANqEDwgASgClAQgCTYCHCABLAD7A0EASARAIAEoAvADEC8LIAEsALsEQQBIBEAgASgCsAQQLwsgASwAqwRBAEgEQCABKAKgBBAvCyAAKAIgIQkgAUGgBGoiAiAFEDkgASACQfTBABA4IgIoAgg2ArgEIAEgAikCADcDsAQgAkIANwIAIAJBADYCCCABIAFBsARqQc0SEDciAigCCDYC+AMgASACKQIANwPwAyACQgA3AgAgAkEANgIIIAEgAUHwA2oiAjYC5AMgAUGUBGogBiACIAFB5ANqEDwgASgClAQgCTYCHCABLAD7A0EASARAIAEoAvADEC8LIAEsALsEQQBIBEAgASgCsAQQLwsgASwAqwRBAEgEQCABKAKgBBAvCyAAKAIIIQkgAUGgBGoiAiAFEDkgASACQfTBABA4IgIoAgg2ArgEIAEgAikCADcDsAQgAkIANwIAIAJBADYCCCABIAFBsARqQeQMEDciAigCCDYC+AMgASACKQIANwPwAyACQgA3AgAgAkEANgIIIAEgAUHwA2oiAjYC5AMgAUGUBGogBiACIAFB5ANqEDwgASgClAQgCTYCHCABLAD7A0EASARAIAEoAvADEC8LIAEsALsEQQBIBEAgASgCsAQQLwsgASwAqwRBAEgEQCABKAKgBBAvCyAAKAIMIQIgAUGgBGoiACAFEDkgASAAQfTBABA4IgAoAgg2ArgEIAEgACkCADcDsAQgAEIANwIAIABBADYCCCABIAFBsARqQdMREDciACgCCDYC+AMgASAAKQIANwPwAyAAQgA3AgAgAEEANgIIIAEgAUHwA2oiADYC5AMgAUGUBGogBiAAIAFB5ANqEDwgASgClAQgAjYCHCABLAD7A0EASARAIAEoAvADEC8LIAEsALsEQQBIBEAgASgCsAQQLwsgASwAqwRBAEgEQCABKAKgBBAvCyAFQQFqIgUgCEcNAAsLIAMgAygCqAFBACAQrCImICgQVTYCgAEgAyADKAKoASAEICYgKRBVNgKEASADIAMoAqgBQQAgJhBJNgKIASADIAMoAqgBQQAgJhBJNgKMASADKAKAASEFIAFBIBAxIgA2AvADIAFCnICAgICEgICAfzcC9AMgAEGQHigAADYAGCAAQYgeKQAANwAQIABB+B39AAAA/QsAACAAQQA6ABwgASABQfADaiIANgKgBCABQbAEaiAGIAAgAUGgBGoQPCABKAKwBCAFNgIcIAEsAPsDQQBIBEAgASgC8AMQLwsgAygChAEhBSABQSAQMSIANgLwAyABQp6AgICAhICAgH83AvQDIABB6Q0pAAA3ABYgAEHjDSkAADcAECAAQdMN/QAAAP0LAAAgAEEAOgAeIAEgAUHwA2oiADYCoAQgAUGwBGogBiAAIAFBoARqEDwgASgCsAQgBTYCHCABLAD7A0EASARAIAEoAvADEC8LIAMoAogBIQUgAUEgEDEiADYC8AMgAUKRgICAgISAgIB/NwL0AyAAQdENLQAAOgAQIABBwQ39AAAA/QsAACAAQQA6ABEgASABQfADaiIANgKgBCABQbAEaiAGIAAgAUGgBGoQPCABKAKwBCAFNgIcIAEsAPsDQQBIBEAgASgC8AMQLwsgAygCjAEhBSABQRAQMSIANgLwAyABQo+AgICAgoCAgH83AvQDIABBrRIpAAA3AAcgAEGmEikAADcAACAAQQA6AA8gASABQfADaiIANgKgBCABQbAEaiAGIAAgAUGgBGoQPCABKAKwBCAFNgIcIAEsAPsDQQBIBEAgASgC8AMQLwsgC0EASgRAIBBBAnSsISdBACEFA0AgAygCnAEgBUHgAGxqIgAgAygCqAFBACAmEEk2AkggACADKAKoAUEAICYQSTYCTCAAIAMoAqgBIAQgJiAnEFU2AlAgACADKAKoAUEAICcQSTYCVCAAIAMoAqgBIAQgJyAmEFU2AlggACADKAKoAUEAICYQSTYCXCAAIAMoAqgBQQAgJhBJNgIAIAAgAygCqAFBACAmEEk2AgQgACADKAKoASAEICYgJhBVNgIQIAAgAygCqAFBACAmEEk2AhQgACADKAKoASAEICYgJhBVNgIYIAAgAygCqAEgBCAmICYQVTYCHCAAIAMoAqgBQQAgJhBJNgIgIAAgAygCqAEgBCAmICYQVTYCCCAAIAMoAqgBQQAgJhBJNgIMIAAgAygCqAFBACAmEEk2AiQgACADKAKoAUEAICYQSTYCKCAAIAMoAqgBIAQgJiAmEFU2AjQgACADKAKoAUEAICYQSTYCOCAAIAMoAqgBIAQgJiAmEFU2AjwgACADKAKoASAEICYgJhBVNgJAIAAgAygCqAFBACAmEEk2AkQgACADKAKoASAEICYgJhBVNgIsIAAgAygCqAFBACAmEEk2AjAgACgCSCEIIAFBoARqIgIgBRA5IAEgAkGEwgAQOCICKAIINgK4BCABIAIpAgA3A7AEIAJCADcCACACQQA2AgggASABQbAEakGMDRA3IgIoAgg2AvgDIAEgAikCADcD8AMgAkIANwIAIAJBADYCCCABIAFB8ANqIgI2AuQDIAFBlARqIAYgAiABQeQDahA8IAEoApQEIAg2AhwgASwA+wNBAEgEQCABKALwAxAvCyABLAC7BEEASARAIAEoArAEEC8LIAEsAKsEQQBIBEAgASgCoAQQLwsgACgCTCEIIAFBoARqIgIgBRA5IAEgAkGEwgAQOCICKAIINgK4BCABIAIpAgA3A7AEIAJCADcCACACQQA2AgggASABQbAEakH3ERA3IgIoAgg2AvgDIAEgAikCADcD8AMgAkIANwIAIAJBADYCCCABIAFB8ANqIgI2AuQDIAFBlARqIAYgAiABQeQDahA8IAEoApQEIAg2AhwgASwA+wNBAEgEQCABKALwAxAvCyABLAC7BEEASARAIAEoArAEEC8LIAEsAKsEQQBIBEAgASgCoAQQLwsgACgCUCEIIAFBoARqIgIgBRA5IAEgAkGEwgAQOCICKAIINgK4BCABIAIpAgA3A7AEIAJCADcCACACQQA2AgggASABQbAEakHWDhA3IgIoAgg2AvgDIAEgAikCADcD8AMgAkIANwIAIAJBADYCCCABIAFB8ANqIgI2AuQDIAFBlARqIAYgAiABQeQDahA8IAEoApQEIAg2AhwgASwA+wNBAEgEQCABKALwAxAvCyABLAC7BEEASARAIAEoArAEEC8LIAEsAKsEQQBIBEAgASgCoAQQLwsgACgCVCEIIAFBoARqIgIgBRA5IAEgAkGEwgAQOCICKAIINgK4BCABIAIpAgA3A7AEIAJCADcCACACQQA2AgggASABQbAEakGQExA3IgIoAgg2AvgDIAEgAikCADcD8AMgAkIANwIAIAJBADYCCCABIAFB8ANqIgI2AuQDIAFBlARqIAYgAiABQeQDahA8IAEoApQEIAg2AhwgASwA+wNBAEgEQCABKALwAxAvCyABLAC7BEEASARAIAEoArAEEC8LIAEsAKsEQQBIBEAgASgCoAQQLwsgACgCWCEIIAFBoARqIgIgBRA5IAEgAkGEwgAQOCICKAIINgK4BCABIAIpAgA3A7AEIAJCADcCACACQQA2AgggASABQbAEakGzDhA3IgIoAgg2AvgDIAEgAikCADcD8AMgAkIANwIAIAJBADYCCCABIAFB8ANqIgI2AuQDIAFBlARqIAYgAiABQeQDahA8IAEoApQEIAg2AhwgASwA+wNBAEgEQCABKALwAxAvCyABLAC7BEEASARAIAEoArAEEC8LIAEsAKsEQQBIBEAgASgCoAQQLwsgACgCXCEIIAFBoARqIgIgBRA5IAEgAkGEwgAQOCICKAIINgK4BCABIAIpAgA3A7AEIAJCADcCACACQQA2AgggASABQbAEakHxEhA3IgIoAgg2AvgDIAEgAikCADcD8AMgAkIANwIAIAJBADYCCCABIAFB8ANqIgI2AuQDIAFBlARqIAYgAiABQeQDahA8IAEoApQEIAg2AhwgASwA+wNBAEgEQCABKALwAxAvCyABLAC7BEEASARAIAEoArAEEC8LIAEsAKsEQQBIBEAgASgCoAQQLwsgACgCACEIIAFBoARqIgIgBRA5IAEgAkGEwgAQOCICKAIINgK4BCABIAIpAgA3A7AEIAJCADcCACACQQA2AgggASABQbAEakGxDRA3IgIoAgg2AvgDIAEgAikCADcD8AMgAkIANwIAIAJBADYCCCABIAFB8ANqIgI2AuQDIAFBlARqIAYgAiABQeQDahA8IAEoApQEIAg2AhwgASwA+wNBAEgEQCABKALwAxAvCyABLAC7BEEASARAIAEoArAEEC8LIAEsAKsEQQBIBEAgASgCoAQQLwsgACgCBCEIIAFBoARqIgIgBRA5IAEgAkGEwgAQOCICKAIINgK4BCABIAIpAgA3A7AEIAJCADcCACACQQA2AgggASABQbAEakGYEhA3IgIoAgg2AvgDIAEgAikCADcD8AMgAkIANwIAIAJBADYCCCABIAFB8ANqIgI2AuQDIAFBlARqIAYgAiABQeQDahA8IAEoApQEIAg2AhwgASwA+wNBAEgEQCABKALwAxAvCyABLAC7BEEASARAIAEoArAEEC8LIAEsAKsEQQBIBEAgASgCoAQQLwsgACgCECEIIAFBoARqIgIgBRA5IAEgAkGEwgAQOCICKAIINgK4BCABIAIpAgA3A7AEIAJCADcCACACQQA2AgggASABQbAEakGSDBA3IgIoAgg2AvgDIAEgAikCADcD8AMgAkIANwIAIAJBADYCCCABIAFB8ANqIgI2AuQDIAFBlARqIAYgAiABQeQDahA8IAEoApQEIAg2AhwgASwA+wNBAEgEQCABKALwAxAvCyABLAC7BEEASARAIAEoArAEEC8LIAEsAKsEQQBIBEAgASgCoAQQLwsgACgCFCEIIAFBoARqIgIgBRA5IAEgAkGEwgAQOCICKAIINgK4BCABIAIpAgA3A7AEIAJCADcCACACQQA2AgggASABQbAEakGtERA3IgIoAgg2AvgDIAEgAikCADcD8AMgAkIANwIAIAJBADYCCCABIAFB8ANqIgI2AuQDIAFBlARqIAYgAiABQeQDahA8IAEoApQEIAg2AhwgASwA+wNBAEgEQCABKALwAxAvCyABLAC7BEEASARAIAEoArAEEC8LIAEsAKsEQQBIBEAgASgCoAQQLwsgACgCGCEIIAFBoARqIgIgBRA5IAEgAkGEwgAQOCICKAIINgK4BCABIAIpAgA3A7AEIAJCADcCACACQQA2AgggASABQbAEakG8DBA3IgIoAgg2AvgDIAEgAikCADcD8AMgAkIANwIAIAJBADYCCCABIAFB8ANqIgI2AuQDIAFBlARqIAYgAiABQeQDahA8IAEoApQEIAg2AhwgASwA+wNBAEgEQCABKALwAxAvCyABLAC7BEEASARAIAEoArAEEC8LIAEsAKsEQQBIBEAgASgCoAQQLwsgACgCHCEIIAFBoARqIgIgBRA5IAEgAkGEwgAQOCICKAIINgK4BCABIAIpAgA3A7AEIAJCADcCACACQQA2AgggASABQbAEakGLDhA3IgIoAgg2AvgDIAEgAikCADcD8AMgAkIANwIAIAJBADYCCCABIAFB8ANqIgI2AuQDIAFBlARqIAYgAiABQeQDahA8IAEoApQEIAg2AhwgASwA+wNBAEgEQCABKALwAxAvCyABLAC7BEEASARAIAEoArAEEC8LIAEsAKsEQQBIBEAgASgCoAQQLwsgACgCICEIIAFBoARqIgIgBRA5IAEgAkGEwgAQOCICKAIINgK4BCABIAIpAgA3A7AEIAJCADcCACACQQA2AgggASABQbAEakHNEhA3IgIoAgg2AvgDIAEgAikCADcD8AMgAkIANwIAIAJBADYCCCABIAFB8ANqIgI2AuQDIAFBlARqIAYgAiABQeQDahA8IAEoApQEIAg2AhwgASwA+wNBAEgEQCABKALwAxAvCyABLAC7BEEASARAIAEoArAEEC8LIAEsAKsEQQBIBEAgASgCoAQQLwsgACgCCCEIIAFBoARqIgIgBRA5IAEgAkGEwgAQOCICKAIINgK4BCABIAIpAgA3A7AEIAJCADcCACACQQA2AgggASABQbAEakHkDBA3IgIoAgg2AvgDIAEgAikCADcD8AMgAkIANwIAIAJBADYCCCABIAFB8ANqIgI2AuQDIAFBlARqIAYgAiABQeQDahA8IAEoApQEIAg2AhwgASwA+wNBAEgEQCABKALwAxAvCyABLAC7BEEASARAIAEoArAEEC8LIAEsAKsEQQBIBEAgASgCoAQQLwsgACgCDCEIIAFBoARqIgIgBRA5IAEgAkGEwgAQOCICKAIINgK4BCABIAIpAgA3A7AEIAJCADcCACACQQA2AgggASABQbAEakHTERA3IgIoAgg2AvgDIAEgAikCADcD8AMgAkIANwIAIAJBADYCCCABIAFB8ANqIgI2AuQDIAFBlARqIAYgAiABQeQDahA8IAEoApQEIAg2AhwgASwA+wNBAEgEQCABKALwAxAvCyABLAC7BEEASARAIAEoArAEEC8LIAEsAKsEQQBIBEAgASgCoAQQLwsgACgCJCEIIAFBoARqIgIgBRA5IAEgAkGEwgAQOCICKAIINgK4BCABIAIpAgA3A7AEIAJCADcCACACQQA2AgggASABQbAEakGbDRA3IgIoAgg2AvgDIAEgAikCADcD8AMgAkIANwIAIAJBADYCCCABIAFB8ANqIgI2AuQDIAFBlARqIAYgAiABQeQDahA8IAEoApQEIAg2AhwgASwA+wNBAEgEQCABKALwAxAvCyABLAC7BEEASARAIAEoArAEEC8LIAEsAKsEQQBIBEAgASgCoAQQLwsgACgCKCEIIAFBoARqIgIgBRA5IAEgAkGEwgAQOCICKAIINgK4BCABIAIpAgA3A7AEIAJCADcCACACQQA2AgggASABQbAEakGEEhA3IgIoAgg2AvgDIAEgAikCADcD8AMgAkIANwIAIAJBADYCCCABIAFB8ANqIgI2AuQDIAFBlARqIAYgAiABQeQDahA8IAEoApQEIAg2AhwgASwA+wNBAEgEQCABKALwAxAvCyABLAC7BEEASARAIAEoArAEEC8LIAEsAKsEQQBIBEAgASgCoAQQLwsgACgCNCEIIAFBoARqIgIgBRA5IAEgAkGEwgAQOCICKAIINgK4BCABIAIpAgA3A7AEIAJCADcCACACQQA2AgggASABQbAEakH5CxA3IgIoAgg2AvgDIAEgAikCADcD8AMgAkIANwIAIAJBADYCCCABIAFB8ANqIgI2AuQDIAFBlARqIAYgAiABQeQDahA8IAEoApQEIAg2AhwgASwA+wNBAEgEQCABKALwAxAvCyABLAC7BEEASARAIAEoArAEEC8LIAEsAKsEQQBIBEAgASgCoAQQLwsgACgCOCEIIAFBoARqIgIgBRA5IAEgAkGEwgAQOCICKAIINgK4BCABIAIpAgA3A7AEIAJCADcCACACQQA2AgggASABQbAEakGWERA3IgIoAgg2AvgDIAEgAikCADcD8AMgAkIANwIAIAJBADYCCCABIAFB8ANqIgI2AuQDIAFBlARqIAYgAiABQeQDahA8IAEoApQEIAg2AhwgASwA+wNBAEgEQCABKALwAxAvCyABLAC7BEEASARAIAEoArAEEC8LIAEsAKsEQQBIBEAgASgCoAQQLwsgACgCPCEIIAFBoARqIgIgBRA5IAEgAkGEwgAQOCICKAIINgK4BCABIAIpAgA3A7AEIAJCADcCACACQQA2AgggASABQbAEakGlDBA3IgIoAgg2AvgDIAEgAikCADcD8AMgAkIANwIAIAJBADYCCCABIAFB8ANqIgI2AuQDIAFBlARqIAYgAiABQeQDahA8IAEoApQEIAg2AhwgASwA+wNBAEgEQCABKALwAxAvCyABLAC7BEEASARAIAEoArAEEC8LIAEsAKsEQQBIBEAgASgCoAQQLwsgAEFAaygCACEIIAFBoARqIgIgBRA5IAEgAkGEwgAQOCICKAIINgK4BCABIAIpAgA3A7AEIAJCADcCACACQQA2AgggASABQbAEakHyDRA3IgIoAgg2AvgDIAEgAikCADcD8AMgAkIANwIAIAJBADYCCCABIAFB8ANqIgI2AuQDIAFBlARqIAYgAiABQeQDahA8IAEoApQEIAg2AhwgASwA+wNBAEgEQCABKALwAxAvCyABLAC7BEEASARAIAEoArAEEC8LIAEsAKsEQQBIBEAgASgCoAQQLwsgACgCRCEIIAFBoARqIgIgBRA5IAEgAkGEwgAQOCICKAIINgK4BCABIAIpAgA3A7AEIAJCADcCACACQQA2AgggASABQbAEakG2EhA3IgIoAgg2AvgDIAEgAikCADcD8AMgAkIANwIAIAJBADYCCCABIAFB8ANqIgI2AuQDIAFBlARqIAYgAiABQeQDahA8IAEoApQEIAg2AhwgASwA+wNBAEgEQCABKALwAxAvCyABLAC7BEEASARAIAEoArAEEC8LIAEsAKsEQQBIBEAgASgCoAQQLwsgACgCLCEIIAFBoARqIgIgBRA5IAEgAkGEwgAQOCICKAIINgK4BCABIAIpAgA3A7AEIAJCADcCACACQQA2AgggASABQbAEakHNDBA3IgIoAgg2AvgDIAEgAikCADcD8AMgAkIANwIAIAJBADYCCCABIAFB8ANqIgI2AuQDIAFBlARqIAYgAiABQeQDahA8IAEoApQEIAg2AhwgASwA+wNBAEgEQCABKALwAxAvCyABLAC7BEEASARAIAEoArAEEC8LIAEsAKsEQQBIBEAgASgCoAQQLwsgACgCMCECIAFBoARqIgAgBRA5IAEgAEGEwgAQOCIAKAIINgK4BCABIAApAgA3A7AEIABCADcCACAAQQA2AgggASABQbAEakG+ERA3IgAoAgg2AvgDIAEgACkCADcD8AMgAEIANwIAIABBADYCCCABIAFB8ANqIgA2AuQDIAFBlARqIAYgACABQeQDahA8IAEoApQEIAI2AhwgASwA+wNBAEgEQCABKALwAxAvCyABLAC7BEEASARAIAEoArAEEC8LIAEsAKsEQQBIBEAgASgCoAQQLwsgBUEBaiIFIAtHDQALCyADEOUEIgA2AoQCQQAhBSADKAK0ASIEIANBuAFqIgtHBEADQCAEKAIcEF8gBWohHQJAIAQoAgQiBQRAA0AgBSIAKAIAIgUNAAwCCwALA0AgBCgCCCIAKAIAIARHIRwgACEEIBwNAAsLIB1BrAJqIQUgCyAAIgRHDQALIAMoAoQCIQALIAMgACAFIAAoAggRBAA2AqwBIAMoAoQCIgAEfyAAIAAoAgARAQAFQesvCyEAIAEgBbhEAAAAAICELkGjOQO4ASABIAA2ArQBIAFBqyU2ArABQQRBou4AIAFBsAFqEDQgAygCrAEQyQEhCSALIAMoArQBIgRHBEADQCAJIAQoAhwQjgECQCAEKAIEIgUEQANAIAUiACgCACIFDQAMAgsACwNAIAQoAggiACgCACAERyEeIAAhBCAeDQALCyALIAAiBEcNAAsLIANBADYCsAEgAUEANgK4BCABQgA3ArAEQQAhCANAAkAgBygCJCABQZAEakEEIAcoAigRAwAaIAcoAiQgAUGMBGpBBCAHKAIoEQMAGiAHKAIkIAFBiARqQQQgBygCKBEDABoCQAJAAkAgBygCJCAHKAIsEQEABEAgAUGrJTYCMCABIAi4RAAAAACAhC5BozkDOEEEQZ7wACABQTBqEDQgAygCsAEiAA0BIAFBqyU2AhBBA0Ge5QAgAUEQahA0QQAhBAwEC0EAIQAgAUHApAH9AAQA/QsE8ANBASEFIAEoApAEQQBKDQEMAgtBACEEIAAgAygCvAEiBUYNAiABIAA2AiggASAFNgIkIAFBqyU2AiBBAkHM6QAgAUEgahA0QQEhBAwCCwNAIAcoAiQgAUHwA2ogAEECdGoiBEEEIAcoAigRAwAaIAQoAgAgBWwhBSAAQQFqIgAgASgCkARIDQALC0EAIQIgAUEANgKoBCABQgA3A6AEIAFBADYCnAQgAUIANwKUBEEAIQAgASgCjAQiBARAIARBAEgNBCABIAQQMSIANgKUBCABIAAgBGoiAjYCnAQgAEEAIAT8CwAgASACNgKYBAsgBygCJCAAIAIgAGsiAiAHKAIoEQMAGiABQaAEaiIEIAAgAhDMAQJ/IAYgBBDxAiALRgRAIAFBqyU2AkAgASABKAKgBCAEIAEsAKsEQQBIGzYCREECQdHmACABQUBrEDRBASEEQQAMAQsgASgCoAQgAUGgBGogASwAqwRBAEgbIgIQaSIAQfD///8HTw0FAkAgAEEKTQRAIAEgADoA7wMgAUHkA2ohBAwBCyAAQQ9yQQFqIgwQMSEEIAEgDEGAgICAeHI2AuwDIAEgBDYC5AMgASAANgLoAwsgBCACIAD8CgAAIAAgBGpBADoAACABIAFB5ANqIgA2AsQEIAFByARqIAYgACABQcQEahA8IAEoAsgEKAIcIQQgASwA7wNBAEgEQCABKALkAxAvCwJAIAEoAqQEIAEsAKsEIgBB/wFxIABBAEgiABtBEkYEQEEBIQIgASgCoAQgAUGgBGogABsiAEH9EkESEEZFDQEgAEHeEkESEEZFDQELIAWsIAQpAyggBCkDICAEKQMYIAQpAxB+fn5SBEAgAUGrJTYCoAEgASABKAKgBCABQaAEaiABLACrBEEASBs2AqQBQQJBo+YAIAFBoAFqEDQgBCkDICEmIAQpAxghJyABIAQpAxA+ApABIAEgJz4ClAEgASAmPgKYASABQaslNgKAASABIAEoAvADNgKEASABIAEpAvQDNwOIAUECQfHtACABQYABahA0QQEhBEEADAILIAQpAxghJiABKAL0AyEAAkACQCAEKQMQIicgASgC8AMiDKxSBEAgASgC+AMhAgwBCyABKAL4AyECICYgAKxSDQAgBCkDICACrFENAQsgASAEKQMgPgJwIAEgDDYCdCABIAA2AnggASACNgJ8IAFBqyU2AmAgASABKAKgBCABQaAEaiABLACrBEEASBs2AmQgASAnPgJoIAEgJj4CbEECQZntACABQeAAahA0QQEhBEEADAILQQAhAiAFIAEoAogEQSRsQZiaAWooAgBsIgAgBCgCAEEkbEGUmgFqKAIAbiAEEF9GDQAgASgCoAQhBSABLACrBCECIAQQXyEEIAEgADYCXCABIAQ2AlggAUGrJTYCUCABIAUgAUGgBGogAkEASBs2AlRBAkH14AAgAUHQAGoQNEEBIQRBAAwBCyADKAKEAigCAEE6RiEAAkACQCACDQAgAEUNACAHKAIoIQAgBygCJCAEKALAASAEEF8gABEDABoMAQsCQCAEEF8iACABKAK0BCABKAKwBCIMayIFSwRAIAFBsARqIAAgBWsQ8gIMAQsgACAFTw0AIAEgACAMajYCtAQLIAEoArQEIAEoArAEIgBrIQUgBygCKCEMIAcoAiQhEAJAIAIEQCAQIAAgBa0gBCkDEH+nIAwRAwAaIAEoArAEIQAgBCkDGCIqQgBXDQEgBCkDECIoQgBXDQEgKEJ8gyEnQgAhKQNAICggKiApQn+FfCImfiErIAAgJqdBAnRqKgIAIS9CACEmAkAgKEIEWgRAIC/9EyEtA0AgACAmICt8p0ECdGogLf0LAgAgJkIEfCImICdSDQALICciJiAoUQ0BCwNAIAAgJiArfKdBAnRqIC84AgAgJkIBfCImIChSDQALCyApQgF8IikgKlINAAsMAQsgECAAIAUgDBEDABogASgCsAQhAAsgBCAAQQAgBBBfEJcBCyAEEF8hHyADIAMoArABQQFqNgKwASAfIAhqIQhBACEEQQELISAgASgClAQiBQRAIAUQLwsgASwAqwRBAEgEQCABKAKgBBAvCyAgDQELCyABKAKwBCIABEAgASAANgK0BCAAEC8LQQAhACAEDQAgCRCPASADEGsgLH03AwBBASEACyABQdAEaiQAIAAMAgsQNgALEE0ACyEhIAcoAiQgBygCMBEAACAhRQRAIA9Bth82AgBBAkHN5AAgDxA0IAMsAJMCQQBIBEAgAygCiAIQLwsgGCADKALUARCPAiAXIAMoAsgBEI4CIBYgAygCuAEQjQIgAygCnAEiAARAIAMgADYCoAEgABAvCyADKAKQASIABEAgAyAANgKUASAAEC8LIAMoAlgiAARAIAMgADYCXCAAEC8LIAMQL0EAIQMLIA9BEGokACADRQ0AIANBiAJqIA4QiAMLIAdB4MkCKAIAIgA2AjQgAEEMaygCACAHQTRqakHsyQIoAgA2AgAgChDyARogIhDBAiAHQfABaiQAIAMiAARAIAACf0EAIQMjAEHQFGsiASQAIAEgACIKNgLMFEHM1jQtAABFBED9DAAAAAABAAAAAgAAAAMAAAAhLQNAIANBAnQiAEHQ1jRqIC39/gH9DBgtRFT7IRlAGC1EVPshGUD98gH9DAAAAAAAAHlAAAAAAAAAeUD98wEiLv0hALYiLxBq/RMgLv0hAbYiMBBq/SABIC0gLf0NCAkKCwwNDg8AAQIDAAECA/3+Af0MGC1EVPshGUAYLURU+yEZQP3yAf0MAAAAAAAAeUAAAAAAAAB5QP3zASIu/SEAtiIxEGr9IAIgLv0hAbYiMhBq/SAD/QsEACAAQZDjNGogLxBc/RMgMBBc/SABIDEQXP0gAiAyEFz9IAP9CwQAIC39DAQAAAAEAAAABAAAAAQAAAD9rgEhLSADQQRqIgNBkANHDQALQczWNEEBOgAAC0HgqAEQMSIG/QwAAAAAAAAAAAAAAAAAAAAA/QsCdCAGQgA3A9ABIAZCADcChAEgBkIANwOIAiAGQQA2AtgBIAZBADYCsAEgBkIANwOoASAG/QwAAAAAAAAAAAAAAAAAAAAA/QsDkAIgBv0MAAAAAAAAAAAAAAAAAAAAAP0LArQCIAb9DAAAAAAAAAAAAAAAAAAAAAD9CwLEAiAG/QwAAAAAAAAAAAAAAAAAAAAA/QsC1AIgBkEAQeQA/AsAQfEqIQQgBkHkAmoiAEHxKjYCAEEBIQMDQCAAIANBAnRqIARBHnYgBHNB5ZKe4AZsIANqIgQ2AgAgACADQQFqIgVBAnRqIARBHnYgBHNB5ZKe4AZsIAVqIgQ2AgAgACADQQJqIgVBAnRqIARBHnYgBHNB5ZKe4AZsIAVqIgQ2AgAgA0EDaiIFQfAERwRAIAAgBUECdGogBEEediAEc0Hlkp7gBmwgBWoiBDYCACADQQRqIQMMAQsLIAZB8BZqQgA3AwAgBkHgFmr9DAAAAAAAAAAAAAAAAAAAAAD9CwMAIAZBjBdq/QwAAAAAAAAAAAAAAAAAAAAA/QsCACAGQZwXav0MAAAAAAAAAAAAAAAAAAAAAP0LAgAgBkGsF2r9DAAAAAAAAAAAAAAAAAAAAAD9CwIAIAZBpBZq/QwAAAAAAAAAAAAAAAAAAAAA/QsCAEHxKiEEIAZBvBdqIgBB8So2AgBBASEDA0AgACADQQJ0aiAEQR52IARzQeWSnuAGbCADaiIENgIAIAAgA0EBaiIFQQJ0aiAEQR52IARzQeWSnuAGbCAFaiIENgIAIAAgA0ECaiIFQQJ0aiAEQR52IARzQeWSnuAGbCAFaiIENgIAIANBA2oiBUHwBEcEQCAAIAVBAnRqIARBHnYgBHNB5ZKe4AZsIAVqIgQ2AgAgA0EEaiEDDAELCyAGQcgrakIANwMAIAZBuCtq/QwAAAAAAAAAAAAAAAAAAAAA/QsDACAGQeQrav0MAAAAAAAAAAAAAAAAAAAAAP0LAgAgBkH0K2r9DAAAAAAAAAAAAAAAAAAAAAD9CwIAIAZBhCxq/QwAAAAAAAAAAAAAAAAAAAAA/QsCACAGQfwqav0MAAAAAAAAAAAAAAAAAAAAAP0LAgBB8SohBCAGQZQsaiIAQfEqNgIAQQEhAwNAIAAgA0ECdGogBEEediAEc0Hlkp7gBmwgA2oiBDYCACAAIANBAWoiBUECdGogBEEediAEc0Hlkp7gBmwgBWoiBDYCACAAIANBAmoiBUECdGogBEEediAEc0Hlkp7gBmwgBWoiBDYCACADQQNqIgVB8ARHBEAgACAFQQJ0aiAEQR52IARzQeWSnuAGbCAFaiIENgIAIANBBGohAwwBCwsgBkGgwABqQgA3AwAgBkGQwABq/QwAAAAAAAAAAAAAAAAAAAAA/QsDACAGQbzAAGr9DAAAAAAAAAAAAAAAAAAAAAD9CwIAIAZBzMAAav0MAAAAAAAAAAAAAAAAAAAAAP0LAgAgBkHcwABq/QwAAAAAAAAAAAAAAAAAAAAA/QsCACAGQdQ/av0MAAAAAAAAAAAAAAAAAAAAAP0LAgBB8SohBCAGQezAAGoiAEHxKjYCAEEBIQMDQCAAIANBAnRqIARBHnYgBHNB5ZKe4AZsIANqIgQ2AgAgACADQQFqIgVBAnRqIARBHnYgBHNB5ZKe4AZsIAVqIgQ2AgAgACADQQJqIgVBAnRqIARBHnYgBHNB5ZKe4AZsIAVqIgQ2AgAgA0EDaiIFQfAERwRAIAAgBUECdGogBEEediAEc0Hlkp7gBmwgBWoiBDYCACADQQRqIQMMAQsLIAZB+NQAakIANwMAIAZB6NQAav0MAAAAAAAAAAAAAAAAAAAAAP0LAwAgBkGU1QBq/QwAAAAAAAAAAAAAAAAAAAAA/QsCACAGQaTVAGr9DAAAAAAAAAAAAAAAAAAAAAD9CwIAIAZBtNUAav0MAAAAAAAAAAAAAAAAAAAAAP0LAgAgBkGs1ABq/QwAAAAAAAAAAAAAAAAAAAAA/QsCAEHxKiEEIAZBxNUAaiIAQfEqNgIAQQEhAwNAIAAgA0ECdGogBEEediAEc0Hlkp7gBmwgA2oiBDYCACAAIANBAWoiBUECdGogBEEediAEc0Hlkp7gBmwgBWoiBDYCACAAIANBAmoiBUECdGogBEEediAEc0Hlkp7gBmwgBWoiBDYCACADQQNqIgVB8ARHBEAgACAFQQJ0aiAEQR52IARzQeWSnuAGbCAFaiIENgIAIANBBGohAwwBCwsgBkHQ6QBqQgA3AwAgBkHA6QBq/QwAAAAAAAAAAAAAAAAAAAAA/QsDACAGQezpAGr9DAAAAAAAAAAAAAAAAAAAAAD9CwIAIAZB/OkAav0MAAAAAAAAAAAAAAAAAAAAAP0LAgAgBkGM6gBq/QwAAAAAAAAAAAAAAAAAAAAA/QsCACAGQYTpAGr9DAAAAAAAAAAAAAAAAAAAAAD9CwIAQfEqIQQgBkGc6gBqIgBB8So2AgBBASEDA0AgACADQQJ0aiAEQR52IARzQeWSnuAGbCADaiIENgIAIAAgA0EBaiIFQQJ0aiAEQR52IARzQeWSnuAGbCAFaiIENgIAIAAgA0ECaiIFQQJ0aiAEQR52IARzQeWSnuAGbCAFaiIENgIAIANBA2oiBUHwBEcEQCAAIAVBAnRqIARBHnYgBHNB5ZKe4AZsIAVqIgQ2AgAgA0EEaiEDDAELCyAGQaj+AGpCADcDACAGQZj+AGr9DAAAAAAAAAAAAAAAAAAAAAD9CwMAIAZBxP4Aav0MAAAAAAAAAAAAAAAAAAAAAP0LAgAgBkHU/gBq/QwAAAAAAAAAAAAAAAAAAAAA/QsCACAGQeT+AGr9DAAAAAAAAAAAAAAAAAAAAAD9CwIAIAZB3P0Aav0MAAAAAAAAAAAAAAAAAAAAAP0LAgBB8SohBCAGQfT+AGoiAEHxKjYCAEEBIQMDQCAAIANBAnRqIARBHnYgBHNB5ZKe4AZsIANqIgQ2AgAgACADQQFqIgVBAnRqIARBHnYgBHNB5ZKe4AZsIAVqIgQ2AgAgACADQQJqIgVBAnRqIARBHnYgBHNB5ZKe4AZsIAVqIgQ2AgAgA0EDaiIFQfAERwRAIAAgBUECdGogBEEediAEc0Hlkp7gBmwgBWoiBDYCACADQQRqIQMMAQsLIAZBgJMBakIANwMAIAZB8JIBav0MAAAAAAAAAAAAAAAAAAAAAP0LAwAgBkGckwFq/QwAAAAAAAAAAAAAAAAAAAAA/QsCACAGQayTAWr9DAAAAAAAAAAAAAAAAAAAAAD9CwIAIAZBvJMBav0MAAAAAAAAAAAAAAAAAAAAAP0LAgAgBkG0kgFq/QwAAAAAAAAAAAAAAAAAAAAA/QsCAEHxKiEEIAZBzJMBaiIAQfEqNgIAQQEhAwNAIAAgA0ECdGogBEEediAEc0Hlkp7gBmwgA2oiBDYCACAAIANBAWoiBUECdGogBEEediAEc0Hlkp7gBmwgBWoiBDYCACAAIANBAmoiBUECdGogBEEediAEc0Hlkp7gBmwgBWoiBDYCACADQQNqIgVB8ARHBEAgACAFQQJ0aiAEQR52IARzQeWSnuAGbCAFaiIENgIAIANBBGohAwwBCwsgBv0MAAAAAAAAAAAAAAAAAAAAAP0LA6inASAG/QwAAAAAAAAAAAAAAAAAAAAA/QsCvKcBIAb9DAAAAAAAAAAAAAAAAAAAAAD9CwPQpwEgBkGMpwFqQgA3AgAgBkGUpwFq/QwAAAAAAAAAAAAAAAAAAAAA/QsCACAGQeSnAWpBAEHkAPwLACAG/QwAAAAAAAAAAAAAAAAAAAAA/QsCzKgBIAEgBjYCyBQgBhDlBDYCkKcBAkACQCAKKAI4IApBQGsiACgCACAGQcwAaiAKKAKEAiAKKAIUIAooAjRBA2wQ4wRFBEAgAUGjHzYCcEECQfjnACABQfAAahA0IAYQ8wIQL0EAIQMMAQsgBigCZBBfIQQgBigCaBBfIQUgAUGjHzYCYCABIAQgBWq4RAAAAACAhC5BozkDaEEEQbDvACABQeAAahA0IAooAjggACgCACAGQfQAaiAKKAKEAiAKKAIUIAooAiQQ4wRFBEAgAUGjHzYCUEECQcLnACABQdAAahA0IAYQ8wIQL0EAIQMMAQsgBigCjAEQXyEAIAYoApABEF8hBCABQaMfNgJAIAEgACAEarhEAAAAAICELkGjOQNIQQRBwu4AIAFBQGsQNAJAIAooAjQiACAKKALAAWwiBCAGQYyoAWooAgAgBigChKgBIgdrQQJ1TQ0AIARBgICAgARPDQIgBkGIqAFqKAIAIQMgBEECdCIEEDEiAiAEaiEIIAIgAyAHayILQXxxaiIFIQQCQCADIAdGDQACQCALQQRrIgRBLEkEQCAFIQQMAQsgAyALQXxxIAJqa0EQSQRAIAUhBAwBCyAFQRBrIQsgA0EQayEOIAMgBEECdkEBaiIPQfz///8HcSICQQJ0IgRrIQMgBSAEayEEA0AgCyANQQJ0IglrIA4gCWv9AAIA/QsCACANQQRqIg0gAkcNAAsgAiAPRg0BCwNAIARBBGsiBCADQQRrIgMqAgA4AgAgAyAHRw0ACwsgBiAINgKMqAEgBiAFNgKIqAEgBiAENgKEqAEgB0UNACAHEC8gCigCNCEACyAAQQJ0IgQQOyEFIAQQOyEHIAQQOyECIARBBGoQOyEEIABBAEoEQEEAIQMDQCAEIANBAnRqQSAQOzYCACADQQFqIgMgAEcNAAsLIAQgAEECdGpBADYCACAGIAAQOzYCyAEgBiAENgLEASAGIAI2AsABIAYgBzYCvAEgBiAFNgK4ASAGQQA2ArQBAkAgBigC2AEgBigC0AEiBGtBMG0gAE8NACAAQdaq1SpPDQIgBigC1AEhAyAAQTBsIgAQMSIFIABqIQcgBSADIARrQTBtQTBsaiIFIQAgAyAERwRAA0AgAEEwayIAIANBMGsiA/0AAwD9CwMAIAAgA/0AAyD9CwMgIAAgA/0AAxD9CwMQIAMgBEcNAAsLIAYgBzYC2AEgBiAFNgLUASAGIAA2AtABIARFDQAgBBAvCwJAIAooAsABIg0gBigCvAIgBigCtAIiB2tBAnVNDQAgDUGAgICABE8NAiAGKAK4AiEDIA1BAnQiABAxIgUgAGohCyAFIAMgB2siAkF8cWoiBCEAAkAgAyAHRg0AAkAgAkEEayIAQSxJBEAgBCEADAELIAMgAkF8cSAFamtBEEkEQCAEIQAMAQsgBEEQayEIIANBEGshDiADIABBAnZBAWoiD0H8////B3EiAkECdCIAayEDIAQgAGshAEEAIQUDQCAIIAVBAnQiCWsgDiAJa/0AAgD9CwIAIAVBBGoiBSACRw0ACyACIA9GDQELA0AgAEEEayIAIANBBGsiAyoCADgCACADIAdHDQALCyAGIAs2ArwCIAYgBDYCuAIgBiAANgK0AiAHRQ0AIAcQLyAKKALAASENCwJAIAYoAsgCIAYoAsACIgdrQQJ1IA1PDQAgDUGAgICABE8NAiAGKALEAiEDIA1BAnQiABAxIgUgAGohCyAFIAMgB2siAkF8cWoiBCEAAkAgAyAHRg0AAkAgAkEEayIAQSxJBEAgBCEADAELIAMgAkF8cSAFamtBEEkEQCAEIQAMAQsgBEEQayEIIANBEGshDiADIABBAnZBAWoiD0H8////B3EiAkECdCIAayEDIAQgAGshAEEAIQUDQCAIIAVBAnQiCWsgDiAJa/0AAgD9CwIAIAVBBGoiBSACRw0ACyACIA9GDQELA0AgAEEEayIAIANBBGsiAyoCADgCACADIAdHDQALCyAGIAs2AsgCIAYgBDYCxAIgBiAANgLAAiAHRQ0AIAcQLyAKKALAASENCwJAIAYoAtQCIAYoAswCIgdrQQJ1IA1PDQAgDUGAgICABE8NAiAGKALQAiEDIA1BAnQiABAxIgUgAGohDSAFIAMgB2siAkF8cWoiBCEAAkAgAyAHRg0AAkAgAkEEayIAQSxJBEAgBCEADAELIAMgAkF8cSAFamtBEEkEQCAEIQAMAQsgBEEQayELIANBEGshCCADIABBAnZBAWoiDkH8////B3EiAkECdCIAayEDIAQgAGshAEEAIQUDQCALIAVBAnQiD2sgCCAPa/0AAgD9CwIAIAVBBGoiBSACRw0ACyACIA5GDQELA0AgAEEEayIAIANBBGsiAyoCADgCACADIAdHDQALCyAGIA02AtQCIAYgBDYC0AIgBiAANgLMAiAHRQ0AIAcQLwsCQCAKKAIgIgAgBigC4AIgBigC2AIiBGtBBHVNDQAgAEGAgICAAU8NAiAGKALcAiEDIABBBHQiABAxIgUgAGohByAFIAMgBGtqIgUhACADIARHBEADQCAAQRBrIgAgA0EQayIDKQMANwMAIAAgAygCCDYCCCADIARHDQALCyAGIAc2AuACIAYgBTYC3AIgBiAANgLYAiAERQ0AIAQQLwtBACEAIAFBADYCgAFBASEDA0AgAUGAAWoiBCADQQJ0aiAAQR52IABzQeWSnuAGbCADaiIANgIAIANBAWoiBUECdCAEaiAAQR52IABzQeWSnuAGbCAFaiIANgIAIANBAmoiBUECdCAEaiAAQR52IABzQeWSnuAGbCAFaiIANgIAIANBA2oiBUHwBEcEQCAFQQJ0IARqIABBHnYgAHNB5ZKe4AZsIAVqIgA2AgAgA0EEaiEDDAELCyABQQA2AsAUIAZB5AJqIAFBgAFqIgBBxBP8CgAAIAooAoQCIQQgASABQcgUajYCiAEgAUHUtAE2AoABIAEgADYCkAEgASABQcwUajYChAEgBkGUpwFqIAQgABCQAgJAAn8gACABKAKQASIDRgRAIAAhAyABKAKAAUEQagwBCyADRQ0BIAMoAgBBFGoLIQAgAyAAKAIAEQAACyABKALIFCIAQZinAWooAgAhBCAAQZynAWooAgAhBSAAKAKUpwEoAgAoApQQIQAgAUGjHzYCMCABIAAgBSAEa2q4RAAAAACAhC5BozkDOEEEQfbvACABQTBqEDQgASgCzBQoAoQCIQQgASgCyBQhIyABIAFByBRqNgKIASABQcS2ATYCgAEgASABQYABaiIANgKQASABIAFBzBRqNgKEASAjQainAWogBCAAEJACAkACfyAAIAEoApABIgNGBEAgACEDIAEoAoABQRBqDAELIANFDQEgAygCAEEUagshACADIAAoAgARAAALIAEoAsgUIgBBrKcBaigCACEEIABBsKcBaigCACEFIAAoAqinASgCACgClBAhACABQaMfNgIgIAEgACAFIARrarhEAAAAAICELkGjOQMoQQRB4O4AIAFBIGoQNCABKALMFCgChAIhBCABKALIFCEkIAEgAUHIFGo2AogBIAFB/LcBNgKAASABIAFBgAFqIgA2ApABIAEgAUHMFGo2AoQBICRBvKcBaiAEIAAQkAICQAJ/IAAgASgCkAEiA0YEQCAAIQMgASgCgAFBEGoMAQsgA0UNASADKAIAQRRqCyEAIAMgACgCABEAAAsgASgCyBQiAEHApwFqKAIAIQQgAEHEpwFqKAIAIQUgACgCvKcBKAIAKAKUECEAIAFBox82AhAgASAAIAUgBGtquEQAAAAAgIQuQaM5AxhBBEHO7wAgAUEQahA0IAEoAswUKAKEAiEEIAEoAsgUISUgASABQcgUajYCiAEgAUG0uQE2AoABIAEgAUGAAWoiADYCkAEgASABQcwUajYChAEgJUHQpwFqIAQgABCQAgJAAn8gACABKAKQASIDRgRAIAAhAyABKAKAAUEQagwBCyADRQ0BIAMoAgBBFGoLIQAgAyAAKAIAEQAACyABKALIFCIAQdSnAWooAgAhBCAAQdinAWooAgAhBSAAKALQpwEoAgAoApQQIQAgAUGjHzYCACABIAAgBSAEa2q4RAAAAACAhC5BozkDCEEEQYjvACABEDQgASgCyBQiAygClKcBIgQEQCABKALMFCgChAIhACAEKAIAKAKUECEEIAMoApSnARCPASADQaSnAWogACAEIAAoAggRBAAiADYCACADIAAQyQE2ApSnASABKALIFCEDCyADKAKopwEiAARAIAEoAswUKAKEAiEEIAAoAgAoApQQIQUgABCPASADQbinAWogBCAFIAQoAggRBAAiADYCACADIAAQyQE2AqinASABKALIFCEDCyADKAK8pwEiAARAIAEoAswUKAKEAiEEIAAoAgAoApQQIQUgABCPASADQcynAWogBCAFIAQoAggRBAAiADYCACADIAAQyQE2ArynASABKALIFCEDCyADKALQpwEiAEUNACABKALMFCgChAIhBCAAKAIAKAKUECEFIAAQjwEgA0HgpwFqIAQgBSAEKAIIEQQAIgA2AgAgAyAAEMkB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AAD9Tv1Q/foB/eYB/QsCMCABIA39DPz////8/////P////z////9DAAAAAAAAAAAAAAAAAAAAAAgFSAO/U79DAAAAAAAAAAAAAAAAAAAAAD9I/2HAf2nAf1SIB0gAv2tAf0MAwAAAAMAAAADAAAAAwAAAP1O/VD9+gH95gH9CwIgIAEgDf0M/P////z////8/////P////0MAAAAAAAAAAAAAAAAAAAAACAWIA79Tv0MAAAAAAAAAAAAAAAAAAAAAP0j/YcB/acB/VIgHiAC/a0B/QwDAAAAAwAAAAMAAAADAAAA/U79UP36Af3mAf0LAhAgASAN/Qz8/////P////z////8/////QwAAAAAAAAAAAAAAAAAAAAAIBcgDv1O/QwAAAAAAAAAAAAAAAAAAAAA/SP9hwH9pwH9UiAfIAL9rQH9DAMAAAADAAAAAwAAAAMAAAD9Tv1Q/foB/eYB/QsCACABICAgCiwAAUEga7KU/RMiDf0M/P////z////8/////P////0MAAAAAAAAAAAAAAAAAAAAACAQIA79Tv0MAAAAAAAAAAAAAAAAAAAAAP0j/YcB/acB/VIgGCAC/a0B/QwDAAAAAwAAAAMAAAADAAAA/U79UP36Af3mAf0LAnAgASAN/Qz8/////P////z////8/////QwAAAAAAAAAAAAAAAAAAAAAIBEgDv1O/QwAAAAAAAAAAAAAAAAAAAAA/SP9hwH9pwH9UiAZIAL9rQH9DAMAAAADAAAAAwAAAAMAAAD9Tv1Q/foB/eYB/QsCYCABIA39DPz////8/////P////z////9DAAAAAAAAAAAAAAAAAAAAAAgEiAO/U79DAAAAAAAAAAAAAAAAAAAAAD9I/2HAf2nAf1SIBogAv2tAf0MAwAAAAMAAAADAAAAAwAAAP1O/VD9+gH95gH9CwJQIAEgDf0M/P////z////8/////P////0MAAAAAAAAAAAAAAAAAAAAACATIA79Tv0MAAAAAAAAAAAAAAAAAAAAAP0j/YcB/acB/VIgGyAC/a0B/QwDAAAAAwAAAAMAAAADAAAA/U79UP36Af3mAf0LAkAgB0EBdCEHIA/9DAIAAAACAAAAAgAAAAIAAAD9rgEhDyABQYABaiEBIAZBAWoiBkEERw0ACyADQSBqIQMgBSEMIA/9GwEhAkEAIQUgDA0A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BSABKAK8AWogAjYCACABKALAASAFakEBNgIAIAEoAsQBIAVqKAIAQQA2AgAgASgCyAEgAmpBADoAACACQQFyIgVBAnQiBiABKAK8AWogBTYCACABKALAASAGakEBNgIAIAEoAsQBIAZqKAIAQQA2AgAgASgCyAEgBWpBADoAACACQQJqIQIgBEECaiIEIAdHDQALCyADQQFxRQ0AIAJBAnQiBCABKAK8AWogAjYCACABKALAASAEakEBNgIAIAEoAsQBIARqKAIAQQA2AgAgASgCyAEgAmpBADoAAAsgAyABKALIAWpBAWtBAToAACAAKAIEKAIAIAAoAggoAgAiACAAQbQBahDaBAsVACABQbS5ATYCACABIAApAgQ3AgQLHQEBf0EMEDEiAUG0uQE2AgAgASAAKQIENwIEIAELBgBBpLkBCxQAIABBBGpBACABKAIEQYi5AUYbCxUAIAAoAgQoAgAgACgCCCgCABDbBAsVACABQfy3ATYCACABIAApAgQ3AgQLHQEBf0EMEDEiAUH8twE2AgAgASAAKQIENwIEIAELBgBB7LcBCxQAIABBBGpBACABKAIEQdC3AUYbCxUAIAAoAgQoAgAgACgCCCgCABDcBAsVACABQcS2ATYCACABIAApAgQ3AgQLHQEBf0EMEDEiAUHEtgE2AgAgASAAKQIENwIEIAELrQICA38BeyACQR9KBEAgAkEgbSEFA0AgASAEQQd0aiIDIAAgBEEibGoiAi8BAEECdEHw1ARq/QkCACIGIAL9XAAC/YcB/acB/foB/eYB/QsCACADIAYgAkEGav1cAAD9hwH9pwH9+gH95gH9CwIQIAMgBiACQQpq/VwAAP2HAf2nAf36Af3mAf0LAiAgAyAGIAJBDmr9XAAA/YcB/acB/foB/eYB/QsCMCADQUBrIAYgAkESav1cAAD9hwH9pwH9+gH95gH9CwIAIAMgBiACQRZq/VwAAP2HAf2nAf36Af3mAf0LAlAgAyAGIAJBGmr9XAAA/YcB/acB/foB/eYB/QsCYCADIAYgAkEeav1cAAD9hwH9pwH9+gH95gH9CwJwIARBAWoiBCAFRw0ACwsLpQEBBX8jAEEQayICJAAgASgCACIDQfD///8HSQRAAkAgA0EKTQRAIAIgAzoADyACQQRqIQQMAQsgA0EPckEBaiIFEDEhBCACIAVBgICAgHhyNgIMIAIgBDYCBCACIAM2AggLIAQgAUEEaiAD/AoAACADIARqQQA6AAAgAkEEaiAAEQEAIQYgAiwAD0EASARAIAIoAgQQLwsgAkEQaiQAIAYPCxBNAAsGAEG0tgELFAAgAEEEakEAIAEoAgRBmLYBRhsLFwAgACgCBCgCACAAKAIIKAIAQQAQ3QQLFQAgAUHUtAE2AgAgASAAKQIENwIECx0BAX9BDBAxIgFB1LQBNgIAIAEgACkCBDcCBCABC58GAgR/BXsgAkEfSgRAIAJBIG0hBgNAIAEgBUEHdGoiA0FAayAAIAVBGGxqIgT9XAAI/YkB/akBIgdBBP2tASAEKAEEIgJBDHb9ESACQQ12/RwBIAJBDnb9HAIgAkEPdv0cAyIK/QwQAAAAEAAAABAAAAAQAAAA/U79UP36ASAELwEAQQJ0QfDUBGr9CQIAIgj95gEgBC8BAkECdEHw1ARq/QkCACIJ/eQB/QsCACADIAkgCCAH/QwPAAAADwAAAA8AAAAPAAAA/U4gAkEEdP0RIAJBA3T9HAEgAkECdP0cAiACQQF0/RwD/QwQAAAAEAAAABAAAAAQAAAA/U79UP36Af3mAf3kAf0LAgAgAyAJIAggBEEMav1cAAD9iQH9qQEiB0EE/a0BIAJBEHb9ESACQRF2/RwBIAJBEnb9HAIgAkETdv0cA/0MEAAAABAAAAAQAAAAEAAAAP1O/VD9+gH95gH95AH9CwJQIAMgCSAIIAf9DA8AAAAPAAAADwAAAA8AAAD9TiACQQR2/REgAkEFdv0cASACQQZ2/RwCIAJBB3b9HAMiB0EE/asB/QwQAAAAEAAAABAAAAAQAAAA/U79UP36Af3mAf3kAf0LAhAgAyAJIAggBEEQav1cAAD9iQH9qQEiC0EE/a0BIAJBFHb9ESACQRV2/RwBIAJBFnb9HAIgAkEXdv0cA/0MEAAAABAAAAAQAAAAEAAAAP1O/VD9+gH95gH95AH9CwJgIAMgCSAIIAv9DA8AAAAPAAAADwAAAA8AAAD9TiAH/QwQAAAAEAAAABAAAAAQAAAA/U79UP36Af3mAf3kAf0LAiAgAyAJIAggBEEUav1cAAD9iQH9qQEiB0EE/a0BIAJBGHb9ESACQRl2/RwBIAJBGnb9HAIgAkEbdv0cA/0MEAAAABAAAAAQAAAAEAAAAP1O/VD9+gH95gH95AH9CwJwIAMgCSAIIAf9DA8AAAAPAAAADwAAAA8AAAD9TiAKQQT9qwH9DBAAAAAQAAAAEAAAABAAAAD9Tv1Q/foB/eYB/eQB/QsCMCAFQQFqIgUgBkcNAAsLC0oBAX8CQCABKAIIIgIgASgCDEYNACACLQAARQ0AIAFBnXg2AgAgASACQQFqNgIIIAEgACgCBDYCKA8LIAFBn3g2AgAgAUEANgIoCyYBAX8gAEHMqAE2AgAgACgCBCIBBEAgASABKAIAKAIEEQAACyAACxwAIAJBnng2AgAgAiAAQQhBBCABG2ooAgA2AigLCgAgAUGgeDYCAAtGAQF/IABBsLIBNgIAIAAoAggiAQRAIAEgASgCACgCBBEAAAsgAEHMqAE2AgAgACgCBCIBBEAgASABKAIAKAIEEQAACyAACxQAIAFBoXg2AgAgASAAKAIENgIoC44HAgR/BHsgAkEfSgRAIAJBIG0hBgNAIAEgBUEHdGoiA0FAayAAIAVBFmxqIgQvAQBBAnRB8NQEav0JAgAiByAEKAECIgJBDHb9ESACQQ12/RwBIAJBDnb9HAIgAkEPdv0cAyIJ/QwQAAAAEAAAABAAAAAQAAAA/U4gBP1cAAb9iQH9qQEiCEEE/a0B/VD9DPD////w////8P////D////9rgH9+gH95gH9CwIAIAMgByACQQR0/REgAkEDdP0cASACQQJ0/RwCIAJBAXT9HAP9DBAAAAAQAAAAEAAAABAAAAD9TiAI/QwPAAAADwAAAA8AAAAPAAAA/U79UP0M8P////D////w////8P////2uAf36Af3mAf0LAgAgAyAHIAJBEHb9ESACQRF2/RwBIAJBEnb9HAIgAkETdv0cA/0MEAAAABAAAAAQAAAAEAAAAP1OIARBCmr9XAAA/YkB/akBIghBBP2tAf1Q/Qzw////8P////D////w/////a4B/foB/eYB/QsCUCADIAcgAkEEdv0RIAJBBXb9HAEgAkEGdv0cAiACQQd2/RwDIgpBBP2rAf0MEAAAABAAAAAQAAAAEAAAAP1OIAj9DA8AAAAPAAAADwAAAA8AAAD9Tv1Q/Qzw////8P////D////w/////a4B/foB/eYB/QsCECADIAcgAkEUdv0RIAJBFXb9HAEgAkEWdv0cAiACQRd2/RwD/QwQAAAAEAAAABAAAAAQAAAA/U4gBEEOav1cAAD9iQH9qQEiCEEE/a0B/VD9DPD////w////8P////D////9rgH9+gH95gH9CwJgIAMgByAK/QwQAAAAEAAAABAAAAAQAAAA/U4gCP0MDwAAAA8AAAAPAAAADwAAAP1O/VD9DPD////w////8P////D////9rgH9+gH95gH9CwIgIAMgByACQRh2/REgAkEZdv0cASACQRp2/RwCIAJBG3b9HAP9DBAAAAAQAAAAEAAAABAAAAD9TiAEQRJq/VwAAP2JAf2pASIIQQT9rQH9UP0M8P////D////w////8P////2uAf36Af3mAf0LAnAgAyAHIAlBBP2rAf0MEAAAABAAAAAQAAAAEAAAAP1OIAj9DA8AAAAPAAAADwAAAA8AAAD9Tv1Q/Qzw////8P////D////w/////a4B/foB/eYB/QsCMCAFQQFqIgUgBkcNAAsLC7ICAQZ/IAJBnng2AgACQCABIAAtACBHBEAgAiAAKAIENgIoIAIoAhwgACgCFEEDdGogAigCCDYCBCAAKAIcIgMgACgCGCIARg0BIABBAWshASACKAIQIQQgAigCDCECIAMgAGtBA3EiBwRAA0AgBCABQQxsaiIGQQA6AAggBiACNgIEIAYgAjYCACABQQFqIQEgBUEBaiIFIAdHDQALCyADIABBf3NqQQNJDQEgA0EFayEDA0AgBCABQQxsaiIAQQA6AAggACACNgIEIAAgAjYCACAAIAI2AgwgACACNgIQIABBADoAFCAAQQA6ACAgACACNgIcIAAgAjYCGCAAQQA6ACwgACACNgIoIAAgAjYCJCABIANGIQggAUEEaiEBIAhFDQALDAELIAIgACgCCDYCKAsL9gUBCH8gASgCHCIEIAAoAhQiBUEDdGohAgJAIAEoAgBBoXhGBEAgAiACKAIAQQFqIgM2AgAgAyAAKAIQIgZJIQIgACgCDCEHAkAgAyAGTw0AIAMgB0kNACAEIAVBA3RqKAIEIAEoAghHIAMgBklxIQILAkAgAkUNACADIAdJDQAgAUGgeDYCAA8LIAFBnng2AgAgAgRAIAEgACgCBDYCKCAEIAVBA3RqIAEoAgg2AgQgACgCHCIDIAAoAhgiBEYNAiAEQQFrIQIgASgCECEFIAEoAgwhASADIARrQQNxIgcEQEEAIQADQCAFIAJB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/YkB/akBIgRBBP2tAf0M+P////j////4////+P////2uAf36Af3mAf0LAgAgAiADIAT9DA8AAAAPAAAADwAAAA8AAAD9Tv0M+P////j////4////+P////2uAf36Af3mAf0LAgAgAiADIAZBBmr9XAAA/YkB/akBIgRBBP2tAf0M+P////j////4////+P////2uAf36Af3mAf0LAlAgAiADIAT9DA8AAAAPAAAADwAAAA8AAAD9Tv0M+P////j////4////+P////2uAf36Af3mAf0LAhAgAiADIAZBCmr9XAAA/YkB/akBIgRBBP2tAf0M+P////j////4////+P////2uAf36Af3mAf0LAmAgAiADIAT9DA8AAAAPAAAADwAAAA8AAAD9Tv0M+P////j////4////+P////2uAf36Af3mAf0LAiAgAiADIAZBDmr9XAAA/YkB/akBIgRBBP2tAf0M+P////j////4////+P////2uAf36Af3mAf0LAnAgAiADIAT9DA8AAAAPAAAADwAAAA8AAAD9Tv0M+P////j////4////+P////2uAf36Af3mAf0LAjAgBUEBaiIFIAdHDQALCwvPAQEEfwJAAkACQCABKAIQIAAoAhRBDGxqQQxrIgMtAAhFDQIgAygCBCADKAIAayIEIAEoAgwgASgCCCICa0oNAiAEQQBMDQFBACECA0AgACgCDCIFIAMoAgAgAmosAAAgBSgCACgCFBEEACAAKAIMIgUgASgCCCACaiwAACAFKAIAKAIUEQQARw0DIAQgAkEBaiICRw0ACwwACyABKAIIIQILIAFBnng2AgAgASACIARqNgIIIAEgACgCBDYCKA8LIAFBn3g2AgAgAUEANgIoC1IBAX8gAEHkrQE2AgAgACgCCCIBQQRqQX/+HgIARQRAIAEgASgCACgCCBEAAAsgAEHMqAE2AgAgACgCBCIBBEAgASABKAIAKAIEEQAACyAAEC8LUAEBfyAAQeStATYCACAAKAIIIgFBBGpBf/4eAgBFBEAgASABKAIAKAIIEQAACyAAQcyoATYCACAAKAIEIgEEQCABIAEoAgAoAgQRAAALIAALTwEBfwJAIAEoAggiAiABKAIMRg0AIAItAAAgAC0ACEcNACABQZ14NgIAIAEgAkEBajYCCCABIAAoAgQ2AigPCyABQZ94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AA8MAQsgA0EEEPMBCyAFQRBqJABBBCEDIAQtAA8EQCAAIAAgACgCAEEMaygCAGooAhgiAyABIAIgAygCACgCIBEDACIBNgIEQQZBACABIAJHGyEDCyAAIAAoAgBBDGsoAgBqIAMQ8wEgBEEQaiQAIAILGQAgACAAKAIAQQxrKAIAai0AEEECcUEBdgspACAAQQhqEPcDRQRAIAAgACgCAEEMaygCAGoiACAAKAIQQQRyELwCCwsQAEGg1jRBpNY0KAIAEPQCCxAAQZTWNEGY1jQoAgAQ9QILBABBAQtoAQN/IwBBIGsiAiQAIAJBDGogASAAKAI4IgAoAgAQ+AIgACgCBCEDIAIoAgwiBCAAKAIISwRAIAAgAyAEEMQBIgM2AgQgACACKAIMNgIICyACIAM2AhAgASACQQxqEPcCIAJBIGokAAsMACABQRhqIAEQ9wILDQAgASgCBBAvIAEQLwuKAQECfyMAQSBrIgIkACAAKAI4IQNB0AAQOyEAIAJBDGogASADKAIAEPgCIAAgAigCHDYCECAAIAL9AAIM/QsCACAAIAEpAzA3A0ggACAB/QADIP0LAzggACAB/QADEP0LAyggACAB/QADAP0LAxggACgCACIBBEAgACABEDs2AgQLIAJBIGokACAACxMAIAIgASgCwAFBACABEF8QlwELEwAgASACKALAAUEAIAEQXxDmBAurAQAjAEEgayIAJAACQAJAIAEQXyADIARqTwRAIAEoAsABIgFFDQEgAiABIANqIAT8CgAAIABBIGokAA8LIABB/dwANgIIIABBnwI2AgQgAEH+JjYCAEGowgIoAgAiAUGl4wAgABAwDAELIABBj94ANgIYIABBoAI2AhQgAEH+JjYCEEGowgIoAgAiAUGl4wAgAEEQahAwCyABEDMaQazCAigCABAzGkEBEAAAC6sBACMAQSBrIgAkAAJAAkAgARBfIAMgBGpPBEAgASgCwAEiAUUNASABIANqIAIgBPwKAAAgAEEgaiQADwsgAEG43AA2AgggAEGWAjYCBCAAQf4mNgIAQajCAigCACIBQaXjACAAEDAMAQsgAEGP3gA2AhggAEGXAjYCFCAAQf4mNgIQQajCAigCACIBQaXjACAAQRBqEDALIAEQMxpBrMICKAIAEDMaQQEQAAALBQBBwAALCQAgACgCGBAvC6IBAQN/IwBBEGsiAiQAIAFBQGsiAxA7IgRFBEAgAkHB3QA2AgggAkGLAjYCBCACQf4mNgIAQajCAigCACIAQaXjACACEDAgABAzGkGswgIoAgAQMxpBARAAAAtBIBA7IgFBOzYCBCABQTw2AgAgASADNgIcIAEgBDYCGCABIAA2AhQgAUHwowEpAgA3AgggAUH4owEoAgA2AhAgAkEQaiQAIAELGAEBfyAAKAI4IgEoAgQQLyABEC8gABAvCwcAIAAoAhgLBQBB9ioLqAYAAkACQAJAQYCYNUEAQQH+SAIADgIAAQILQYAIJAFBgAj9DAAAAAAAAAAAAAAAAAAAAAD9CwAAQZAIQQBBkpMB/AgAAEGimwFBAEEe/AsAQcCbAUEAQQb8CAEAQcabAUEAQR78CwBB5JsBQQBB9QL8CAIAQdmeAUEAQRv8CwBB9J4BQQBBCfwIAwBB/Z4BQQBBG/wLAEGYnwFBAEEJ/AgEAEGhnwFBAEEf/AsAQcCfAUEAQYiTAfwIBQBByLICQQBBHvwLAEHmsgJBAEEC/AgGAEHosgJBAEEd/AsAQYWzAkEAQZ0Q/AgHAEGiwwJBAEEZ/AsAQbvDAkEAQSH8CAgAQdzDAkEAQRn8CwBB9cMCQQBBIfwICQBBlsQCQQBBGfwLAEGvxAJBAEEq/AgKAEHZxAJBAEEZ/AsAQfLEAkEAQQ78CAsAQYDFAkEAQSP8CwBBo8UCQQBBIfwIDABBxMUCQQBBGfwLAEHdxQJBAEG2CvwIDQBBk9ACQQBBLfwLAEHA0AJBAEEC/AgOAEHC0AJBAEEe/AsAQeDQAkEAQcoA/AgPAEGq0QJBAEGKBPwLAEG01QJBAEH5A/wIEABBrdkCQQBBgwT8CwBBsN0CQQBBAvwIEQBBst0CQQBBkgT8CwBBxOECQQBB+QP8CBIAQb3lAkEAQYME/AsAQcDpAkEAQb0G/AgTAEH97wJBAEGHBPwLAEGE9AJBAEHnOPwIFABB66wDQQBBH/wLAEGKrQNBAEH4APwIFQBBgq4DQQBB5AD8CwBB5q4DQQBBvgj8CBYAQai3A0EAQQH8CBcAQam3A0EAQTf8CwBB4LcDQQBB5AD8CBgAQcS4A0EAQTz8CwBBgLkDQQBB2QD8CBkAQdm5A0EAQT/8CwBBmLoDQQBBDPwIGgBBsLoDQQBB0N0x/AsAQYCYNUEC/hcCAEGAmDVBf/4AAgAaDAELQYCYNUEBQn/+AQIAGgv8CQD8CQH8CQL8CQP8CQT8CQX8CQb8CQf8CQj8CQn8CQr8CQv8CQz8CQ38CQ78CQ/8CRD8CRH8CRL8CRP8CRT8CRX8CRb8CRf8CRj8CRn8CRoLC76YAxsBkpMB4pmvAOKZrgDima0A4pmsAOKZqwDimarimarimaoA4pmpAOOAjwDjgI4A44CNAOOAjAB6AGluZmluaXR5AGluc3VmZmljaWVudCBtZW1vcnkARmVicnVhcnkASmFudWFyeQBKdWx5AG1hbGF5AFRodXJzZGF5AFR1ZXNkYXkAV2VkbmVzZGF5AFNhdHVyZGF5AFN1bmRheQBNb25kYXkARnJpZGF5AE1heQAlbS8lZC8leQAhIWt2X3NlbGYuY3R4AHNpeAAlcyBmYWlsZWQgdG8gcmVsZWFzZSBtdXRleAAlcyBmYWlsZWQgdG8gYWNxdWlyZSBtdXRleABjaXJjdW1mbGV4AC0rICAgMFgweAAtMFgrMFggMFgtMHgrMHggMHgAaGVicmV3AGhhdwBOb3YAZW1iZF9jb252AFRodQB0ZWx1Z3UAQXVndXN0ACVzIGZhaWxlZCB0byBicm9hZGNhc3QAdW5zaWduZWQgc2hvcnQAYWxlcnQAd2hpc3Blcl9rdl9jYWNoZV9maW5kX3Nsb3QAcHJpbnQAdW5zaWduZWQgaW50AGNpcmN1bWZsZXgtYWNjZW50AGdyYXZlLWFjY2VudABmdWxsX2RlZmF1bHQAa3ZfY2FjaGVfaW5pdAB4ZGlnaXQALmNyb3NzX2F0dG4ucXVlcnkud2VpZ2h0AC5hdHRuLnF1ZXJ5LndlaWdodAAuY3Jvc3NfYXR0bi5rZXkud2VpZ2h0AC5hdHRuLmtleS53ZWlnaHQALmNyb3NzX2F0dG4ub3V0LndlaWdodAAuYXR0bi5vdXQud2VpZ2h0AGVuY29kZXIubG5fcG9zdC53ZWlnaHQALm1scF9sbi53ZWlnaHQALmNyb3NzX2F0dG5fbG4ud2VpZ2h0AC5hdHRuX2xuLndlaWdodABkZWNvZGVyLmxuLndlaWdodABkZWNvZGVyLnRva2VuX2VtYmVkZGluZy53ZWlnaHQALmNyb3NzX2F0dG4udmFsdWUud2VpZ2h0AC5hdHRuLnZhbHVlLndlaWdodABlbmNvZGVyLmNvbnYyLndlaWdodAAubWxwLjIud2VpZ2h0AGVuY29kZXIuY29udjEud2VpZ2h0AC5tbHAuMC53ZWlnaHQAc2V0AHJpZ2h0LWN1cmx5LWJyYWNrZXQAbGVmdC1jdXJseS1icmFja2V0AHJpZ2h0LXNxdWFyZS1icmFja2V0AGxlZnQtc3F1YXJlLWJyYWNrZXQAcHVuY3QAZ2dtbF9uZXdfb2JqZWN0AE9jdABmbG9hdABTYXQAY29tbWVyY2lhbC1hdAB1aW50NjRfdABoeXBoZW4tbWludXMAcmV2ZXJzZS1zb2xpZHVzAHdoaXNwZXJfZXhwX2NvbXB1dGVfdG9rZW5fbGV2ZWxfdGltZXN0YW1wcwBhZnJpa2FhbnMAcGFyYW1zAGdnbWxfZ2V0X25fdGFza3MAcmlnaHQtcGFyZW50aGVzaXMAbGVmdC1wYXJlbnRoZXNpcwB3aGlzcGVyX3ByaW50X3RpbWluZ3MALmNyb3NzX2F0dG4ucXVlcnkuYmlhcwAuYXR0bi5xdWVyeS5iaWFzAC5jcm9zc19hdHRuLm91dC5iaWFzAC5hdHRuLm91dC5iaWFzAGVuY29kZXIubG5fcG9zdC5iaWFzAC5tbHBfbG4uYmlhcwAuY3Jvc3NfYXR0bl9sbi5iaWFzAC5hdHRuX2xuLmJpYXMAZGVjb2Rlci5sbi5iaWFzAC5jcm9zc19hdHRuLnZhbHVlLmJpYXMALmF0dG4udmFsdWUuYmlhcwBlbmNvZGVyLmNvbnYyLmJpYXMALm1scC4yLmJpYXMAZW5jb2Rlci5jb252MS5iaWFzAC5tbHAuMC5iaWFzACVzAGZvdXIAd2hpc3Blcl9sYW5nX3N0cgBBcHIAY29uc3RydWN0b3IAdmVjdG9yAGNncmFwaC0+bm9kZXNbY2dyYXBoLT5uX25vZGVzIC0gMV0gPT0gdGVuc29yAHVua25vd24gYWxsb2NhdGlvbiBlcnJvcgBiYXNoa2lyAGxvd2VyAHVwcGVyAGtobWVyAGJ1ZmZlcgBPY3RvYmVyAE5vdmVtYmVyAFNlcHRlbWJlcgBEZWNlbWJlcgB0YXRhcgBteWFubWFyAHVuc2lnbmVkIGNoYXIAaW9zX2Jhc2U6OmNsZWFyAE1hcgBxAC9Vc2Vycy9nZ2VyZ2Fub3YvZGV2ZWxvcG1lbnQvZ2l0aHViL3doaXNwZXIuY3BwL3doaXNwZXIuY3BwAGZ1bGwtc3RvcABTZXAAJUk6JU06JVMgJXAAdHdvAGF1dG8AcGFzaHRvAHplcm8AbGFvAHVua25vd24AU3VuAEp1bgBjYXJyaWFnZS1yZXR1cm4AYnJldG9uAHNlbWljb2xvbgBzdGQ6OmV4Y2VwdGlvbgBfX2N4YV9ndWFyZF9hY3F1aXJlIGRldGVjdGVkIHJlY3Vyc2l2ZSBpbml0aWFsaXphdGlvbgBNb24AbGF0aW4AcGVyY2VudC1zaWduAHBsdXMtc2lnbgBlcXVhbHMtc2lnbgBudW1iZXItc2lnbgBkb2xsYXItc2lnbgBsZXNzLXRoYW4tc2lnbgBncmVhdGVyLXRoYW4tc2lnbgBzZXZlbgB0dXJrbWVuAGh5cGhlbgBvY2NpdGFuAHRpYmV0YW4AbmFuAGdlcm1hbgBjcGxhbgBjYXRhbGFuAGxhdHZpYW4AYmVsYXJ1c2lhbgBydXNzaWFuAHBlcnNpYW4AaW5kb25lc2lhbgBodW5nYXJpYW4AYnVsZ2FyaWFuAGJvc25pYW4AbWFjZWRvbmlhbgB1a3JhaW5pYW4Ac2xvdmVuaWFuAGxpdGh1YW5pYW4AbW9uZ29saWFuAGl0YWxpYW4Abm9yd2VnaWFuAHNlcmJpYW4Aa29yZWFuAEphbgBhbG51bQBtZWRpdW0AbWFsYXlhbGFtAEp1bABjbnRybABnZ21sX25ld190ZW5zb3JfaW1wbABib29sAHNtYWxsAHN0ZDo6YmFkX2Z1bmN0aW9uX2NhbGwAQXByaWwAdGFtaWwAZW1zY3JpcHRlbjo6dmFsAG55bm9yc2sAYXN0ZXJpc2sAcXVlc3Rpb24tbWFyawBxdW90YXRpb24tbWFyawBleGNsYW1hdGlvbi1tYXJrAGJsYW5rAHRhamlrAGdyZWVrAHV6YmVrAHNsb3ZhawBqAG1hb3JpAEZyaQBhemVyYmFpamFuaQBzd2FoaWxpAG5lcGFsaQBzb21hbGkAYmVuZ2FsaQBtYXJhdGhpAHNpbmRoaQBoaW5kaQBwdW5qYWJpAGJhZF9hcnJheV9uZXdfbGVuZ3RoAHdlbHNoAGZpbm5pc2gAc3BhbmlzaABkYW5pc2gAcG9saXNoAGVuZ2xpc2gAdHVya2lzaABsdXhlbWJvdXJnaXNoAHN3ZWRpc2gAeWlkZGlzaABiYWNrc2xhc2gAZ3JhcGgAa2F6YWtoAGR1dGNoAE1hcmNoAGZyZW5jaABjemVjaABBdWcAdGFnYWxvZwB1bnNpZ25lZCBsb25nAHRlcm1pbmF0aW5nAHN0ZDo6d3N0cmluZwBiYXNpY19zdHJpbmcAc3RkOjpzdHJpbmcAc3RkOjp1MTZzdHJpbmcAc3RkOjp1MzJzdHJpbmcAZW5jb2Rlci5wb3NpdGlvbmFsX2VtYmVkZGluZwBkZWNvZGVyLnBvc2l0aW9uYWxfZW1iZWRkaW5nAGluZgAlLjBMZgAlTGYAY2dyYXBoLT5uX2xlYWZzIDwgY2dyYXBoLT5zaXplAGNncmFwaC0+bl9ub2RlcyA8IGNncmFwaC0+c2l6ZQB3aGlzcGVyX3Rva2VuaXplAGZpdmUAeXVlAHRydWUAYmFzcXVlAGludmFsaWQgYWxpZ25tZW50IHZhbHVlAFR1ZQB3aGlzcGVyX2luaXRfc3RhdGUAd2hpc3Blcl9pbml0X3dpdGhfcGFyYW1zX25vX3N0YXRlAHdoaXNwZXJfaW5pdF9mcm9tX2ZpbGVfd2l0aF9wYXJhbXNfbm9fc3RhdGUAd2hpc3Blcl9sYW5nX2F1dG9fZGV0ZWN0X3dpdGhfc3RhdGUAd2hpc3Blcl9mdWxsX3dpdGhfc3RhdGUAd2hpc3Blcl9lbmNvZGVfd2l0aF9zdGF0ZQB3aGlzcGVyX2RlY29kZV93aXRoX3N0YXRlAHRyYW5zbGF0ZQBmYWxzZQBwb3J0dWd1ZXNlAG1hbHRlc2UAZmFyb2VzZQBjYW50b25lc2UAY2hpbmVzZQBzdW5kYW5lc2UAdmlldG5hbWVzZQBfX2N4YV9ndWFyZF9yZWxlYXNlAHVuZGVyc2NvcmUAX19jeGFfZ3VhcmRfYWNxdWlyZQBzcmMwLT50eXBlID09IGRzdC0+dHlwZQBkc3QtPnR5cGUgPT0gc3JjMC0+dHlwZQBVbmtub3duIGVycm9yIHR5cGUASnVuZQBvbmUAbmluZQBuZXdsaW5lAGxvdy1saW5lAHZlcnRpY2FsLWxpbmUAaGFpdGlhbiBjcmVvbGUAZG91YmxlAGFwb3N0cm9waGUAbGFyZ2UAdGhyZWUAZnJlZQB0aWxkZQByaWdodC1icmFjZQBsZWZ0LWJyYWNlAGJhY2tzcGFjZQB0cmFuc2NyaWJlAHBlcmlvZABtYXA6OmF0OiAga2V5IG5vdCBmb3VuZABhbXBlcnNhbmQAdm9pZAB3aGlzcGVyX2xhbmdfaWQAdGVybWluYXRlX2hhbmRsZXIgdW5leHBlY3RlZGx5IHJldHVybmVkAHRocmVhZCBjb25zdHJ1Y3RvciBmYWlsZWQAX190aHJlYWRfc3BlY2lmaWNfcHRyIGNvbnN0cnVjdGlvbiBmYWlsZWQAdGhyZWFkOjpqb2luIGZhaWxlZABtdXRleCBsb2NrIGZhaWxlZABmb3JtLWZlZWQAV2VkAHdoaXNwZXJfbW9kZWxfbG9hZAAlMDJkOiUwMmQ6JTAyZCVzJTAzZABsZWFmXyVkAG5vZGVfJWQAZ2dtbF9hbGlnbmVkX21hbGxvYwBnZ21sX3RhbGxvY3JfYWxsb2MAc3RkOjpiYWRfYWxsb2MAZHN0LT5uZVswXSA9PSBuYwBhbWhhcmljAGljZWxhbmRpYwBhcmFiaWMARGVjAC9Vc2Vycy9nZ2VyZ2Fub3YvZGV2ZWxvcG1lbnQvZ2l0aHViL3doaXNwZXIuY3BwL2dnbWwuYwAvVXNlcnMvZ2dlcmdhbm92L2RldmVsb3BtZW50L2dpdGh1Yi93aGlzcGVyLmNwcC9nZ21sLWJhY2tlbmQuYwAvVXNlcnMvZ2dlcmdhbm92L2RldmVsb3BtZW50L2dpdGh1Yi93aGlzcGVyLmNwcC9nZ21sLWFsbG9jLmMAd2IAcmIARmViAHZlcnRpY2FsLXRhYgBuX2xvZ2l0cyA9PSBjdHgudm9jYWIubl92b2NhYgB3K2IAcitiAGErYgByd2EAY3BsYW4tPndvcmtfZGF0YQBoYXVzYQBzaG9uYQBjb21tYQBzaW5oYWxhAGxpbmdhbGEAYWxwaGEAa2FubmFkYQB5b3J1YmEAW19leHRyYV90b2tlbl8AW19UVF8AW19MQU5HXwBbX1NPVF9dAFtfTk9UX10AW19FT1RfXQBbX0JFR19dAFtfVFJBTlNMQVRFX10AW19UUkFOU0NSSUJFX10AYS0+bmVbMl0gPT0gYi0+bmVbMl0AYS0+bmVbMV0gPT0gYi0+bmVbMV0AWgB0ZW5zb3ItPm9wID09IEdHTUxfT1BfVU5BUlkATUFQX1VOQVJZAE1BUF9CSU5BUlkAQ1BZACVhICViICVkICVIOiVNOiVTICVZAFBPU0lYAFNPRlRfTUFYAEFSR01BWABWSUVXAERJVgBDUFUAU1FSVABXSU5fUEFSVABXSU5fVU5QQVJUAGlzX3Bvc2l0aXZlX2NoYXIgfHwgcG9zLT50eXBlID09IFdISVNQRVJfR1JFVFlQRV9DSEFSX05PVAB3dHlwZSAhPSBHR01MX1RZUEVfQ09VTlQAQ09OVABTRVQATVVMX01BVABSRVBFQVQAQ09OQ0FUAEdFVF9ST1dTAFNVTV9ST1dTAENST1NTX0VOVFJPUFlfTE9TUwBHRVRfUkVMX1BPUwBBRERfUkVMX1BPUwBheGlzMyA+PSAwICYmIGF4aXMzIDwgR0dNTF9NQVhfRElNUwBheGlzMiA+PSAwICYmIGF4aXMyIDwgR0dNTF9NQVhfRElNUwBheGlzMSA+PSAwICYmIGF4aXMxIDwgR0dNTF9NQVhfRElNUwBheGlzMCA+PSAwICYmIGF4aXMwIDwgR0dNTF9NQVhfRElNUwAlSDolTTolUwBTUVIAUQBEVVAAQ0xBTVAARElBR19NQVNLX1pFUk8ARkxBU0hfQVRUTgBOQU4ATUVBTgBuZTEgPT0gTgBuZWQxID09IE4AU1VNAFJNU19OT1JNAEdST1VQX05PUk0AUE0AQU0AbmViMTAgPT0gTQBuZWMwMCA9PSBNAE5VTABNVUwASU0yQ09MAHRlbnNvci0+ZGF0YSA9PSBOVUxMAGhhc2hfc2V0LmtleXNbaV0gPT0gTlVMTAB0ZW5zb3IgIT0gTlVMTABjdHgtPm1lbV9idWZmZXIgIT0gTlVMTAB2aWV3LT52aWV3X3NyYyAhPSBOVUxMICYmIHZpZXctPnZpZXdfc3JjLT5kYXRhICE9IE5VTEwAaSAhPSBHR01MX0hBU0hUQUJMRV9GVUxMAExDX0FMTABxOF9LAHE2X0sAcTVfSwBxNF9LAHEzX0sAcTJfSwBTT0ZUX01BWF9CQUNLAFNJTFVfQkFDSwBSRVBFQVRfQkFDSwBHRVRfUk9XU19CQUNLAENST1NTX0VOVFJPUFlfTE9TU19CQUNLAEZMQVNIX0FUVE5fQkFDSwBSTVNfTk9STV9CQUNLAFJPUEVfQkFDSwBKAEFMSUJJAEgATE9HAExBTkcARElBRwBESUFHX01BU0tfSU5GAEZMQVNIX0ZGAFBFUk1VVEUAVFJBTlNQT1NFAFJPUEUAUkVTSEFQRQBOT05FAFVQU0NBTEUAT1VUX1BST0QAREVQUkVDQVRFRABBREQAUE9PTF8yRABDT05WX1RSQU5TUE9TRV8yRABQT09MXzFEAENPTlZfVFJBTlNQT1NFXzFEAG5ldjEgPT0gRABuZWMwMSA9PSBEAG5lazAgPT0gRABuZTAgPT0gRABuZWQwID09IEQAbmVjMTAgPT0gRABuZWIwMCA9PSBEAEFDQwBTVUIAQQBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzxzaG9ydD4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8dW5zaWduZWQgc2hvcnQ+AGVtc2NyaXB0ZW46Om1lbW9yeV92aWV3PGludD4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8dW5zaWduZWQgaW50PgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzxmbG9hdD4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8dWludDhfdD4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8aW50OF90PgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzx1aW50MTZfdD4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8aW50MTZfdD4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8dWludDY0X3Q+AGVtc2NyaXB0ZW46Om1lbW9yeV92aWV3PGludDY0X3Q+AGVtc2NyaXB0ZW46Om1lbW9yeV92aWV3PHVpbnQzMl90PgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzxpbnQzMl90PgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzxjaGFyPgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzx1bnNpZ25lZCBjaGFyPgBzdGQ6OmJhc2ljX3N0cmluZzx1bnNpZ25lZCBjaGFyPgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzxzaWduZWQgY2hhcj4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8bG9uZz4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8dW5zaWduZWQgbG9uZz4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8ZG91YmxlPgA+Pj4APDw8ADAxMjM0NTY3ODkAaTgASEVBUFU4AEMuVVRGLTgAaTE2AGYxNgBkc3QtPnR5cGUgPT0gR0dNTF9UWVBFX0YxNgBzcmMwLT50eXBlID09IEdHTUxfVFlQRV9GMTYAIHYzAGF4aXMyICE9IGF4aXMzAGF4aXMxICE9IGF4aXMzAGF4aXMwICE9IGF4aXMzAG5lMDMgPT0gbmUzAG5iMiA8PSBuYjMATUFQX0NVU1RPTTMAbmUzID09IG5lMTMAbmUwMyA9PSBuZTEzAG5lMyA9PSBuZTAzAGF4aXMxICE9IGF4aXMyAGF4aXMwICE9IGF4aXMyAGdnbWxfbmVsZW1lbnRzKGEpID09IG5lMCpuZTEqbmUyAG5faGVhZCA9PSBuZTIAbmUwMiA9PSBuZTIAbmIxIDw9IG5iMgBuZTIgPT0gbmVhMgBNQVBfQ1VTVE9NMgBpMzIAZjMyAGdnbWxfaXNfbWF0cml4KGEpICYmIGdnbWxfaXNfdmVjdG9yKGIpICYmIGItPnR5cGUgPT0gR0dNTF9UWVBFX0kzMgBkc3QtPnR5cGUgPT0gR0dNTF9UWVBFX0YzMgBzcmMxLT50eXBlID09IEdHTUxfVFlQRV9GMzIATUFQX0NVU1RPTTNfRjMyAE1BUF9DVVNUT00yX0YzMgBNQVBfQ1VTVE9NMV9GMzIAbmUyID09IG5lMTIAbmUwMiA9PSBuZTEyAG5lMiA9PSBuZTAyAGF4aXMwICE9IGF4aXMxAGdnbWxfbmVsZW1lbnRzKGEpID09IG5lMCpuZTEAbmUwMCA9PSBuZTEAbmIwIDw9IG5iMQBuZTEgPT0gbmVhMQBxOF8xAHE1XzEAcTRfMQBNQVBfQ1VTVE9NMQBBREQxAG5lMSA9PSBuZTExAG5lMSA9PSBuZTAxAG5lMCA9PSBuZTAxAHQgPT0gMCB8fCB0ID09IDEAbm9kZS0+c3JjWzFdLT5uZVszXSA9PSAxAG5vZGUtPnNyY1swXS0+bmVbM10gPT0gMQBub2RlLT5zcmNbMV0tPm5lWzJdID09IDEAbmVjMTEgPT0gMQBuZWIxMSA9PSAxAG5lMDEgPT0gMQBuZTAgPT0gMQBnZ21sX2JsY2tfc2l6ZShyZXN1bHRfdHlwZSkgPT0gMQBrMCA9PSBzMABuZTAwID09IG5lMABuX2RpbXMgPD0gbmUwAG5lMCA9PSBuZWEwAHE4XzAAcTVfMABxNF8wAG5lMSA9PSBuZTEwAG5lMCA9PSBuZTAwAGNwbGFuLT5uX3RocmVhZHMgPiAwAG5fcGFzdCA+PSAwAFAgPj0gMABwYXJhbXMtPml0aCA9PSAwAHJjID09IDAAKCh1aW50cHRyX3QpIChtZW1fYnVmZmVyICsgb2JqX25ldy0+b2ZmcykpJUdHTUxfTUVNX0FMSUdOID09IDAAKCh1aW50cHRyX3QpIChjdHgtPm1lbV9idWZmZXIpKSVHR01MX01FTV9BTElHTiA9PSAwAG5fZGltcyAlIDIgPT0gMABwMCA9PSAwAFRoZSBleHByZXNzaW9uIGNvbnRhaW5lZCBtaXNtYXRjaGVkIHsgYW5kIH0uAGVuY29kZXIuYmxvY2tzLgBkZWNvZGVyLmJsb2Nrcy4AVGhlIGV4cHJlc3Npb24gY29udGFpbmVkIGFuIGludmFsaWQgY2hhcmFjdGVyIHJhbmdlLCBzdWNoIGFzIFtiLWFdIGluIG1vc3QgZW5jb2RpbmdzLgBBbiBlbXB0eSByZWdleCBpcyBub3QgYWxsb3dlZCBpbiB0aGUgUE9TSVggZ3JhbW1hci4AVGhlIGV4cHJlc3Npb24gY29udGFpbmVkIGFuIGludmFsaWQgcmFuZ2UgaW4gYSB7fSBleHByZXNzaW9uLgBUaGUgcGFyc2VyIGRpZCBub3QgY29uc3VtZSB0aGUgZW50aXJlIHJlZ3VsYXIgZXhwcmVzc2lvbi4AT25lIG9mICo/K3sgd2FzIG5vdCBwcmVjZWRlZCBieSBhIHZhbGlkIHJlZ3VsYXIgZXhwcmVzc2lvbi4AVGhlIGNvbXBsZXhpdHkgb2YgYW4gYXR0ZW1wdGVkIG1hdGNoIGFnYWluc3QgYSByZWd1bGFyIGV4cHJlc3Npb24gZXhjZWVkZWQgYSBwcmUtc2V0IGxldmVsLgBUaGUgZXhwcmVzc2lvbiBjb250YWluZWQgYW4gaW52YWxpZCBlc2NhcGVkIGNoYXJhY3Rlciwgb3IgYSB0cmFpbGluZyBlc2NhcGUuAFRoZXJlIHdhcyBpbnN1ZmZpY2llbnQgbWVtb3J5IHRvIGNvbnZlcnQgdGhlIGV4cHJlc3Npb24gaW50byBhIGZpbml0ZSBzdGF0ZSBtYWNoaW5lLgBUaGUgZXhwcmVzc2lvbiBjb250YWluZWQgYW4gaW52YWxpZCBjb2xsYXRpbmcgZWxlbWVudCBuYW1lLgBUaGUgZXhwcmVzc2lvbiBjb250YWluZWQgYW4gaW52YWxpZCBjaGFyYWN0ZXIgY2xhc3MgbmFtZS4AVGhlcmUgd2FzIGluc3VmZmljaWVudCBtZW1vcnkgdG8gZGV0ZXJtaW5lIHdoZXRoZXIgdGhlIHJlZ3VsYXIgZXhwcmVzc2lvbiBjb3VsZCBtYXRjaCB0aGUgc3BlY2lmaWVkIGNoYXJhY3RlciBzZXF1ZW5jZS4AVGhlIGV4cHJlc3Npb24gY29udGFpbmVkIGFuIGludmFsaWQgYmFjayByZWZlcmVuY2UuAEFuIGludmFsaWQgcmVnZXggZ3JhbW1hciBoYXMgYmVlbiByZXF1ZXN0ZWQuAFRoZSBleHByZXNzaW9uIGNvbnRhaW5lZCBtaXNtYXRjaGVkIFsgYW5kIF0uAFRoZSBleHByZXNzaW9uIGNvbnRhaW5lZCBtaXNtYXRjaGVkICggYW5kICkuAC0tLQB3KwAnc3wndHwncmV8J3ZlfCdtfCdsbHwnZHwgP1tbOmFscGhhOl1dK3wgP1tbOmRpZ2l0Ol1dK3wgP1teXHNbOmFscGhhOl1bOmRpZ2l0Ol1dK3xccysoPyFcUyl8XHMrAHIrAGErACVzIChjb3B5KQAlcyAodmlldykAZ2dtbF9iYWNrZW5kX2lzX2NwdShiYWNrZW5kX2NwdSkAZ2dtbF9pc19jb250aWd1b3VzKGRzdCkAb2Zmc2V0ICsgaW0wKm5iMCArIGltMSpuYjEgKyBpbTIqbmIyICsgaW0zKm5iMyA8PSBnZ21sX25ieXRlcyhkc3QpAG9mZnNldCArIChuZTEwID09IDAgPyAwIDogbmUxMC0xKSpuYjAgKyAobmUxMSA9PSAwID8gMCA6IG5lMTEtMSkqbmIxICsgKG5lMTIgPT0gMCA/IDAgOiBuZTEyLTEpKm5iMiArIChuZTEzID09IDAgPyAwIDogbmUxMy0xKSpuYjMgPCBnZ21sX25ieXRlcyhkc3QpAGdnbWxfaXNfc2NhbGFyKGRzdCkAZ2dtbF9pc19jb250aWd1b3VzX2V4Y2VwdF9kaW1fMShkc3QpAGdnbWxfYXJlX3NhbWVfc2hhcGUoc3JjMSwgZHN0KQBnZ21sX2Nhbl9yZXBlYXQoc3JjMCwgZHN0KQBnZ21sX2FyZV9zYW1lX3NoYXBlKHNyYzAsIHNyYzEpICYmIGdnbWxfYXJlX3NhbWVfc2hhcGUoc3JjMCwgZHN0KQBnZ21sX2Nhbl9yZXBlYXRfcm93cyhzcmMxLCBzcmMwKSAmJiBnZ21sX2FyZV9zYW1lX3NoYXBlKHNyYzAsIGRzdCkAJXMgKGNvbnQpAGRzdC0+bmJbMF0gPT0gc2l6ZW9mKGZsb2F0KQBzcmMwLT5uYlswXSA9PSBzaXplb2YoZmxvYXQpAG5idjAgPT0gc2l6ZW9mKGZsb2F0KQBuYnEwID09IHNpemVvZihmbG9hdCkAbmJrMCA9PSBzaXplb2YoZmxvYXQpAG5iMCA9PSBzaXplb2YoZmxvYXQpAG5iYzEwID09IHNpemVvZihmbG9hdCkAbmIxMCA9PSBzaXplb2YoZmxvYXQpAG5iYjEwID09IHNpemVvZihmbG9hdCkAbmIwMCA9PSBzaXplb2YoZmxvYXQpAHNyYzAtPm5iWzBdID09IHNpemVvZihnZ21sX2ZwMTZfdCkAbmJ2MCA9PSBzaXplb2YoZ2dtbF9mcDE2X3QpAG5icTAgPT0gc2l6ZW9mKGdnbWxfZnAxNl90KQBuYmswID09IHNpemVvZihnZ21sX2ZwMTZfdCkAbmIwID09IHNpemVvZihnZ21sX2ZwMTZfdCkAbmJhMCA9PSBzaXplb2YoZ2dtbF9mcDE2X3QpAG5iYzAwID09IHNpemVvZihnZ21sX2ZwMTZfdCkAbmIwMCA9PSBzaXplb2YoZ2dtbF9mcDE2X3QpAG5iYjAwID09IHNpemVvZihnZ21sX2ZwMTZfdCkAJXMgKGNvcHkgb2YgJXMpACFnZ21sX2lzX3ZpZXcodGVuc29yKQAobnVsbCkAbmIxMCA9PSBnZ21sX3R5cGVfc2l6ZShzcmMxLT50eXBlKQBnZ21sX2lzX3F1YW50aXplZChzcmMwLT50eXBlKQBuYjAwID09IGdnbWxfdHlwZV9zaXplKHR5cGUpACVzIChwZXJtdXRlZCkAJXMgKHRyYW5zcG9zZWQpACVzIChyZXNoYXBlZCkAZ2dtbF9pc19jb250aWd1b3VzX2V4Y2VwdF9kaW1fMShncmFkKQBnZ21sX2FyZV9zYW1lX3NoYXBlKHNyYzAsIGdyYWQpAHZpZXdfc3JjID09IE5VTEwgfHwgZGF0YV9zaXplICsgdmlld19vZmZzIDw9IGdnbWxfbmJ5dGVzKHZpZXdfc3JjKQBwYXJhbXMtPndzaXplID49IHNpemVvZihmbG9hdCkgKiAobnRoICsgbnRoICogbmMpAGdnbWxfbmVsZW1lbnRzKGEpID09IGdnbWxfbmVsZW1lbnRzKGIpAGdnbWxfaXNfc2NhbGFyKGIpAGdnbWxfY2FuX211bF9tYXQoYSwgYikAZ2dtbF9hcmVfc2FtZV9zaGFwZShhLCBiKQBnZ21sX2lzX2NvbnRpZ3VvdXMoYSkAIWdnbWxfaXNfdHJhbnNwb3NlZChhKQBnZ21sX2lzX3BhZGRlZF8xZChhKQBnZ21sX2Nhbl9yZXBlYXRfcm93cyhiLCBhKQBnZ21sX2lzX2NvbnRpZ3VvdXMoc3JjMSkAZ2dtbF9pc19zY2FsYXIoc3JjMSkAZ2dtbF9hcmVfc2FtZV9zaGFwZShzcmMwLCBkc3QpICYmIGdnbWxfYXJlX3NhbWVfc2hhcGUoc3JjMCwgc3JjMSkAZ2dtbF9pc19jb250aWd1b3VzKG9wdDApAGdnbWxfaXNfY29udGlndW91cyhkc3QpICYmIGdnbWxfaXNfY29udGlndW91cyhzcmMwKQBnZ21sX25lbGVtZW50cyhkc3QpID09IGdnbWxfbmVsZW1lbnRzKHNyYzApAG9mZnNldCArIChuZTEwID09IDAgPyAwIDogbmUxMC0xKSpuYjAwICsgKG5lMTEgPT0gMCA/IDAgOiBuZTExLTEpKm5iMDEgKyAobmUxMiA9PSAwID8gMCA6IG5lMTItMSkqbmIwMiArIChuZTEzID09IDAgPyAwIDogbmUxMy0xKSpuYjAzIDwgZ2dtbF9uYnl0ZXMoc3JjMCkAZ2dtbF9pc19jb250aWd1b3VzX2V4Y2VwdF9kaW1fMShzcmMwKQBnZ21sX2Nhbl9yZXBlYXQoZHN0LCBzcmMwKQApKSkAb3BlcmF0b3IoKQAoKCgAc3JjMS0+dHlwZSA9PSBHR01MX1RZUEVfRjMyICYmICJvbmx5IGYzMiBzcmMxIHN1cHBvcnRlZCBmb3Igbm93IgBiYWNrZW5kICE9IE5VTEwgJiYgInRlbnNvciBiYWNrZW5kIG5vdCBzZXQiAGFsbG9jLT5uX2ZyZWVfYmxvY2tzIDwgTUFYX0ZSRUVfQkxPQ0tTICYmICJvdXQgb2YgZnJlZSBibG9ja3MiAG9mZnNldCArIHNpemUgPD0gZ2dtbF9uYnl0ZXModGVuc29yKSAmJiAidGVuc29yIHdyaXRlIG91dCBvZiBib3VuZHMiAG9mZnNldCArIHNpemUgPD0gZ2dtbF9uYnl0ZXModGVuc29yKSAmJiAidGVuc29yIHJlYWQgb3V0IG9mIGJvdW5kcyIAZGF0YSAhPSBOVUxMICYmICJmYWlsZWQgdG8gYWxsb2NhdGUgYnVmZmVyIgAhIm5vdCBlbm91Z2ggc3BhY2UgaW4gdGhlIGJ1ZmZlciIAdGVuc29yLT5kYXRhICE9IE5VTEwgJiYgInRlbnNvciBub3QgYWxsb2NhdGVkIgBiYXNlICE9IE5VTEwgJiYgImJhY2tlbmQgYnVmZmVyIGJhc2UgY2Fubm90IGJlIE5VTEwiAFB1cmUgdmlydHVhbCBmdW5jdGlvbiBjYWxsZWQhAFdBUk5JTkc6IEJlaGF2aW9yIG1heSBiZSB1bmV4cGVjdGVkIHdoZW4gYWxsb2NhdGluZyAwIGJ5dGVzIGZvciBnZ21sX2FsaWduZWRfbWFsbG9jIQAgfCAAQVZYID0gAFZTWCA9IABCTEFTID0gAE9QRU5WSU5PID0gAE5FT04gPSAAQ09SRU1MID0gAE1FVEFMID0gAFdBU01fU0lNRCA9IABGMTZDID0gAEZQMTZfVkEgPSAAQVJNX0ZNQSA9IABDVURBID0gAFNTU0UzID0gAEFWWDIgPSAAQVZYNTEyID0gACVzOiB0ZW5zb3IgJyVzJyBoYXMgd3Jvbmcgc2l6ZSBpbiBtb2RlbCBmaWxlOiBnb3QgJXp1LCBleHBlY3RlZCAlenUKACVzOiB1c2luZyBkaXN0aWxsZWQgbW9kZWwgLSBmb3JjaW5nIG5vX3RpbWVzdGFtcHMKACVzOiBhZGRpbmcgJWQgZXh0cmEgdG9rZW5zCgAlczogICAgICBtZWwgdGltZSA9ICU4LjJmIG1zCgAlczogICAgdG90YWwgdGltZSA9ICU4LjJmIG1zCgAlczogICAgIGxvYWQgdGltZSA9ICU4LjJmIG1zCgBzeXN0ZW1faW5mbzogbl90aHJlYWRzID0gJWQgLyAlZCB8ICVzCgBXSElTUEVSX0FTU0VSVDogJXM6JWQ6ICVzCgBHR01MX0FTU0VSVDogJXM6JWQ6ICVzCgBbJXMgLS0+ICVzXSAgJXMKACVzOiBvZmZzZXQgJWRtcyBpcyBiZWZvcmUgdGhlIHN0YXJ0IG9mIHRoZSBhdWRpbwoAdW5rbm93biB0b2tlbgoAJXM6IGZhaWxlZCB0byBjb21wdXRlIGxvZyBtZWwgc3BlY3Ryb2dyYW0KACVzOiBsb2FkaW5nIG1vZGVsCgAlczogZmFpbGVkIHRvIGxvYWQgbW9kZWwKACVzOiBmYWlsZWQgdG8gZXZhbAoAJXM6ICAgICBmYWxsYmFja3MgPSAlM2QgcCAvICUzZCBoCgAlczogV0FSTiBubyB0ZW5zb3JzIGxvYWRlZCBmcm9tIG1vZGVsIGZpbGUgLSBhc3N1bWluZyBlbXB0eSBtb2RlbCBmb3IgdGVzdGluZwoAJXM6IGVuY29kZXJfYmVnaW5fY2FsbGJhY2sgcmV0dXJuZWQgZmFsc2UgLSBhYm9ydGluZwoAJXM6IHRlbnNvciAnJXMnIGhhcyB3cm9uZyBzaXplIGluIG1vZGVsIGZpbGUKACVzOiB1bmtub3duIHRlbnNvciAnJXMnIGluIG1vZGVsIGZpbGUKACVzOiBubyBzaWduYWwgZGF0YSBhdmFpbGFibGUKACVzOiBmYWlsZWQgdG8gYWxsb2NhdGUgbWVtb3J5IGZvciBrdiBjYWNoZQoAJXM6IGt2X2NhY2hlX2luaXQoKSBmYWlsZWQgZm9yIGNyb3NzLWF0dGVudGlvbiBjYWNoZQoAJXM6IGt2X2NhY2hlX2luaXQoKSBmYWlsZWQgZm9yIHNlbGYtYXR0ZW50aW9uIGNhY2hlCgAlczogZmFpbGVkIHRvIGF1dG8tZGV0ZWN0IGxhbmd1YWdlCgAlczogZmFpbGVkIHRvIGVuY29kZQoAJXM6IGZhaWxlZCB0byBkZWNvZGUKACVzOiBvcCAlcyBub3QgaW1wbGVtZW50ZWQKACVzOiBnZ21sX2luaXQoKSBmYWlsZWQKACVzOiBuX3Rva2Vucz0lZCA+IG5fY3R4PSVkCgAlczogRVJS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EBAAEAAQEAAQAAAQABAQABAQEAAAEBAAEAAQAAAQEAAQEAAAABAQABAAAAAAEBAAEBAQEBAAEAAQABAQEAAQABAQABAQABAAEAAAEBAAEAAQEBAAEAAQABAAEAAQABAAEBAAABAAEAAQAAAAEAAQABAQEBAAABAAEAAQEAAAEAAQEAAQAAAQABAAABAAABAAEBAQAAAAEAAQABAAAAAQABAQAAAAABAAEAAAAAAAEAAQEBAQEBAAABAAEBAQEAAAEBAAEBAQAAAQAAAQEBAAABAQEAAQEAAAEAAQABAQAAAQEAAAEBAAABAAAAAQEAAAEBAQEAAQAAAQABAQABAAABAQABAAEAAAEAAAEAAQAAAQEBAAABAAABAAEAAAEAAAEBAAAAAQAAAQAAAAABAAABAQEBAQAAAAEAAQEBAAAAAQEAAQEAAAABAAABAQAAAAEBAQABAAAAAQABAAEAAAABAQAAAQAAAAEAAAABAAAAAQEBAQAAAAABAAEBAAAAAAEBAAEAAAAAAQAAAQAAAAABAQEAAAAAAAEAAQAAAAAAAQEAAAAAAAABAAAAAAAAAAEBAQEBAQEBAAABAQEBAQEAAQABAQEBAQAAAAEBAQEBAAEBAAEBAQEAAAEAAQEBAQABAAABAQEBAAAAAAEBAQEAAQEBAAEBAQAAAQEAAQEBAAEAAQABAQEAAAABAAEBAQABAQAAAQEBAAABAAABAQEAAQAAAAEBAQAAAAAAAQEBAAEBAQEAAQEAAAEBAQABAQABAAEBAAEBAAAAAQEAAQEAAQEAAQABAQAAAQABAAEBAAEAAAEAAQEAAAAAAQABAQABAQEAAAEBAAABAQAAAQEAAQABAAABAQAAAAEAAAEBAAEBAAAAAQEAAAEAAAABAQABAAAAAAEBAAAAAAAAAQEAAQEBAQEAAQAAAQEBAQABAAEAAQEBAAEAAAABAQEAAQABAQABAQABAAABAAEBAAEAAQAAAQEAAQAAAAABAQABAAEBAQABAAEAAAEBAAEAAQABAAEAAQABAAAAAQABAAEAAQEAAAEAAQAAAQAAAQABAAEAAAABAAEAAAAAAAEAAQABAQEBAAABAAABAQEAAAEAAQABAQAAAQAAAAEBAAABAAEBAAEAAAEAAAEAAQAAAQABAAABAAABAAAAAAEAAAEAAQEBAAAAAQAAAQEAAAABAAEAAQAAAAEAAAABAAAAAQABAQAAAAABAAABAAAAAAEAAQAAAAAAAQAAAAAAAAABAAEBAQEBAQAAAAEBAQEBAAABAAEBAQEAAAAAAQEBAQAAAQEAAQEBAAAAAQABAQEAAAEAAAEBAQAAAAAAAQEBAAABAQEAAQEAAAABAQABAQAAAQABAAEBAAAAAAEAAQEAAAEBAAABAQAAAAEAAAEBAAABAAAAAQEAAAAAAAABAQAAAQEBAQABAAAAAQEBAAEAAAEAAQEAAQAAAAABAQABAAABAQABAAEAAAABAAEAAQAAAQAAAQABAAAAAAABAAEAAAEBAQAAAQAAAAEBAAABAAABAAEAAAEAAAAAAQAAAQAAAQEAAAABAAAAAQAAAAEAAAEAAAAAAQAAAAAAAAABAAABAQEBAQAAAAABAQEBAAAAAQABAQEAAAAAAAEBAQAAAAEBAAEBAAAAAAEAAQEAAAABAAABAQAAAAAAAAEBAAAAAQEBAAEAAAAAAQEAAQAAAAEAAQABAAAAAAABAAEAAAABAQAAAQAAAAABAAABAAAAAQAAAAEAAAAAAAAAAQAAAAEBAQEAAAAAAAEBAQAAAAABAAEBAAAAAAAAAQEAAAAAAQEAAQAAAAAAAQABAAAAAAEAAAEAAAAAAAAAAQAAAAABAQEAAAAAAAABAQAAAAAAAQABAAAAAAAAAAEAAAAAAAEBAAAAAAAAAAEAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAABAAAAAAAAAQEAAAAAAAAAAAEAAAAAAAEAAQAAAAAAAAEBAAAAAAABAQEAAAAAAAAAAAEAAAAAAQAAAQAAAAAAAQABAAAAAAEBAAEAAAAAAAABAQAAAAABAAEBAAAAAAABAQEAAAAAAQEBAQAAAAAAAAAAAQAAAAEAAAABAAAAAAEAAAEAAAABAQAAAQAAAAAAAQABAAAAAQABAAEAAAAAAQEAAQAAAAEBAQABAAAAAAAAAQEAAAABAAABAQAAAAABAAEBAAAAAQEAAQEAAAAAAAEBAQAAAAEAAQEBAAAAAAEBAQEAAAABAQEBAQAAAAAAAAAAAQAAAQAAAAABAAAAAQAAAAEAAAEBAAAAAQAAAAABAAABAAABAAEAAAEAAAABAQAAAQAAAQEBAAABAAAAAAABAAEAAAEAAAEAAQAAAAEAAQABAAABAQABAAEAAAAAAQEAAQAAAQABAQABAAAAAQEBAAEAAAEBAQEAAQAAAAAAAAEBAAABAAAAAQEAAAABAAABAQAAAQEAAAEBAAAAAAEAAQEAAAEAAQABAQAAAAEBAAEBAAABAQEAAQEAAAAAAAEBAQAAAQAAAQEBAAAAAQABAQEAAAEBAAEBAQAAAAABAQEBAAABAAEBAQEAAAABAQEBAQAAAQEBAQEBAAAAAAAAAAABAAEAAAAAAAEAAAEAAAAAAQABAQAAAAABAAAAAQAAAAEAAQABAAAAAQAAAQEAAAABAAEBAQAAAAEAAAAAAQAAAQABAAABAAABAAABAAEAAAEAAQEAAQAAAQAAAAEBAAABAAEAAQEAAAEAAAEBAQAAAQABAQEBAAABAAAAAAABAAEAAQAAAAEAAQAAAQAAAQABAAEBAAABAAEAAAABAAEAAQABAAEAAQABAAABAQABAAEAAQEBAAEAAQAAAAABAQABAAEAAAEBAAEAAAEAAQEAAQABAQABAQABAAAAAQEBAAEAAQABAQEAAQAAAQEBAQABAAEBAQEBAAEAAAAAAAABAQABAAAAAAEBAAABAAAAAQEAAQEAAAABAQAAAAEAAAEBAAEAAQAAAQEAAAEBAAABAQABAQEAAAEBAAAAAAEAAQEAAQAAAQABAQAAAQABAAEBAAEBAAEAAQEAAAABAQABAQABAAEBAAEBAAABAQEAAQEAAQEBAQABAQAAAAAAAQEBAAEAAAABAQEAAAEAAAEBAQABAQAAAQEBAAAAAQABAQEAAQABAAEBAQAAAQEAAQEBAAEBAQABAQEAAAAAAQEBAQABAAABAQEBAAABAAEBAQEAAQEAAQEBAQAAAAEBAQEBAAEAAQEBAQEAAAEBAQEBAQABAQEBAQEBAAAAAAAAAAABAQAAAAAAAAEAAQAAAAAAAQEBAAAAAAABAAABAAAAAAEBAAEAAAAAAQABAQAAAAABAQEBAAAAAAEAAAABAAAAAQEAAAEAAAABAAEAAQAAAAEBAQABAAAAAQAAAQEAAAABAQABAQAAAAEAAQEBAAAAAQEBAQEAAAABAAAAAAEAAAEBAAAAAQAAAQABAAABAAABAQEAAAEAAAEAAAEAAQAAAQEAAQABAAABAAEBAAEAAAEBAQEAAQAAAQAAAAEBAAABAQAAAQEAAAEAAQABAQAAAQEBAAEBAAABAAABAQEAAAEBAAEBAQAAAQABAQEBAAABAQEBAQEAAAEAAAAAAAEAAQEAAAAAAQABAAEAAAABAAEBAQAAAAEAAQAAAQAAAQABAQABAAABAAEAAQEAAAEAAQEBAQAAAQABAAAAAQABAAEBAAABAAEAAQABAAEAAQABAQEAAQABAAEAAAEBAAEAAQEAAQEAAQABAAEBAQABAAEBAQEBAAEAAQAAAAABAQABAQAAAAEBAAEAAQAAAQEAAQEBAAABAQABAAABAAEBAAEBAAEAAQEAAQABAQABAQABAQEBAAEBAAEAAAABAQEAAQEAAAEBAQABAAEAAQEBAAEBAQABAQEAAQAAAQEBAQABAQABAQEBAAEAAQEBAQEAAQEBAQEBAQABAAAAAAAAAQEBAAAAAAABAQABAAAAAAEBAQEAAAAAAQEAAAEAAAABAQEAAQAAAAEBAAEBAAAAAQEBAQEAAAABAQAAAAEAAAEBAQAAAQAAAQEAAQABAAABAQEBAAEAAAEBAAABAQAAAQEBAAEBAAABAQABAQEAAAEBAQEBAQAAAQEAAAAAAQABAQEAAAABAAEBAAEAAAEAAQEBAQAAAQABAQAAAQABAAEBAQABAAEAAQEAAQEAAQABAQEBAQABAAEBAAAAAQEAAQEBAAABAQABAQABAAEBAAEBAQEAAQEAAQEAAAEBAQABAQEAAQEBAAEBAAEBAQEAAQEBAQEBAQABAQAAAAAAAQEBAQAAAAABAQEAAQAAAAEBAQEBAAAAAQEBAAABAAABAQEBAAEAAAEBAQABAQAAAQEBAQEBAAABAQEAAAABAAEBAQEAAAEAAQEBAAEAAQABAQEBAQABAAEBAQAAAQEAAQEBAQABAQABAQEAAQEBAAEBAQEBAQEAAQEBAAAAAAEBAQEBAAAAAQEBAQABAAABAQEBAQEAAAEBAQEAAAEAAQEBAQEAAQABAQEBAAEBAAEBAQEBAQEAAQEBAQAAAAEBAQEBAQAAAQEBAQEAAQABAQEBAQEBAAEBAQEBAAABAQEBAQEBAAEBAQEBAQABAQEBAQEBAQEBAQEBAQEJkdAAABAAAABAAAAAAAAAAAAAAAAAAAAAAAAAALAAAAAAAAAGUcAAABAAAAAgAAAAAAAAAMAAAADQAAAA0AAAAOAAAAAQAAAN4fAAAgAAAAEgAAAAEAAAAPAAAAEAAA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AGwAAABbAAAATlN0M19fMjE1X193b3JkX2JvdW5kYXJ5SWNOU18xMnJlZ2V4X3RyYWl0c0ljRUVFRQAAAHjZAAAEVQAALFQAAAAAAACMVQAAbQAAAG4AAABvAAAAWwAAAE5TdDNfXzIxMV9fbG9va2FoZWFkSWNOU18xMnJlZ2V4X3RyYWl0c0ljRUVFRQAAAHjZAABcVQAALFQAAAAAAADYVQAAYQAAAHAAAABxAAAAWwAAAE5TdDNfXzIyM19fbWF0Y2hfYW55X2J1dF9uZXdsaW5lSWNFRQAAAAB42QAAsFUAACxUAAAAAAAANFYAAHIAAABzAAAAdAAAAFsAAABOU3QzX18yMThfX21hdGNoX2NoYXJfaWNhc2VJY05TXzEycmVnZXhfdHJhaXRzSWNFRUVFAAAAAHjZAAD8VQAALFQAAAAAAACQVgAAdQAAAHYAAAB3AAAAWwAAAE5TdDNfXzIyMF9fbWF0Y2hfY2hhcl9jb2xsYXRlSWNOU18xMnJlZ2V4X3RyYWl0c0ljRUVFRQAAeNkAAFhWAAAsVAAAAAAAANBWAABhAAAAeAAAAHkAAABbAAAATlN0M19fMjEyX19tYXRjaF9jaGFySWNFRQAAAHjZAAC0VgAALFQAAAAAAAAoVwAAegAAAHsAAAB8AAAAWwAAAE5TdDNfXzIxNl9fYmFja19yZWZfaWNhc2VJY05TXzEycmVnZXhfdHJhaXRzSWNFRUVFAAB42QAA9FYAACxUAAAAAAAAhFcAAH0AAAB+AAAAfwAAAFsAAABOU3QzX18yMThfX2JhY2tfcmVmX2NvbGxhdGVJY05TXzEycmVnZXhfdHJhaXRzSWNFRUVFAAAAAHjZAABMVwAALFQAAAAAAADAVwAAYQAAAIAAAACBAAAAWwAAAE5TdDNfXzIxMF9fYmFja19yZWZJY0VFAHjZAACoVwAALFQAAAAAAAAcWAAAggAAAIMAAACEAAAAWwAAAE5TdDNfXzIyMF9fYnJhY2tldF9leHByZXNzaW9uSWNOU18xMnJlZ2V4X3RyYWl0c0ljRUVFRQAAeNkAAORXAAAsVAAAAAAAAGxYAABhAAAAhQAAAIYAAABbAAAATlN0M19fMjI4X19iZWdpbl9tYXJrZWRfc3ViZXhwcmVzc2lvbkljRUUAAAB42QAAQFgAACxUAAAAAAAAuFgAAGEAAACHAAAAiAAAAFsAAABOU3QzX18yMjZfX2VuZF9tYXJrZWRfc3ViZXhwcmVzc2lvbkljRUUAeNkAAJBYAAAsVAAAAAAAABxZAACJAAAAigAAAIsAAACMAAAATlN0M19fMjZfX2xvb3BJY0VFAE5TdDNfXzIxN19fb3duc190d29fc3RhdGVzSWNFRQAAAHjZAADvWAAALFQAAHjZAADcWAAAEFkAAAAAAAAQWQAAiQAAAI0AAABlAAAAWwAAAAAAAAB4WQAAWAAAAI4AAACPAAAAWwAAAE5TdDNfXzIxN19fcmVwZWF0X29uZV9sb29wSWNFRQAAeNkAAFhZAAAgVAAAAAAAALhZAACJAAAAkAAAAJEAAACSAAAATlN0M19fMjExX19hbHRlcm5hdGVJY0VFAAAAAHjZAACcWQAAEFkAAAAAAAAAWgAAWAAAAJMAAACUAAAAWwAAAE5TdDNfXzIyMV9fZW1wdHlfbm9uX293bl9zdGF0ZUljRUUAAHjZAADcWQAAIFQAAAAAAABAWgAAYQAAAJUAAACWAAAAWwAAAE5TdDNfXzIxMV9fbWF0Y2hfYW55SWNFRQAAAAB42QAAJFoAACxUAAAAAAAADFsAAJcAAACYAAAAmQAAAJoAAACbAAAAnAAAAJ0AAACeAAAAnwAAAE5TdDNfXzIxMF9fZnVuY3Rpb242X19mdW5jSVoxOHdoaXNwZXJfaW5pdF9zdGF0ZUUzJF8wTlNfOWFsbG9jYXRvcklTMl9FRUZQMTFnZ21sX2NncmFwaHZFRUUATlN0M19fMjEwX19mdW5jdGlvbjZfX2Jhc2VJRlAxMWdnbWxfY2dyYXBodkVFRQAAUNkAANRaAAB42QAAeFoAAARbAABaMTh3aGlzcGVyX2luaXRfc3RhdGVFMyRfMAAAUNkAABhbAAAAAAAAxFsAAJcAAACgAAAAoQAAAKIAAACjAAAApAAAAKUAAACmAAAApwAAAE5TdDNfXzIxMF9fZnVuY3Rpb242X19mdW5jSVoxOHdoaXNwZXJfaW5pdF9zdGF0ZUUzJF8xTlNfOWFsbG9jYXRvcklTMl9FRUZQMTFnZ21sX2NncmFwaHZFRUUAeNkAAGhbAAAEWwAAWjE4d2hpc3Blcl9pbml0X3N0YXRlRTMkXzEAAFDZAADQWwAAAAAAAHxcAACXAAAAqAAAAKkAAACqAAAAqwAAAKwAAACtAAAArgAAAK8AAABOU3QzX18yMTBfX2Z1bmN0aW9uNl9fZnVuY0laMTh3aGlzcGVyX2luaXRfc3RhdGVFMyRfMk5TXzlhbGxvY2F0b3JJUzJfRUVGUDExZ2dtbF9jZ3JhcGh2RUVFAHjZAAAgXAAABFsAAFoxOHdoaXNwZXJfaW5pdF9zdGF0ZUUzJF8yAABQ2QAAiFwAAAAAAAA0XQAAlwAAALAAAACxAAAAsgAAALMAAAC0AAAAtQAAALYAAAC3AAAATlN0M19fMjEwX19mdW5jdGlvbjZfX2Z1bmNJWjE4d2hpc3Blcl9pbml0X3N0YXRlRTMkXzNOU185YWxsb2NhdG9ySVMyX0VFRlAxMWdnbWxfY2dyYXBodkVFRQB42QAA2FwAAARbAABaMTh3aGlzcGVyX2luaXRfc3RhdGVFMyRfMwAAUNkAAEBdAABOU3QzX18yMTJiYXNpY19zdHJpbmdJaE5TXzExY2hhcl90cmFpdHNJaEVFTlNfOWFsbG9jYXRvckloRUVFRQAAUNkAAGRdAABOU3QzX18yMTJiYXNpY19zdHJpbmdJd05TXzExY2hhcl90cmFpdHNJd0VFTlNfOWFsbG9jYXRvckl3RUVFRQAAUNkAAKxdAABOU3QzX18yMTJiYXNpY19zdHJpbmdJRHNOU18xMWNoYXJfdHJhaXRzSURzRUVOU185YWxsb2NhdG9ySURzRUVFRQAAAFDZAAD0XQAATlN0M19fMjEyYmFzaWNfc3RyaW5nSURpTlNfMTFjaGFyX3RyYWl0c0lEaUVFTlNfOWFsbG9jYXRvcklEaUVFRUUAAABQ2QAAQF4AAE4xMGVtc2NyaXB0ZW4xMW1lbW9yeV92aWV3SWNFRQAAUNkAAIxeAABOMTBlbXNjcmlwdGVuMTFtZW1vcnlfdmlld0lhRUUAAFDZAAC0XgAATjEwZW1zY3JpcHRlbjExbWVtb3J5X3ZpZXdJaEVFAABQ2QAA3F4AAE4xMGVtc2NyaXB0ZW4xMW1lbW9yeV92aWV3SXNFRQAAUNkAAARfAABOMTBlbXNjcmlwdGVuMTFtZW1vcnlfdmlld0l0RUUAAFDZAAAsXwAATjEwZW1zY3JpcHRlbjExbWVtb3J5X3ZpZXdJaUVFAABQ2QAAVF8AAE4xMGVtc2NyaXB0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zwAAANAAAABOU3QzX18yMTdiYWRfZnVuY3Rpb25fY2FsbEUAeNkAACSjAAB02gAAAAAAAGikAADSAAAA0wAAANQAAADVAAAA1gAAANcAAADYAAAA2QAAANoAAADbAAAA3AAAAN0AAADeAAAA3wAAAAgAAAAAAAAAoKQAAOAAAADhAAAA+P////j///+gpAAA4gAAAOMAAACYowAArKMAAAAAAACEpQAA5AAAAOUAAADmAAAA5wAAAOgAAADpAAAA6gAAANkAAADaAAAA6wAAANwAAADsAAAA3gAAAO0AAABOU3QzX18yOWJhc2ljX2lvc0ljTlNfMTFjaGFyX3RyYWl0c0ljRUVFRQAAAHjZAAD8owAAtKUAAE5TdDNfXzIxNWJhc2ljX3N0cmVhbWJ1ZkljTlNfMTFjaGFyX3RyYWl0c0ljRUVFRQAAAABQ2QAANKQAAE5TdDNfXzIxM2Jhc2ljX2lzdHJlYW1JY05TXzExY2hhcl90cmFpdHNJY0VFRUUAANTZAABwpAAAAAAAAAEAAAAopAAAA/T//2wAAAAAAAAASKUAAO4AAADvAAAAlP///5T///9IpQAA8AAAAPEAAADEpAAA/KQAABClAADYpAAAbAAAAAAAAACgpAAA4AAAAOEAAACU////lP///6CkAADiAAAA4wAAAE5TdDNfXzIxNGJhc2ljX2lmc3RyZWFtSWNOU18xMWNoYXJfdHJhaXRzSWNFRUVFAHjZAAAYpQAAoKQAAE5TdDNfXzIxM2Jhc2ljX2ZpbGVidWZJY05TXzExY2hhcl90cmFpdHNJY0VFRUUAAHjZAABUpQAAaKQAAAAAAAC0pQAA8gAAAPMAAABOU3QzX18yOGlvc19iYXNlRQAAAFDZAACgpQAAAAAAANF0ngBXnb0qgHBSD///PicKAAAAZAAAAOgDAAAQJwAAoIYBAEBCDwCAlpgAAOH1BRgAAAA1AAAAcQAAAGv////O+///kr///wAAAAAAAAAA/////////////////////////////////////////////////////////////////wABAgMEBQYHCAn/////////CgsMDQ4PEBESExQVFhcYGRobHB0eHyAhIiP///////8KCwwNDg8QERITFBUWFxgZGhscHR4fICEiI/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////8AAQIEBwMGBQAAAAAAAAACAADAAwAAwAQAAMAFAADABgAAwAcAAMAIAADACQAAwAoAAMALAADADAAAwA0AAMAOAADADwAAwBAAAMARAADAEgAAwBMAAMAUAADAFQAAwBYAAMAXAADAGAAAwBkAAMAaAADAGwAAwBwAAMAdAADAHgAAwB8AAMAAAACzAQAAwwIAAMMDAADDBAAAwwUAAMMGAADDBwAAwwgAAMMJAADDCgAAwwsAAMMMAADDDQAA0w4AAMMPAADDAAAMuwEADMMCAAzDAwAMwwQADNsAAAAA3hIElQAAAAD////////////////wpwAAFAAAAEMuVVRGLTgBAgSoAUpMQ19DVFlQRQAAAABMQ19OVU1FUklDAABMQ19USU1FAAAAAABMQ19DT0xMQVRFAABMQ19NT05FVEFSWQBMQ19NRVNTQUdFUwCwqgH5AwEAAAACAAAAAwAAAAQAAAAFAAAABgAAAAcAAAAIAAAACQAAAAoAAAALAAAADAAAAA0AAAAOAAAADwAAABAAAAARAAAAEgAAABMAAAAUAAAAFQAAABYAAAAXAAAAGAAAABkAAAAaAAAAGwAAABwAAAAdAAAAHgAAAB8AAAAgAAAAIQAAACIAAAAjAAAAJAAAACUAAAAmAAAAJwAAACgAAAApAAAAKgAAACsAAAAsAAAALQAAAC4AAAAvAAAAMAAAADEAAAAyAAAAMwAAADQAAAA1AAAANgAAADcAAAA4AAAAOQAAADoAAAA7AAAAPAAAAD0AAAA+AAAAPwAAAEAAAABBAAAAQgAAAEMAAABEAAAARQAAAEYAAABHAAAASAAAAEkAAABKAAAASwAAAEwAAABNAAAATgAAAE8AAABQAAAAUQAAAFIAAABTAAAAVAAAAFUAAABWAAAAVwAAAFgAAABZAAAAWgAAAFsAAABcAAAAXQAAAF4AAABfAAAAYAAAAEEAAABCAAAAQwAAAEQAAABFAAAARgAAAEcAAABIAAAASQAAAEoAAABLAAAATAAAAE0AAABOAAAATwAAAFAA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dDNfXzIxMXJlZ2V4X2Vycm9yRQAAAHjZAAAo1AAAgNsAAFAjAACMIwAAriIAAD4kAACfJAAAzCQAAMcgAACeIQAAFCEAAPsiAAAWIgAAUiIAAMYjAAByJAAAaiEAACkRAADcIQAAAAAAAAoAAABkAAAA6AMAABAnAACghgEAQEIPAICWmAAA4fUFAMqaOwAAAAAAAAAAMDAwMTAyMDMwNDA1MDYwNzA4MDkxMDExMTIxMzE0MTUxNjE3MTgxOTIwMjEyMjIzMjQyNTI2MjcyODI5MzAzMTMyMzMzNDM1MzYzNzM4Mzk0MDQxNDI0MzQ0NDU0NjQ3NDg0OTUwNTE1MjUzNTQ1NTU2NTc1ODU5NjA2MTYyNjM2NDY1NjY2NzY4Njk3MDcxNzI3Mzc0NzU3Njc3Nzg3OTgwODE4MjgzODQ4NTg2ODc4ODg5OTA5MTkyOTM5NDk1OTY5Nzk4OTkAAAAAAAAAAAL/AARkACAAAAT//wYAAQABAAEA//8B/wH//////wH/Af8B/wH/Af8B/wH/Af//////Cv8gAP//A/8B/wT/HgAAAQX//////2MAAAhjAOgDAgAAAP//////AAAAAf8B//////////////8AAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAf8B//////8AASAABACAAAAI//8B/wH/////////Af8G/wf/CP8J//////+8ArwCAQD//wEAAQD//wAA//////////8AAAAAAAAAAAAAAAAAAAAAFAF4//8BAAr///////////8B/wH/AAAAAAAAAf8B/wH/AAAAAAAAAAAAAAAAAAAAAAAAAf8AAAAAAAAB/wH/AQAAAAEAAAAB//////8AAAAAAf///wAAAAD/////////////KAAK//////8BAAr/////AP//////////Ab4IAf8B////AQD//////////////////wr//////wz/Df9OMTBfX2N4eGFiaXYxMTZfX3NoaW1fdHlwZV9pbmZvRQAAeNkAAIbXAACc2wAATjEwX19jeHhhYml2MTE3X19jbGFzc190eXBlX2luZm9FAAAAeNkAALTXAACo1wAATjEwX19jeHhhYml2MTE3X19wYmFzZV90eXBlX2luZm9FAAAAeNkAAOTXAACo1wAATjEwX19jeHhhYml2MTE5X19wb2ludGVyX3R5cGVfaW5mb0UAeNkAABTYAAAI2AAAAAAAAIjYAAD+AQAA/wEAAAACAAABAgAAAgIAAE4xMF9fY3h4YWJpdjEyM19fZnVuZGFtZW50YWxfdHlwZV9pbmZvRQB42QAAYNgAAKjXAAB2AAAATNgAAJTYAABiAAAATNgAAKDYAABjAAAATNgAAKzYAABoAAAATNgAALjYAABhAAAATNgAAMTYAABzAAAATNgAANDYAAB0AAAATNgAANzYAABpAAAATNgAAOjYAABqAAAATNgAAPTYAABsAAAATNgAAADZAABtAAAATNgAAAzZAAB4AAAATNgAABjZAAB5AAAATNgAACTZAABmAAAATNgAADDZAABkAAAATNgAADzZAAAAAAAA2NcAAP4BAAADAgAAAAIAAAECAAAEAgAABQIAAAYCAAAHAgAAAAAAAMDZAAD+AQAACAIAAAACAAABAgAABAIAAAkCAAAKAgAACwIAAE4xMF9fY3h4YWJpdjEyMF9fc2lfY2xhc3NfdHlwZV9pbmZvRQAAAAB42QAAmNkAANjXAAAAAAAAHNoAAP4BAAAMAgAAAAIAAAECAAAEAgAADQIAAA4CAAAPAgAATjEwX19jeHhhYml2MTIxX192bWlfY2xhc3NfdHlwZV9pbmZvRQAAAHjZAAD02QAA2NcAAAAAAACM2gAACAAAABACAAARAgAAAAAAALTaAAAIAAAAEgIAABMCAAAAAAAAdNoAAAgAAAAUAgAAFQIAAFN0OWV4Y2VwdGlvbgAAAABQ2QAAZNoAAFN0OWJhZF9hbGxvYwAAAAB42QAAfNoAAHTaAABTdDIwYmFkX2FycmF5X25ld19sZW5ndGgAAAAAeNkAAJjaAACM2gAAAAAAAPjaAAAHAAAAFgIAABcCAAAAAAAAgNsAABgCAAAZAgAA+wEAAFN0MTFsb2dpY19lcnJvcgB42QAA6NoAAHTaAAAAAAAALNsAAAcAAAAaAgAAFwIAAFN0MTJsZW5ndGhfZXJyb3IAAAAAeNkAABjbAAD42gAAAAAAAGDbAAAHAAAAGwIAABcCAABTdDEyb3V0X29mX3JhbmdlAAAAAHjZAABM2wAA+NoAAFN0MTNydW50aW1lX2Vycm9yAAAAeNkAAGzbAAB02gAAU3Q5dHlwZV9pbmZvAAAAAFDZAACM2wAAAQFXAWSs2wAArNsAAAAAAQAAAgAABQAAAAAAAAAAAAAAvAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAugAAALkAAAAwPQ0AAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAP//////////AVnw2wAAAAAAAAUAAAAAAAAAAAAAAMoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALoAAADLAAAAOD0NAAAEAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAD/////CgEMiNwAABBMDgD9AQAA";if(!isDataURI(wasmBinaryFile)){wasmBinaryFile=locateFile(wasmBinaryFile)}function getBinarySync(file){if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}var binary=tryParseAsDataURI(file);if(binary){return binary}if(readBinary){return readBinary(file)}throw"both async and sync fetching of the wasm failed"}function getBinaryPromise(binaryFile){return Promise.resolve().then(()=>getBinarySync(binaryFile))}function instantiateArrayBuffer(binaryFile,imports,receiver){return getBinaryPromise(binaryFile).then(binary=>WebAssembly.instantiate(binary,imports)).then(instance=>instance).then(receiver,reason=>{err(`failed to asynchronously prepare wasm: ${reason}`);abort(reason)})}function instantiateAsync(binary,binaryFile,imports,callback){return instantiateArrayBuffer(binaryFile,imports,callback)}function createWasm(){var info={"a":wasmImports};function receiveInstance(instance,module){var exports=instance.exports;wasmExports=exports;registerTLSInit(wasmExports["_"]);wasmTable=wasmExports["X"];addOnInit(wasmExports["W"]);wasmModule=module;removeRunDependency("wasm-instantiate");return exports}addRunDependency("wasm-instantiate");function receiveInstantiationResult(result){receiveInstance(result["instance"],result["module"])}if(Module["instantiateWasm"]){try{return Module["instantiateWasm"](info,receiveInstance)}catch(e){err(`Module.instantiateWasm callback failed with error: ${e}`);readyPromiseReject(e)}}instantiateAsync(wasmBinary,wasmBinaryFile,info,receiveInstantiationResult).catch(readyPromiseReject);return{}}var tempDouble;var tempI64;function ExitStatus(status){this.name="ExitStatus";this.message=`Program terminated with exit(${status})`;this.status=status}var terminateWorker=worker=>{worker.terminate();worker.onmessage=e=>{}};var killThread=pthread_ptr=>{var worker=PThread.pthreads[pthread_ptr];delete PThread.pthreads[pthread_ptr];terminateWorker(worker);__emscripten_thread_free_data(pthread_ptr);PThread.runningWorkers.splice(PThread.runningWorkers.indexOf(worker),1);worker.pthread_ptr=0};var cancelThread=pthread_ptr=>{var worker=PThread.pthreads[pthread_ptr];worker.postMessage({"cmd":"cancel"})};var cleanupThread=pthread_ptr=>{var worker=PThread.pthreads[pthread_ptr];assert(worker);PThread.returnWorkerToPool(worker)};var spawnThread=threadParams=>{var worker=PThread.getNewWorker();if(!worker){return 6}PThread.runningWorkers.push(worker);PThread.pthreads[threadParams.pthread_ptr]=worker;worker.pthread_ptr=threadParams.pthread_ptr;var msg={"cmd":"run","start_routine":threadParams.startRoutine,"arg":threadParams.arg,"pthread_ptr":threadParams.pthread_ptr};if(ENVIRONMENT_IS_NODE){worker.unref()}worker.postMessage(msg,threadParams.transferList);return 0};var PATH={isAbs:path=>path.charAt(0)==="/",splitPath:filename=>{var splitPathRe=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;return splitPathRe.exec(filename).slice(1)},normalizeArray:(parts,allowAboveRoot)=>{var up=0;for(var i=parts.length-1;i>=0;i--){var last=parts[i];if(last==="."){parts.splice(i,1)}else if(last===".."){parts.splice(i,1);up++}else if(up){parts.splice(i,1);up--}}if(allowAboveRoot){for(;up;up--){parts.unshift("..")}}return parts},normalize:path=>{var isAbsolute=PATH.isAbs(path),trailingSlash=path.substr(-1)==="/";path=PATH.normalizeArray(path.split("/").filter(p=>!!p),!isAbsolute).join("/");if(!path&&!isAbsolute){path="."}if(path&&trailingSlash){path+="/"}return(isAbsolute?"/":"")+path},dirname:path=>{var result=PATH.splitPath(path),root=result[0],dir=result[1];if(!root&&!dir){return"."}if(dir){dir=dir.substr(0,dir.length-1)}return root+dir},basename:path=>{if(path==="/")return"/";path=PATH.normalize(path);path=path.replace(/\/$/,"");var lastSlash=path.lastIndexOf("/");if(lastSlash===-1)return path;return path.substr(lastSlash+1)},join:function(){var paths=Array.prototype.slice.call(arguments);return PATH.normalize(paths.join("/"))},join2:(l,r)=>PATH.normalize(l+"/"+r)};var initRandomFill=()=>{if(typeof crypto=="object"&&typeof crypto["getRandomValues"]=="function"){return view=>(view.set(crypto.getRandomValues(new Uint8Array(view.byteLength))),view)}else if(ENVIRONMENT_IS_NODE){try{var crypto_module=require("crypto");var randomFillSync=crypto_module["randomFillSync"];if(randomFillSync){return view=>crypto_module["randomFillSync"](view)}var randomBytes=crypto_module["randomBytes"];return view=>(view.set(randomBytes(view.byteLength)),view)}catch(e){}}abort("initRandomDevice")};var randomFill=view=>(randomFill=initRandomFill())(view);var PATH_FS={resolve:function(){var resolvedPath="",resolvedAbsolute=false;for(var i=arguments.length-1;i>=-1&&!resolvedAbsolute;i--){var path=i>=0?arguments[i]:FS.cwd();if(typeof path!="string"){throw new TypeError("Arguments to path.resolve must be strings")}else if(!path){return""}resolvedPath=path+"/"+resolvedPath;resolvedAbsolute=PATH.isAbs(path)}resolvedPath=PATH.normalizeArray(resolvedPath.split("/").filter(p=>!!p),!resolvedAbsolute).join("/");return(resolvedAbsolute?"/":"")+resolvedPath||"."},relative:(from,to)=>{from=PATH_FS.resolve(from).substr(1);to=PATH_FS.resolve(to).substr(1);function trim(arr){var start=0;for(;start=0;end--){if(arr[end]!=="")break}if(start>end)return[];return arr.slice(start,end-start+1)}var fromParts=trim(from.split("/"));var toParts=trim(to.split("/"));var length=Math.min(fromParts.length,toParts.length);var samePartsLength=length;for(var i=0;i{var endIdx=idx+maxBytesToRead;var endPtr=idx;while(heapOrArray[endPtr]&&!(endPtr>=endIdx))++endPtr;if(endPtr-idx>16&&heapOrArray.buffer&&UTF8Decoder){return UTF8Decoder.decode(heapOrArray.buffer instanceof SharedArrayBuffer?heapOrArray.slice(idx,endPtr):heapOrArray.subarray(idx,endPtr))}var str="";while(idx>10,56320|ch&1023)}}return str};var FS_stdin_getChar_buffer=[];var lengthBytesUTF8=str=>{var len=0;for(var i=0;i=55296&&c<=57343){len+=4;++i}else{len+=3}}return len};var stringToUTF8Array=(str,heap,outIdx,maxBytesToWrite)=>{if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=55296&&u<=57343){var u1=str.charCodeAt(++i);u=65536+((u&1023)<<10)|u1&1023}if(u<=127){if(outIdx>=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}}heap[outIdx]=0;return outIdx-startIdx};function intArrayFromString(stringy,dontAddNull,length){var len=length>0?length:lengthBytesUTF8(stringy)+1;var u8array=new Array(len);var numBytesWritten=stringToUTF8Array(stringy,u8array,0,u8array.length);if(dontAddNull)u8array.length=numBytesWritten;return u8array}var FS_stdin_getChar=()=>{if(!FS_stdin_getChar_buffer.length){var result=null;if(ENVIRONMENT_IS_NODE){var BUFSIZE=256;var buf=Buffer.alloc(BUFSIZE);var bytesRead=0;var fd=process.stdin.fd;try{bytesRead=fs.readSync(fd,buf)}catch(e){if(e.toString().includes("EOF"))bytesRead=0;else throw e}if(bytesRead>0){result=buf.slice(0,bytesRead).toString("utf-8")}else{result=null}}else if(typeof window!="undefined"&&typeof window.prompt=="function"){result=window.prompt("Input: ");if(result!==null){result+="\n"}}else if(typeof readline=="function"){result=readline();if(result!==null){result+="\n"}}if(!result){return null}FS_stdin_getChar_buffer=intArrayFromString(result,true)}return FS_stdin_getChar_buffer.shift()};var TTY={ttys:[],init(){},shutdown(){},register(dev,ops){TTY.ttys[dev]={input:[],output:[],ops:ops};FS.registerDevice(dev,TTY.stream_ops)},stream_ops:{open(stream){var tty=TTY.ttys[stream.node.rdev];if(!tty){throw new FS.ErrnoError(43)}stream.tty=tty;stream.seekable=false},close(stream){stream.tty.ops.fsync(stream.tty)},fsync(stream){stream.tty.ops.fsync(stream.tty)},read(stream,buffer,offset,length,pos){if(!stream.tty||!stream.tty.ops.get_char){throw new FS.ErrnoError(60)}var bytesRead=0;for(var i=0;i0){out(UTF8ArrayToString(tty.output,0));tty.output=[]}},ioctl_tcgets(tty){return{c_iflag:25856,c_oflag:5,c_cflag:191,c_lflag:35387,c_cc:[3,28,127,21,4,0,1,0,17,19,26,0,18,15,23,22,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}},ioctl_tcsets(tty,optional_actions,data){return 0},ioctl_tiocgwinsz(tty){return[24,80]}},default_tty1_ops:{put_char(tty,val){if(val===null||val===10){err(UTF8ArrayToString(tty.output,0));tty.output=[]}else{if(val!=0)tty.output.push(val)}},fsync(tty){if(tty.output&&tty.output.length>0){err(UTF8ArrayToString(tty.output,0));tty.output=[]}}}};var mmapAlloc=size=>{abort()};var MEMFS={ops_table:null,mount(mount){return MEMFS.createNode(null,"/",16384|511,0)},createNode(parent,name,mode,dev){if(FS.isBlkdev(mode)||FS.isFIFO(mode)){throw new FS.ErrnoError(63)}if(!MEMFS.ops_table){MEMFS.ops_table={dir:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,lookup:MEMFS.node_ops.lookup,mknod:MEMFS.node_ops.mknod,rename:MEMFS.node_ops.rename,unlink:MEMFS.node_ops.unlink,rmdir:MEMFS.node_ops.rmdir,readdir:MEMFS.node_ops.readdir,symlink:MEMFS.node_ops.symlink},stream:{llseek:MEMFS.stream_ops.llseek}},file:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:{llseek:MEMFS.stream_ops.llseek,read:MEMFS.stream_ops.read,write:MEMFS.stream_ops.write,allocate:MEMFS.stream_ops.allocate,mmap:MEMFS.stream_ops.mmap,msync:MEMFS.stream_ops.msync}},link:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,readlink:MEMFS.node_ops.readlink},stream:{}},chrdev:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:FS.chrdev_stream_ops}}}var node=FS.createNode(parent,name,mode,dev);if(FS.isDir(node.mode)){node.node_ops=MEMFS.ops_table.dir.node;node.stream_ops=MEMFS.ops_table.dir.stream;node.contents={}}else if(FS.isFile(node.mode)){node.node_ops=MEMFS.ops_table.file.node;node.stream_ops=MEMFS.ops_table.file.stream;node.usedBytes=0;node.contents=null}else if(FS.isLink(node.mode)){node.node_ops=MEMFS.ops_table.link.node;node.stream_ops=MEMFS.ops_table.link.stream}else if(FS.isChrdev(node.mode)){node.node_ops=MEMFS.ops_table.chrdev.node;node.stream_ops=MEMFS.ops_table.chrdev.stream}node.timestamp=Date.now();if(parent){parent.contents[name]=node;parent.timestamp=node.timestamp}return node},getFileDataAsTypedArray(node){if(!node.contents)return new Uint8Array(0);if(node.contents.subarray)return node.contents.subarray(0,node.usedBytes);return new Uint8Array(node.contents)},expandFileStorage(node,newCapacity){var prevCapacity=node.contents?node.contents.length:0;if(prevCapacity>=newCapacity)return;var CAPACITY_DOUBLING_MAX=1024*1024;newCapacity=Math.max(newCapacity,prevCapacity*(prevCapacity>>0);if(prevCapacity!=0)newCapacity=Math.max(newCapacity,256);var oldContents=node.contents;node.contents=new Uint8Array(newCapacity);if(node.usedBytes>0)node.contents.set(oldContents.subarray(0,node.usedBytes),0)},resizeFileStorage(node,newSize){if(node.usedBytes==newSize)return;if(newSize==0){node.contents=null;node.usedBytes=0}else{var oldContents=node.contents;node.contents=new Uint8Array(newSize);if(oldContents){node.contents.set(oldContents.subarray(0,Math.min(newSize,node.usedBytes)))}node.usedBytes=newSize}},node_ops:{getattr(node){var attr={};attr.dev=FS.isChrdev(node.mode)?node.id:1;attr.ino=node.id;attr.mode=node.mode;attr.nlink=1;attr.uid=0;attr.gid=0;attr.rdev=node.rdev;if(FS.isDir(node.mode)){attr.size=4096}else if(FS.isFile(node.mode)){attr.size=node.usedBytes}else if(FS.isLink(node.mode)){attr.size=node.link.length}else{attr.size=0}attr.atime=new Date(node.timestamp);attr.mtime=new Date(node.timestamp);attr.ctime=new Date(node.timestamp);attr.blksize=4096;attr.blocks=Math.ceil(attr.size/attr.blksize);return attr},setattr(node,attr){if(attr.mode!==undefined){node.mode=attr.mode}if(attr.timestamp!==undefined){node.timestamp=attr.timestamp}if(attr.size!==undefined){MEMFS.resizeFileStorage(node,attr.size)}},lookup(parent,name){throw FS.genericErrors[44]},mknod(parent,name,mode,dev){return MEMFS.createNode(parent,name,mode,dev)},rename(old_node,new_dir,new_name){if(FS.isDir(old_node.mode)){var new_node;try{new_node=FS.lookupNode(new_dir,new_name)}catch(e){}if(new_node){for(var i in new_node.contents){throw new FS.ErrnoError(55)}}}delete old_node.parent.contents[old_node.name];old_node.parent.timestamp=Date.now();old_node.name=new_name;new_dir.contents[new_name]=old_node;new_dir.timestamp=old_node.parent.timestamp;old_node.parent=new_dir},unlink(parent,name){delete parent.contents[name];parent.timestamp=Date.now()},rmdir(parent,name){var node=FS.lookupNode(parent,name);for(var i in node.contents){throw new FS.ErrnoError(55)}delete parent.contents[name];parent.timestamp=Date.now()},readdir(node){var entries=[".",".."];for(var key in node.contents){if(!node.contents.hasOwnProperty(key)){continue}entries.push(key)}return entries},symlink(parent,newname,oldpath){var node=MEMFS.createNode(parent,newname,511|40960,0);node.link=oldpath;return node},readlink(node){if(!FS.isLink(node.mode)){throw new FS.ErrnoError(28)}return node.link}},stream_ops:{read(stream,buffer,offset,length,position){var contents=stream.node.contents;if(position>=stream.node.usedBytes)return 0;var size=Math.min(stream.node.usedBytes-position,length);if(size>8&&contents.subarray){buffer.set(contents.subarray(position,position+size),offset)}else{for(var i=0;i0||position+length{var dep=!noRunDep?getUniqueRunDependency(`al ${url}`):"";readAsync(url,arrayBuffer=>{assert(arrayBuffer,`Loading data file "${url}" failed (no arrayBuffer).`);onload(new Uint8Array(arrayBuffer));if(dep)removeRunDependency(dep)},event=>{if(onerror){onerror()}else{throw`Loading data file "${url}" failed.`}});if(dep)addRunDependency(dep)};var preloadPlugins=Module["preloadPlugins"]||[];var FS_handledByPreloadPlugin=(byteArray,fullname,finish,onerror)=>{if(typeof Browser!="undefined")Browser.init();var handled=false;preloadPlugins.forEach(plugin=>{if(handled)return;if(plugin["canHandle"](fullname)){plugin["handle"](byteArray,fullname,finish,onerror);handled=true}});return handled};var FS_createPreloadedFile=(parent,name,url,canRead,canWrite,onload,onerror,dontCreateFile,canOwn,preFinish)=>{var fullname=name?PATH_FS.resolve(PATH.join2(parent,name)):parent;var dep=getUniqueRunDependency(`cp ${fullname}`);function processData(byteArray){function finish(byteArray){if(preFinish)preFinish();if(!dontCreateFile){FS.createDataFile(parent,name,byteArray,canRead,canWrite,canOwn)}if(onload)onload();removeRunDependency(dep)}if(FS_handledByPreloadPlugin(byteArray,fullname,finish,()=>{if(onerror)onerror();removeRunDependency(dep)})){return}finish(byteArray)}addRunDependency(dep);if(typeof url=="string"){asyncLoad(url,byteArray=>processData(byteArray),onerror)}else{processData(url)}};var FS_modeStringToFlags=str=>{var flagModes={"r":0,"r+":2,"w":512|64|1,"w+":512|64|2,"a":1024|64|1,"a+":1024|64|2};var flags=flagModes[str];if(typeof flags=="undefined"){throw new Error(`Unknown file open mode: ${str}`)}return flags};var FS_getMode=(canRead,canWrite)=>{var mode=0;if(canRead)mode|=292|73;if(canWrite)mode|=146;return mode};var FS={root:null,mounts:[],devices:{},streams:[],nextInode:1,nameTable:null,currentPath:"/",initialized:false,ignorePermissions:true,ErrnoError:null,genericErrors:{},filesystems:null,syncFSRequests:0,lookupPath(path,opts={}){path=PATH_FS.resolve(path);if(!path)return{path:"",node:null};var defaults={follow_mount:true,recurse_count:0};opts=Object.assign(defaults,opts);if(opts.recurse_count>8){throw new FS.ErrnoError(32)}var parts=path.split("/").filter(p=>!!p);var current=FS.root;var current_path="/";for(var i=0;i40){throw new FS.ErrnoError(32)}}}}return{path:current_path,node:current}},getPath(node){var path;while(true){if(FS.isRoot(node)){var mount=node.mount.mountpoint;if(!path)return mount;return mount[mount.length-1]!=="/"?`${mount}/${path}`:mount+path}path=path?`${node.name}/${path}`:node.name;node=node.parent}},hashName(parentid,name){var hash=0;for(var i=0;i>>0)%FS.nameTable.length},hashAddNode(node){var hash=FS.hashName(node.parent.id,node.name);node.name_next=FS.nameTable[hash];FS.nameTable[hash]=node},hashRemoveNode(node){var hash=FS.hashName(node.parent.id,node.name);if(FS.nameTable[hash]===node){FS.nameTable[hash]=node.name_next}else{var current=FS.nameTable[hash];while(current){if(current.name_next===node){current.name_next=node.name_next;break}current=current.name_next}}},lookupNode(parent,name){var errCode=FS.mayLookup(parent);if(errCode){throw new FS.ErrnoError(errCode,parent)}var hash=FS.hashName(parent.id,name);for(var node=FS.nameTable[hash];node;node=node.name_next){var nodeName=node.name;if(node.parent.id===parent.id&&nodeName===name){return node}}return FS.lookup(parent,name)},createNode(parent,name,mode,rdev){var node=new FS.FSNode(parent,name,mode,rdev);FS.hashAddNode(node);return node},destroyNode(node){FS.hashRemoveNode(node)},isRoot(node){return node===node.parent},isMountpoint(node){return!!node.mounted},isFile(mode){return(mode&61440)===32768},isDir(mode){return(mode&61440)===16384},isLink(mode){return(mode&61440)===40960},isChrdev(mode){return(mode&61440)===8192},isBlkdev(mode){return(mode&61440)===24576},isFIFO(mode){return(mode&61440)===4096},isSocket(mode){return(mode&49152)===49152},flagsToPermissionString(flag){var perms=["r","w","rw"][flag&3];if(flag&512){perms+="w"}return perms},nodePermissions(node,perms){if(FS.ignorePermissions){return 0}if(perms.includes("r")&&!(node.mode&292)){return 2}else if(perms.includes("w")&&!(node.mode&146)){return 2}else if(perms.includes("x")&&!(node.mode&73)){return 2}return 0},mayLookup(dir){var errCode=FS.nodePermissions(dir,"x");if(errCode)return errCode;if(!dir.node_ops.lookup)return 2;return 0},mayCreate(dir,name){try{var node=FS.lookupNode(dir,name);return 20}catch(e){}return FS.nodePermissions(dir,"wx")},mayDelete(dir,name,isdir){var node;try{node=FS.lookupNode(dir,name)}catch(e){return e.errno}var errCode=FS.nodePermissions(dir,"wx");if(errCode){return errCode}if(isdir){if(!FS.isDir(node.mode)){return 54}if(FS.isRoot(node)||FS.getPath(node)===FS.cwd()){return 10}}else{if(FS.isDir(node.mode)){return 31}}return 0},mayOpen(node,flags){if(!node){return 44}if(FS.isLink(node.mode)){return 32}else if(FS.isDir(node.mode)){if(FS.flagsToPermissionString(flags)!=="r"||flags&512){return 31}}return FS.nodePermissions(node,FS.flagsToPermissionString(flags))},MAX_OPEN_FDS:4096,nextfd(){for(var fd=0;fd<=FS.MAX_OPEN_FDS;fd++){if(!FS.streams[fd]){return fd}}throw new FS.ErrnoError(33)},getStreamChecked(fd){var stream=FS.getStream(fd);if(!stream){throw new FS.ErrnoError(8)}return stream},getStream:fd=>FS.streams[fd],createStream(stream,fd=-1){if(!FS.FSStream){FS.FSStream=function(){this.shared={}};FS.FSStream.prototype={};Object.defineProperties(FS.FSStream.prototype,{object:{get(){return this.node},set(val){this.node=val}},isRead:{get(){return(this.flags&2097155)!==1}},isWrite:{get(){return(this.flags&2097155)!==0}},isAppend:{get(){return this.flags&1024}},flags:{get(){return this.shared.flags},set(val){this.shared.flags=val}},position:{get(){return this.shared.position},set(val){this.shared.position=val}}})}stream=Object.assign(new FS.FSStream,stream);if(fd==-1){fd=FS.nextfd()}stream.fd=fd;FS.streams[fd]=stream;return stream},closeStream(fd){FS.streams[fd]=null},chrdev_stream_ops:{open(stream){var device=FS.getDevice(stream.node.rdev);stream.stream_ops=device.stream_ops;if(stream.stream_ops.open){stream.stream_ops.open(stream)}},llseek(){throw new FS.ErrnoError(70)}},major:dev=>dev>>8,minor:dev=>dev&255,makedev:(ma,mi)=>ma<<8|mi,registerDevice(dev,ops){FS.devices[dev]={stream_ops:ops}},getDevice:dev=>FS.devices[dev],getMounts(mount){var mounts=[];var check=[mount];while(check.length){var m=check.pop();mounts.push(m);check.push.apply(check,m.mounts)}return mounts},syncfs(populate,callback){if(typeof populate=="function"){callback=populate;populate=false}FS.syncFSRequests++;if(FS.syncFSRequests>1){err(`warning: ${FS.syncFSRequests} FS.syncfs operations in flight at once, probably just doing extra work`)}var mounts=FS.getMounts(FS.root.mount);var completed=0;function doCallback(errCode){FS.syncFSRequests--;return callback(errCode)}function done(errCode){if(errCode){if(!done.errored){done.errored=true;return doCallback(errCode)}return}if(++completed>=mounts.length){doCallback(null)}}mounts.forEach(mount=>{if(!mount.type.syncfs){return done(null)}mount.type.syncfs(mount,populate,done)})},mount(type,opts,mountpoint){var root=mountpoint==="/";var pseudo=!mountpoint;var node;if(root&&FS.root){throw new FS.ErrnoError(10)}else if(!root&&!pseudo){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});mountpoint=lookup.path;node=lookup.node;if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}if(!FS.isDir(node.mode)){throw new FS.ErrnoError(54)}}var mount={type:type,opts:opts,mountpoint:mountpoint,mounts:[]};var mountRoot=type.mount(mount);mountRoot.mount=mount;mount.root=mountRoot;if(root){FS.root=mountRoot}else if(node){node.mounted=mount;if(node.mount){node.mount.mounts.push(mount)}}return mountRoot},unmount(mountpoint){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});if(!FS.isMountpoint(lookup.node)){throw new FS.ErrnoError(28)}var node=lookup.node;var mount=node.mounted;var mounts=FS.getMounts(mount);Object.keys(FS.nameTable).forEach(hash=>{var current=FS.nameTable[hash];while(current){var next=current.name_next;if(mounts.includes(current.mount)){FS.destroyNode(current)}current=next}});node.mounted=null;var idx=node.mount.mounts.indexOf(mount);node.mount.mounts.splice(idx,1)},lookup(parent,name){return parent.node_ops.lookup(parent,name)},mknod(path,mode,dev){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);if(!name||name==="."||name===".."){throw new FS.ErrnoError(28)}var errCode=FS.mayCreate(parent,name);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.mknod){throw new FS.ErrnoError(63)}return parent.node_ops.mknod(parent,name,mode,dev)},create(path,mode){mode=mode!==undefined?mode:438;mode&=4095;mode|=32768;return FS.mknod(path,mode,0)},mkdir(path,mode){mode=mode!==undefined?mode:511;mode&=511|512;mode|=16384;return FS.mknod(path,mode,0)},mkdirTree(path,mode){var dirs=path.split("/");var d="";for(var i=0;i0,ioctl(stream,cmd,arg){if(!stream.stream_ops.ioctl){throw new FS.ErrnoError(59)}return stream.stream_ops.ioctl(stream,cmd,arg)},readFile(path,opts={}){opts.flags=opts.flags||0;opts.encoding=opts.encoding||"binary";if(opts.encoding!=="utf8"&&opts.encoding!=="binary"){throw new Error(`Invalid encoding type "${opts.encoding}"`)}var ret;var stream=FS.open(path,opts.flags);var stat=FS.stat(path);var length=stat.size;var buf=new Uint8Array(length);FS.read(stream,buf,0,length,0);if(opts.encoding==="utf8"){ret=UTF8ArrayToString(buf,0)}else if(opts.encoding==="binary"){ret=buf}FS.close(stream);return ret},writeFile(path,data,opts={}){opts.flags=opts.flags||577;var stream=FS.open(path,opts.flags,opts.mode);if(typeof data=="string"){var buf=new Uint8Array(lengthBytesUTF8(data)+1);var actualNumBytes=stringToUTF8Array(data,buf,0,buf.length);FS.write(stream,buf,0,actualNumBytes,undefined,opts.canOwn)}else if(ArrayBuffer.isView(data)){FS.write(stream,data,0,data.byteLength,undefined,opts.canOwn)}else{throw new Error("Unsupported data type")}FS.close(stream)},cwd:()=>FS.currentPath,chdir(path){var lookup=FS.lookupPath(path,{follow:true});if(lookup.node===null){throw new FS.ErrnoError(44)}if(!FS.isDir(lookup.node.mode)){throw new FS.ErrnoError(54)}var errCode=FS.nodePermissions(lookup.node,"x");if(errCode){throw new FS.ErrnoError(errCode)}FS.currentPath=lookup.path},createDefaultDirectories(){FS.mkdir("/tmp");FS.mkdir("/home");FS.mkdir("/home/web_user")},createDefaultDevices(){FS.mkdir("/dev");FS.registerDevice(FS.makedev(1,3),{read:()=>0,write:(stream,buffer,offset,length,pos)=>length});FS.mkdev("/dev/null",FS.makedev(1,3));TTY.register(FS.makedev(5,0),TTY.default_tty_ops);TTY.register(FS.makedev(6,0),TTY.default_tty1_ops);FS.mkdev("/dev/tty",FS.makedev(5,0));FS.mkdev("/dev/tty1",FS.makedev(6,0));var randomBuffer=new Uint8Array(1024),randomLeft=0;var randomByte=()=>{if(randomLeft===0){randomLeft=randomFill(randomBuffer).byteLength}return randomBuffer[--randomLeft]};FS.createDevice("/dev","random",randomByte);FS.createDevice("/dev","urandom",randomByte);FS.mkdir("/dev/shm");FS.mkdir("/dev/shm/tmp")},createSpecialDirectories(){FS.mkdir("/proc");var proc_self=FS.mkdir("/proc/self");FS.mkdir("/proc/self/fd");FS.mount({mount(){var node=FS.createNode(proc_self,"fd",16384|511,73);node.node_ops={lookup(parent,name){var fd=+name;var stream=FS.getStreamChecked(fd);var ret={parent:null,mount:{mountpoint:"fake"},node_ops:{readlink:()=>stream.path}};ret.parent=ret;return ret}};return node}},{},"/proc/self/fd")},createStandardStreams(){if(Module["stdin"]){FS.createDevice("/dev","stdin",Module["stdin"])}else{FS.symlink("/dev/tty","/dev/stdin")}if(Module["stdout"]){FS.createDevice("/dev","stdout",null,Module["stdout"])}else{FS.symlink("/dev/tty","/dev/stdout")}if(Module["stderr"]){FS.createDevice("/dev","stderr",null,Module["stderr"])}else{FS.symlink("/dev/tty1","/dev/stderr")}var stdin=FS.open("/dev/stdin",0);var stdout=FS.open("/dev/stdout",1);var stderr=FS.open("/dev/stderr",1)},ensureErrnoError(){if(FS.ErrnoError)return;FS.ErrnoError=function ErrnoError(errno,node){this.name="ErrnoError";this.node=node;this.setErrno=function(errno){this.errno=errno};this.setErrno(errno);this.message="FS error"};FS.ErrnoError.prototype=new Error;FS.ErrnoError.prototype.constructor=FS.ErrnoError;[44].forEach(code=>{FS.genericErrors[code]=new FS.ErrnoError(code);FS.genericErrors[code].stack=""})},staticInit(){FS.ensureErrnoError();FS.nameTable=new Array(4096);FS.mount(MEMFS,{},"/");FS.createDefaultDirectories();FS.createDefaultDevices();FS.createSpecialDirectories();FS.filesystems={"MEMFS":MEMFS}},init(input,output,error){FS.init.initialized=true;FS.ensureErrnoError();Module["stdin"]=input||Module["stdin"];Module["stdout"]=output||Module["stdout"];Module["stderr"]=error||Module["stderr"];FS.createStandardStreams()},quit(){FS.init.initialized=false;for(var i=0;ithis.length-1||idx<0){return undefined}var chunkOffset=idx%this.chunkSize;var chunkNum=idx/this.chunkSize|0;return this.getter(chunkNum)[chunkOffset]};LazyUint8Array.prototype.setDataGetter=function LazyUint8Array_setDataGetter(getter){this.getter=getter};LazyUint8Array.prototype.cacheLength=function LazyUint8Array_cacheLength(){var xhr=new XMLHttpRequest;xhr.open("HEAD",url,false);xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);var datalength=Number(xhr.getResponseHeader("Content-length"));var header;var hasByteServing=(header=xhr.getResponseHeader("Accept-Ranges"))&&header==="bytes";var usesGzip=(header=xhr.getResponseHeader("Content-Encoding"))&&header==="gzip";var chunkSize=1024*1024;if(!hasByteServing)chunkSize=datalength;var doXHR=(from,to)=>{if(from>to)throw new Error("invalid range ("+from+", "+to+") or no bytes requested!");if(to>datalength-1)throw new Error("only "+datalength+" bytes available! programmer error!");var xhr=new XMLHttpRequest;xhr.open("GET",url,false);if(datalength!==chunkSize)xhr.setRequestHeader("Range","bytes="+from+"-"+to);xhr.responseType="arraybuffer";if(xhr.overrideMimeType){xhr.overrideMimeType("text/plain; charset=x-user-defined")}xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);if(xhr.response!==undefined){return new Uint8Array(xhr.response||[])}return intArrayFromString(xhr.responseText||"",true)};var lazyArray=this;lazyArray.setDataGetter(chunkNum=>{var start=chunkNum*chunkSize;var end=(chunkNum+1)*chunkSize-1;end=Math.min(end,datalength-1);if(typeof lazyArray.chunks[chunkNum]=="undefined"){lazyArray.chunks[chunkNum]=doXHR(start,end)}if(typeof lazyArray.chunks[chunkNum]=="undefined")throw new Error("doXHR failed!");return lazyArray.chunks[chunkNum]});if(usesGzip||!datalength){chunkSize=datalength=1;datalength=this.getter(0).length;chunkSize=datalength;out("LazyFiles on gzip forces download of the whole file when length is accessed")}this._length=datalength;this._chunkSize=chunkSize;this.lengthKnown=true};if(typeof XMLHttpRequest!="undefined"){if(!ENVIRONMENT_IS_WORKER)throw"Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc";var lazyArray=new LazyUint8Array;Object.defineProperties(lazyArray,{length:{get:function(){if(!this.lengthKnown){this.cacheLength()}return this._length}},chunkSize:{get:function(){if(!this.lengthKnown){this.cacheLength()}return this._chunkSize}}});var properties={isDevice:false,contents:lazyArray}}else{var properties={isDevice:false,url:url}}var node=FS.createFile(parent,name,properties,canRead,canWrite);if(properties.contents){node.contents=properties.contents}else if(properties.url){node.contents=null;node.url=properties.url}Object.defineProperties(node,{usedBytes:{get:function(){return this.contents.length}}});var stream_ops={};var keys=Object.keys(node.stream_ops);keys.forEach(key=>{var fn=node.stream_ops[key];stream_ops[key]=function forceLoadLazyFile(){FS.forceLoadFile(node);return fn.apply(null,arguments)}});function writeChunks(stream,buffer,offset,length,position){var contents=stream.node.contents;if(position>=contents.length)return 0;var size=Math.min(contents.length-position,length);if(contents.slice){for(var i=0;i{FS.forceLoadFile(node);return writeChunks(stream,buffer,offset,length,position)};stream_ops.mmap=(stream,length,position,prot,flags)=>{FS.forceLoadFile(node);var ptr=mmapAlloc(length);if(!ptr){throw new FS.ErrnoError(48)}writeChunks(stream,GROWABLE_HEAP_I8(),ptr,length,position);return{ptr:ptr,allocated:true}};node.stream_ops=stream_ops;return node}};var UTF8ToString=(ptr,maxBytesToRead)=>ptr?UTF8ArrayToString(GROWABLE_HEAP_U8(),ptr,maxBytesToRead):"";var SYSCALLS={DEFAULT_POLLMASK:5,calculateAt(dirfd,path,allowEmpty){if(PATH.isAbs(path)){return path}var dir;if(dirfd===-100){dir=FS.cwd()}else{var dirstream=SYSCALLS.getStreamFromFD(dirfd);dir=dirstream.path}if(path.length==0){if(!allowEmpty){throw new FS.ErrnoError(44)}return dir}return PATH.join2(dir,path)},doStat(func,path,buf){try{var stat=func(path)}catch(e){if(e&&e.node&&PATH.normalize(path)!==PATH.normalize(FS.getPath(e.node))){return-54}throw e}GROWABLE_HEAP_I32()[buf>>2]=stat.dev;GROWABLE_HEAP_I32()[buf+4>>2]=stat.mode;GROWABLE_HEAP_U32()[buf+8>>2]=stat.nlink;GROWABLE_HEAP_I32()[buf+12>>2]=stat.uid;GROWABLE_HEAP_I32()[buf+16>>2]=stat.gid;GROWABLE_HEAP_I32()[buf+20>>2]=stat.rdev;tempI64=[stat.size>>>0,(tempDouble=stat.size,+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],GROWABLE_HEAP_I32()[buf+24>>2]=tempI64[0],GROWABLE_HEAP_I32()[buf+28>>2]=tempI64[1];GROWABLE_HEAP_I32()[buf+32>>2]=4096;GROWABLE_HEAP_I32()[buf+36>>2]=stat.blocks;var atime=stat.atime.getTime();var mtime=stat.mtime.getTime();var ctime=stat.ctime.getTime();tempI64=[Math.floor(atime/1e3)>>>0,(tempDouble=Math.floor(atime/1e3),+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],GROWABLE_HEAP_I32()[buf+40>>2]=tempI64[0],GROWABLE_HEAP_I32()[buf+44>>2]=tempI64[1];GROWABLE_HEAP_U32()[buf+48>>2]=atime%1e3*1e3;tempI64=[Math.floor(mtime/1e3)>>>0,(tempDouble=Math.floor(mtime/1e3),+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],GROWABLE_HEAP_I32()[buf+56>>2]=tempI64[0],GROWABLE_HEAP_I32()[buf+60>>2]=tempI64[1];GROWABLE_HEAP_U32()[buf+64>>2]=mtime%1e3*1e3;tempI64=[Math.floor(ctime/1e3)>>>0,(tempDouble=Math.floor(ctime/1e3),+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],GROWABLE_HEAP_I32()[buf+72>>2]=tempI64[0],GROWABLE_HEAP_I32()[buf+76>>2]=tempI64[1];GROWABLE_HEAP_U32()[buf+80>>2]=ctime%1e3*1e3;tempI64=[stat.ino>>>0,(tempDouble=stat.ino,+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],GROWABLE_HEAP_I32()[buf+88>>2]=tempI64[0],GROWABLE_HEAP_I32()[buf+92>>2]=tempI64[1];return 0},doMsync(addr,stream,len,flags,offset){if(!FS.isFile(stream.node.mode)){throw new FS.ErrnoError(43)}if(flags&2){return 0}var buffer=GROWABLE_HEAP_U8().slice(addr,addr+len);FS.msync(stream,buffer,offset,len,flags)},varargs:undefined,get(){var ret=GROWABLE_HEAP_I32()[SYSCALLS.varargs>>2];SYSCALLS.varargs+=4;return ret},getp(){return SYSCALLS.get()},getStr(ptr){var ret=UTF8ToString(ptr);return ret},getStreamFromFD(fd){var stream=FS.getStreamChecked(fd);return stream}};function _proc_exit(code){if(ENVIRONMENT_IS_PTHREAD)return proxyToMainThread(0,1,code);EXITSTATUS=code;if(!keepRuntimeAlive()){PThread.terminateAllThreads();if(Module["onExit"])Module["onExit"](code);ABORT=true}quit_(code,new ExitStatus(code))}var exitJS=(status,implicit)=>{EXITSTATUS=status;if(ENVIRONMENT_IS_PTHREAD){exitOnMainThread(status);throw"unwind"}_proc_exit(status)};var _exit=exitJS;var handleException=e=>{if(e instanceof ExitStatus||e=="unwind"){return EXITSTATUS}quit_(1,e)};var PThread={unusedWorkers:[],runningWorkers:[],tlsInitFunctions:[],pthreads:{},init(){if(ENVIRONMENT_IS_PTHREAD){PThread.initWorker()}else{PThread.initMainThread()}},initMainThread(){var pthreadPoolSize=8;while(pthreadPoolSize--){PThread.allocateUnusedWorker()}addOnPreRun(()=>{addRunDependency("loading-workers");PThread.loadWasmModuleToAllWorkers(()=>removeRunDependency("loading-workers"))})},initWorker(){noExitRuntime=false},setExitStatus:status=>{EXITSTATUS=status},terminateAllThreads__deps:["$terminateWorker"],terminateAllThreads:()=>{for(var worker of PThread.runningWorkers){terminateWorker(worker)}for(var worker of PThread.unusedWorkers){terminateWorker(worker)}PThread.unusedWorkers=[];PThread.runningWorkers=[];PThread.pthreads=[]},returnWorkerToPool:worker=>{var pthread_ptr=worker.pthread_ptr;delete PThread.pthreads[pthread_ptr];PThread.unusedWorkers.push(worker);PThread.runningWorkers.splice(PThread.runningWorkers.indexOf(worker),1);worker.pthread_ptr=0;__emscripten_thread_free_data(pthread_ptr)},receiveObjectTransfer(data){},threadInitTLS(){PThread.tlsInitFunctions.forEach(f=>f())},loadWasmModuleToWorker:worker=>new Promise(onFinishedLoading=>{worker.onmessage=e=>{var d=e["data"];var cmd=d["cmd"];if(d["targetThread"]&&d["targetThread"]!=_pthread_self()){var targetWorker=PThread.pthreads[d["targetThread"]];if(targetWorker){targetWorker.postMessage(d,d["transferList"])}else{err(`Internal error! Worker sent a message "${cmd}" to target pthread ${d["targetThread"]}, but that thread no longer exists!`)}return}if(cmd==="checkMailbox"){checkMailbox()}else if(cmd==="spawnThread"){spawnThread(d)}else if(cmd==="cleanupThread"){cleanupThread(d["thread"])}else if(cmd==="killThread"){killThread(d["thread"])}else if(cmd==="cancelThread"){cancelThread(d["thread"])}else if(cmd==="loaded"){worker.loaded=true;if(ENVIRONMENT_IS_NODE&&!worker.pthread_ptr){worker.unref()}onFinishedLoading(worker)}else if(cmd==="alert"){alert(`Thread ${d["threadId"]}: ${d["text"]}`)}else if(d.target==="setimmediate"){worker.postMessage(d)}else if(cmd==="callHandler"){Module[d["handler"]](...d["args"])}else if(cmd){err(`worker sent an unknown command ${cmd}`)}};worker.onerror=e=>{var message="worker sent an error!";err(`${message} ${e.filename}:${e.lineno}: ${e.message}`);throw e};if(ENVIRONMENT_IS_NODE){worker.on("message",data=>worker.onmessage({data:data}));worker.on("error",e=>worker.onerror(e))}var handlers=[];var knownHandlers=["onExit","onAbort","print","printErr"];for(var handler of knownHandlers){if(Module.hasOwnProperty(handler)){handlers.push(handler)}}worker.postMessage({"cmd":"load","handlers":handlers,"urlOrBlob":Module["mainScriptUrlOrBlob"]||_scriptDir,"wasmMemory":wasmMemory,"wasmModule":wasmModule})}),loadWasmModuleToAllWorkers(onMaybeReady){if(ENVIRONMENT_IS_PTHREAD){return onMaybeReady()}let pthreadPoolReady=Promise.all(PThread.unusedWorkers.map(PThread.loadWasmModuleToWorker));pthreadPoolReady.then(onMaybeReady)},allocateUnusedWorker(){var worker;var pthreadMainJs=locateFile("libwhisper.worker.js");worker=new Worker(pthreadMainJs);PThread.unusedWorkers.push(worker)},getNewWorker(){if(PThread.unusedWorkers.length==0){PThread.allocateUnusedWorker();PThread.loadWasmModuleToWorker(PThread.unusedWorkers[0])}return PThread.unusedWorkers.pop()}};Module["PThread"]=PThread;var callRuntimeCallbacks=callbacks=>{while(callbacks.length>0){callbacks.shift()(Module)}};var establishStackSpace=()=>{var pthread_ptr=_pthread_self();var stackHigh=GROWABLE_HEAP_I32()[pthread_ptr+52>>2];var stackSize=GROWABLE_HEAP_I32()[pthread_ptr+56>>2];var stackLow=stackHigh-stackSize;_emscripten_stack_set_limits(stackHigh,stackLow);stackRestore(stackHigh)};Module["establishStackSpace"]=establishStackSpace;function exitOnMainThread(returnCode){if(ENVIRONMENT_IS_PTHREAD)return proxyToMainThread(1,0,returnCode);_exit(returnCode)}var wasmTableMirror=[];var getWasmTableEntry=funcPtr=>{var func=wasmTableMirror[funcPtr];if(!func){if(funcPtr>=wasmTableMirror.length)wasmTableMirror.length=funcPtr+1;wasmTableMirror[funcPtr]=func=wasmTable.get(funcPtr)}return func};var invokeEntryPoint=(ptr,arg)=>{var result=getWasmTableEntry(ptr)(arg);function finish(result){if(keepRuntimeAlive()){PThread.setExitStatus(result)}else{__emscripten_thread_exit(result)}}finish(result)};Module["invokeEntryPoint"]=invokeEntryPoint;var registerTLSInit=tlsInitFunc=>{PThread.tlsInitFunctions.push(tlsInitFunc)};function ExceptionInfo(excPtr){this.excPtr=excPtr;this.ptr=excPtr-24;this.set_type=function(type){GROWABLE_HEAP_U32()[this.ptr+4>>2]=type};this.get_type=function(){return GROWABLE_HEAP_U32()[this.ptr+4>>2]};this.set_destructor=function(destructor){GROWABLE_HEAP_U32()[this.ptr+8>>2]=destructor};this.get_destructor=function(){return GROWABLE_HEAP_U32()[this.ptr+8>>2]};this.set_caught=function(caught){caught=caught?1:0;GROWABLE_HEAP_I8()[this.ptr+12>>0]=caught};this.get_caught=function(){return GROWABLE_HEAP_I8()[this.ptr+12>>0]!=0};this.set_rethrown=function(rethrown){rethrown=rethrown?1:0;GROWABLE_HEAP_I8()[this.ptr+13>>0]=rethrown};this.get_rethrown=function(){return GROWABLE_HEAP_I8()[this.ptr+13>>0]!=0};this.init=function(type,destructor){this.set_adjusted_ptr(0);this.set_type(type);this.set_destructor(destructor)};this.set_adjusted_ptr=function(adjustedPtr){GROWABLE_HEAP_U32()[this.ptr+16>>2]=adjustedPtr};this.get_adjusted_ptr=function(){return GROWABLE_HEAP_U32()[this.ptr+16>>2]};this.get_exception_ptr=function(){var isPointer=___cxa_is_pointer_type(this.get_type());if(isPointer){return GROWABLE_HEAP_U32()[this.excPtr>>2]}var adjusted=this.get_adjusted_ptr();if(adjusted!==0)return adjusted;return this.excPtr}}var exceptionLast=0;var uncaughtExceptionCount=0;var ___cxa_throw=(ptr,type,destructor)=>{var info=new ExceptionInfo(ptr);info.init(type,destructor);exceptionLast=ptr;uncaughtExceptionCount++;throw exceptionLast};var ___emscripten_init_main_thread_js=tb=>{__emscripten_thread_init(tb,!ENVIRONMENT_IS_WORKER,1,!ENVIRONMENT_IS_WEB,65536,false);PThread.threadInitTLS()};var ___emscripten_thread_cleanup=thread=>{if(!ENVIRONMENT_IS_PTHREAD)cleanupThread(thread);else postMessage({"cmd":"cleanupThread","thread":thread})};function pthreadCreateProxied(pthread_ptr,attr,startRoutine,arg){if(ENVIRONMENT_IS_PTHREAD)return proxyToMainThread(2,1,pthread_ptr,attr,startRoutine,arg);return ___pthread_create_js(pthread_ptr,attr,startRoutine,arg)}var ___pthread_create_js=(pthread_ptr,attr,startRoutine,arg)=>{if(typeof SharedArrayBuffer=="undefined"){err("Current environment does not support SharedArrayBuffer, pthreads are not available!");return 6}var transferList=[];var error=0;if(ENVIRONMENT_IS_PTHREAD&&(transferList.length===0||error)){return pthreadCreateProxied(pthread_ptr,attr,startRoutine,arg)}if(error)return error;var threadParams={startRoutine:startRoutine,pthread_ptr:pthread_ptr,arg:arg,transferList:transferList};if(ENVIRONMENT_IS_PTHREAD){threadParams.cmd="spawnThread";postMessage(threadParams,transferList);return 0}return spawnThread(threadParams)};var setErrNo=value=>{GROWABLE_HEAP_I32()[___errno_location()>>2]=value;return value};function ___syscall_fcntl64(fd,cmd,varargs){if(ENVIRONMENT_IS_PTHREAD)return proxyToMainThread(3,1,fd,cmd,varargs);SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(fd);switch(cmd){case 0:{var arg=SYSCALLS.get();if(arg<0){return-28}while(FS.streams[arg]){arg++}var newStream;newStream=FS.createStream(stream,arg);return newStream.fd}case 1:case 2:return 0;case 3:return stream.flags;case 4:{var arg=SYSCALLS.get();stream.flags|=arg;return 0}case 5:{var arg=SYSCALLS.getp();var offset=0;GROWABLE_HEAP_I16()[arg+offset>>1]=2;return 0}case 6:case 7:return 0;case 16:case 8:return-28;case 9:setErrNo(28);return-1;default:{return-28}}}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_ioctl(fd,op,varargs){if(ENVIRONMENT_IS_PTHREAD)return proxyToMainThread(4,1,fd,op,varargs);SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(fd);switch(op){case 21509:{if(!stream.tty)return-59;return 0}case 21505:{if(!stream.tty)return-59;if(stream.tty.ops.ioctl_tcgets){var termios=stream.tty.ops.ioctl_tcgets(stream);var argp=SYSCALLS.getp();GROWABLE_HEAP_I32()[argp>>2]=termios.c_iflag||0;GROWABLE_HEAP_I32()[argp+4>>2]=termios.c_oflag||0;GROWABLE_HEAP_I32()[argp+8>>2]=termios.c_cflag||0;GROWABLE_HEAP_I32()[argp+12>>2]=termios.c_lflag||0;for(var i=0;i<32;i++){GROWABLE_HEAP_I8()[argp+i+17>>0]=termios.c_cc[i]||0}return 0}return 0}case 21510:case 21511:case 21512:{if(!stream.tty)return-59;return 0}case 21506:case 21507:case 21508:{if(!stream.tty)return-59;if(stream.tty.ops.ioctl_tcsets){var argp=SYSCALLS.getp();var c_iflag=GROWABLE_HEAP_I32()[argp>>2];var c_oflag=GROWABLE_HEAP_I32()[argp+4>>2];var c_cflag=GROWABLE_HEAP_I32()[argp+8>>2];var c_lflag=GROWABLE_HEAP_I32()[argp+12>>2];var c_cc=[];for(var i=0;i<32;i++){c_cc.push(GROWABLE_HEAP_I8()[argp+i+17>>0])}return stream.tty.ops.ioctl_tcsets(stream.tty,op,{c_iflag:c_iflag,c_oflag:c_oflag,c_cflag:c_cflag,c_lflag:c_lflag,c_cc:c_cc})}return 0}case 21519:{if(!stream.tty)return-59;var argp=SYSCALLS.getp();GROWABLE_HEAP_I32()[argp>>2]=0;return 0}case 21520:{if(!stream.tty)return-59;return-28}case 21531:{var argp=SYSCALLS.getp();return FS.ioctl(stream,op,argp)}case 21523:{if(!stream.tty)return-59;if(stream.tty.ops.ioctl_tiocgwinsz){var winsize=stream.tty.ops.ioctl_tiocgwinsz(stream.tty);var argp=SYSCALLS.getp();GROWABLE_HEAP_I16()[argp>>1]=winsize[0];GROWABLE_HEAP_I16()[argp+2>>1]=winsize[1]}return 0}case 21524:{if(!stream.tty)return-59;return 0}case 21515:{if(!stream.tty)return-59;return 0}default:return-28}}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_openat(dirfd,path,flags,varargs){if(ENVIRONMENT_IS_PTHREAD)return proxyToMainThread(5,1,dirfd,path,flags,varargs);SYSCALLS.varargs=varargs;try{path=SYSCALLS.getStr(path);path=SYSCALLS.calculateAt(dirfd,path);var mode=varargs?SYSCALLS.get():0;return FS.open(path,flags,mode).fd}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}var __embind_register_bigint=(primitiveType,name,size,minRange,maxRange)=>{};var embind_init_charCodes=()=>{var codes=new Array(256);for(var i=0;i<256;++i){codes[i]=String.fromCharCode(i)}embind_charCodes=codes};var embind_charCodes=undefined;var readLatin1String=ptr=>{var ret="";var c=ptr;while(GROWABLE_HEAP_U8()[c]){ret+=embind_charCodes[GROWABLE_HEAP_U8()[c++]]}return ret};var awaitingDependencies={};var registeredTypes={};var typeDependencies={};var BindingError=undefined;var throwBindingError=message=>{throw new BindingError(message)};var InternalError=undefined;var throwInternalError=message=>{throw new InternalError(message)};var whenDependentTypesAreResolved=(myTypes,dependentTypes,getTypeConverters)=>{myTypes.forEach(function(type){typeDependencies[type]=dependentTypes});function onComplete(typeConverters){var myTypeConverters=getTypeConverters(typeConverters);if(myTypeConverters.length!==myTypes.length){throwInternalError("Mismatched type converter count")}for(var i=0;i{if(registeredTypes.hasOwnProperty(dt)){typeConverters[i]=registeredTypes[dt]}else{unregisteredTypes.push(dt);if(!awaitingDependencies.hasOwnProperty(dt)){awaitingDependencies[dt]=[]}awaitingDependencies[dt].push(()=>{typeConverters[i]=registeredTypes[dt];++registered;if(registered===unregisteredTypes.length){onComplete(typeConverters)}})}});if(0===unregisteredTypes.length){onComplete(typeConverters)}};function sharedRegisterType(rawType,registeredInstance,options={}){var name=registeredInstance.name;if(!rawType){throwBindingError(`type "${name}" must have a positive integer typeid pointer`)}if(registeredTypes.hasOwnProperty(rawType)){if(options.ignoreDuplicateRegistrations){return}else{throwBindingError(`Cannot register type '${name}' twice`)}}registeredTypes[rawType]=registeredInstance;delete typeDependencies[rawType];if(awaitingDependencies.hasOwnProperty(rawType)){var callbacks=awaitingDependencies[rawType];delete awaitingDependencies[rawType];callbacks.forEach(cb=>cb())}}function registerType(rawType,registeredInstance,options={}){if(!("argPackAdvance"in registeredInstance)){throw new TypeError("registerType registeredInstance requires argPackAdvance")}return sharedRegisterType(rawType,registeredInstance,options)}var GenericWireTypeSize=8;var __embind_register_bool=(rawType,name,trueValue,falseValue)=>{name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":function(wt){return!!wt},"toWireType":function(destructors,o){return o?trueValue:falseValue},"argPackAdvance":GenericWireTypeSize,"readValueFromPointer":function(pointer){return this["fromWireType"](GROWABLE_HEAP_U8()[pointer])},destructorFunction:null})};function handleAllocatorInit(){Object.assign(HandleAllocator.prototype,{get(id){return this.allocated[id]},has(id){return this.allocated[id]!==undefined},allocate(handle){var id=this.freelist.pop()||this.allocated.length;this.allocated[id]=handle;return id},free(id){this.allocated[id]=undefined;this.freelist.push(id)}})}function HandleAllocator(){this.allocated=[undefined];this.freelist=[]}var emval_handles=new HandleAllocator;var __emval_decref=handle=>{if(handle>=emval_handles.reserved&&0===--emval_handles.get(handle).refcount){emval_handles.free(handle)}};var count_emval_handles=()=>{var count=0;for(var i=emval_handles.reserved;i{emval_handles.allocated.push({value:undefined},{value:null},{value:true},{value:false});emval_handles.reserved=emval_handles.allocated.length;Module["count_emval_handles"]=count_emval_handles};var Emval={toValue:handle=>{if(!handle){throwBindingError("Cannot use deleted val. handle = "+handle)}return emval_handles.get(handle).value},toHandle:value=>{switch(value){case undefined:return 1;case null:return 2;case true:return 3;case false:return 4;default:{return emval_handles.allocate({refcount:1,value:value})}}}};function simpleReadValueFromPointer(pointer){return this["fromWireType"](GROWABLE_HEAP_I32()[pointer>>2])}var __embind_register_emval=(rawType,name)=>{name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":handle=>{var rv=Emval.toValue(handle);__emval_decref(handle);return rv},"toWireType":(destructors,value)=>Emval.toHandle(value),"argPackAdvance":GenericWireTypeSize,"readValueFromPointer":simpleReadValueFromPointer,destructorFunction:null})};var floatReadValueFromPointer=(name,width)=>{switch(width){case 4:return function(pointer){return this["fromWireType"](GROWABLE_HEAP_F32()[pointer>>2])};case 8:return function(pointer){return this["fromWireType"](GROWABLE_HEAP_F64()[pointer>>3])};default:throw new TypeError(`invalid float width (${width}): ${name}`)}};var __embind_register_float=(rawType,name,size)=>{name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":value=>value,"toWireType":(destructors,value)=>value,"argPackAdvance":GenericWireTypeSize,"readValueFromPointer":floatReadValueFromPointer(name,size),destructorFunction:null})};var char_0=48;var char_9=57;var makeLegalFunctionName=name=>{if(undefined===name){return"_unknown"}name=name.replace(/[^a-zA-Z0-9_]/g,"$");var f=name.charCodeAt(0);if(f>=char_0&&f<=char_9){return`_${name}`}return name};var runDestructors=destructors=>{while(destructors.length){var ptr=destructors.pop();var del=destructors.pop();del(ptr)}};function createNamedFunction(name,body){name=makeLegalFunctionName(name);return{[name]:function(){return body.apply(this,arguments)}}[name]}function newFunc(constructor,argumentList){if(!(constructor instanceof Function)){throw new TypeError(`new_ called with constructor type ${typeof constructor} which is not a function`)}var dummy=createNamedFunction(constructor.name||"unknownFunctionName",function(){});dummy.prototype=constructor.prototype;var obj=new dummy;var r=constructor.apply(obj,argumentList);return r instanceof Object?r:obj}function craftInvokerFunction(humanName,argTypes,classType,cppInvokerFunc,cppTargetFunc,isAsync){var argCount=argTypes.length;if(argCount<2){throwBindingError("argTypes array size mismatch! Must at least get return value and 'this' types!")}var isClassMethodFunc=argTypes[1]!==null&&classType!==null;var needsDestructorStack=false;for(var i=1;i0?", ":"")+argsListWired}invokerFnBody+=(returns||isAsync?"var rv = ":"")+"invoker(fn"+(argsListWired.length>0?", ":"")+argsListWired+");\n";if(needsDestructorStack){invokerFnBody+="runDestructors(destructors);\n"}else{for(var i=isClassMethodFunc?1:2;i{if(undefined===proto[methodName].overloadTable){var prevFunc=proto[methodName];proto[methodName]=function(){if(!proto[methodName].overloadTable.hasOwnProperty(arguments.length)){throwBindingError(`Function '${humanName}' called with an invalid number of arguments (${arguments.length}) - expects one of (${proto[methodName].overloadTable})!`)}return proto[methodName].overloadTable[arguments.length].apply(this,arguments)};proto[methodName].overloadTable=[];proto[methodName].overloadTable[prevFunc.argCount]=prevFunc}};var exposePublicSymbol=(name,value,numArguments)=>{if(Module.hasOwnProperty(name)){if(undefined===numArguments||undefined!==Module[name].overloadTable&&undefined!==Module[name].overloadTable[numArguments]){throwBindingError(`Cannot register public name '${name}' twice`)}ensureOverloadTable(Module,name,name);if(Module.hasOwnProperty(numArguments)){throwBindingError(`Cannot register multiple overloads of a function with the same number of arguments (${numArguments})!`)}Module[name].overloadTable[numArguments]=value}else{Module[name]=value;if(undefined!==numArguments){Module[name].numArguments=numArguments}}};var heap32VectorToArray=(count,firstElement)=>{var array=[];for(var i=0;i>2])}return array};var replacePublicSymbol=(name,value,numArguments)=>{if(!Module.hasOwnProperty(name)){throwInternalError("Replacing nonexistant public symbol")}if(undefined!==Module[name].overloadTable&&undefined!==numArguments){Module[name].overloadTable[numArguments]=value}else{Module[name]=value;Module[name].argCount=numArguments}};var dynCallLegacy=(sig,ptr,args)=>{var f=Module["dynCall_"+sig];return args&&args.length?f.apply(null,[ptr].concat(args)):f.call(null,ptr)};var dynCall=(sig,ptr,args)=>{if(sig.includes("j")){return dynCallLegacy(sig,ptr,args)}var rtn=getWasmTableEntry(ptr).apply(null,args);return rtn};var getDynCaller=(sig,ptr)=>{var argCache=[];return function(){argCache.length=0;Object.assign(argCache,arguments);return dynCall(sig,ptr,argCache)}};var embind__requireFunction=(signature,rawFunction)=>{signature=readLatin1String(signature);function makeDynCaller(){if(signature.includes("j")){return getDynCaller(signature,rawFunction)}return getWasmTableEntry(rawFunction)}var fp=makeDynCaller();if(typeof fp!="function"){throwBindingError(`unknown function pointer with signature ${signature}: ${rawFunction}`)}return fp};var extendError=(baseErrorType,errorName)=>{var errorClass=createNamedFunction(errorName,function(message){this.name=errorName;this.message=message;var stack=new Error(message).stack;if(stack!==undefined){this.stack=this.toString()+"\n"+stack.replace(/^Error(:[^\n]*)?\n/,"")}});errorClass.prototype=Object.create(baseErrorType.prototype);errorClass.prototype.constructor=errorClass;errorClass.prototype.toString=function(){if(this.message===undefined){return this.name}else{return`${this.name}: ${this.message}`}};return errorClass};var UnboundTypeError=undefined;var getTypeName=type=>{var ptr=___getTypeName(type);var rv=readLatin1String(ptr);_free(ptr);return rv};var throwUnboundTypeError=(message,types)=>{var unboundTypes=[];var seen={};function visit(type){if(seen[type]){return}if(registeredTypes[type]){return}if(typeDependencies[type]){typeDependencies[type].forEach(visit);return}unboundTypes.push(type);seen[type]=true}types.forEach(visit);throw new UnboundTypeError(`${message}: `+unboundTypes.map(getTypeName).join([", "]))};var __embind_register_function=(name,argCount,rawArgTypesAddr,signature,rawInvoker,fn,isAsync)=>{var argTypes=heap32VectorToArray(argCount,rawArgTypesAddr);name=readLatin1String(name);rawInvoker=embind__requireFunction(signature,rawInvoker);exposePublicSymbol(name,function(){throwUnboundTypeError(`Cannot call ${name} due to unbound types`,argTypes)},argCount-1);whenDependentTypesAreResolved([],argTypes,function(argTypes){var invokerArgsArray=[argTypes[0],null].concat(argTypes.slice(1));replacePublicSymbol(name,craftInvokerFunction(name,invokerArgsArray,null,rawInvoker,fn,isAsync),argCount-1);return[]})};var integerReadValueFromPointer=(name,width,signed)=>{switch(width){case 1:return signed?pointer=>GROWABLE_HEAP_I8()[pointer>>0]:pointer=>GROWABLE_HEAP_U8()[pointer>>0];case 2:return signed?pointer=>GROWABLE_HEAP_I16()[pointer>>1]:pointer=>GROWABLE_HEAP_U16()[pointer>>1];case 4:return signed?pointer=>GROWABLE_HEAP_I32()[pointer>>2]:pointer=>GROWABLE_HEAP_U32()[pointer>>2];default:throw new TypeError(`invalid integer width (${width}): ${name}`)}};var __embind_register_integer=(primitiveType,name,size,minRange,maxRange)=>{name=readLatin1String(name);if(maxRange===-1){maxRange=4294967295}var fromWireType=value=>value;if(minRange===0){var bitshift=32-8*size;fromWireType=value=>value<>>bitshift}var isUnsignedType=name.includes("unsigned");var checkAssertions=(value,toTypeName)=>{};var toWireType;if(isUnsignedType){toWireType=function(destructors,value){checkAssertions(value,this.name);return value>>>0}}else{toWireType=function(destructors,value){checkAssertions(value,this.name);return value}}registerType(primitiveType,{name:name,"fromWireType":fromWireType,"toWireType":toWireType,"argPackAdvance":GenericWireTypeSize,"readValueFromPointer":integerReadValueFromPointer(name,size,minRange!==0),destructorFunction:null})};var __embind_register_memory_view=(rawType,dataTypeIndex,name)=>{var typeMapping=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array];var TA=typeMapping[dataTypeIndex];function decodeMemoryView(handle){var size=GROWABLE_HEAP_U32()[handle>>2];var data=GROWABLE_HEAP_U32()[handle+4>>2];return new TA(GROWABLE_HEAP_I8().buffer,data,size)}name=readLatin1String(name);registerType(rawType,{name:name,"fromWireType":decodeMemoryView,"argPackAdvance":GenericWireTypeSize,"readValueFromPointer":decodeMemoryView},{ignoreDuplicateRegistrations:true})};function readPointer(pointer){return this["fromWireType"](GROWABLE_HEAP_U32()[pointer>>2])}var stringToUTF8=(str,outPtr,maxBytesToWrite)=>stringToUTF8Array(str,GROWABLE_HEAP_U8(),outPtr,maxBytesToWrite);var __embind_register_std_string=(rawType,name)=>{name=readLatin1String(name);var stdStringIsUTF8=name==="std::string";registerType(rawType,{name:name,"fromWireType":value=>{var length=GROWABLE_HEAP_U32()[value>>2];var payload=value+4;var str;if(stdStringIsUTF8){var decodeStartPtr=payload;for(var i=0;i<=length;++i){var currentBytePtr=payload+i;if(i==length||GROWABLE_HEAP_U8()[currentBytePtr]==0){var maxRead=currentBytePtr-decodeStartPtr;var stringSegment=UTF8ToString(decodeStartPtr,maxRead);if(str===undefined){str=stringSegment}else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+1}}}else{var a=new Array(length);for(var i=0;i{if(value instanceof ArrayBuffer){value=new Uint8Array(value)}var length;var valueIsOfTypeString=typeof value=="string";if(!(valueIsOfTypeString||value instanceof Uint8Array||value instanceof Uint8ClampedArray||value instanceof Int8Array)){throwBindingError("Cannot pass non-string to std::string")}if(stdStringIsUTF8&&valueIsOfTypeString){length=lengthBytesUTF8(value)}else{length=value.length}var base=_malloc(4+length+1);var ptr=base+4;GROWABLE_HEAP_U32()[base>>2]=length;if(stdStringIsUTF8&&valueIsOfTypeString){stringToUTF8(value,ptr,length+1)}else{if(valueIsOfTypeString){for(var i=0;i255){_free(ptr);throwBindingError("String has UTF-16 code units that do not fit in 8 bits")}GROWABLE_HEAP_U8()[ptr+i]=charCode}}else{for(var i=0;i_free(ptr)})};var UTF16Decoder=typeof TextDecoder!="undefined"?new TextDecoder("utf-16le"):undefined;var UTF16ToString=(ptr,maxBytesToRead)=>{var endPtr=ptr;var idx=endPtr>>1;var maxIdx=idx+maxBytesToRead/2;while(!(idx>=maxIdx)&&GROWABLE_HEAP_U16()[idx])++idx;endPtr=idx<<1;if(endPtr-ptr>32&&UTF16Decoder)return UTF16Decoder.decode(GROWABLE_HEAP_U8().slice(ptr,endPtr));var str="";for(var i=0;!(i>=maxBytesToRead/2);++i){var codeUnit=GROWABLE_HEAP_I16()[ptr+i*2>>1];if(codeUnit==0)break;str+=String.fromCharCode(codeUnit)}return str};var stringToUTF16=(str,outPtr,maxBytesToWrite)=>{if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<2)return 0;maxBytesToWrite-=2;var startPtr=outPtr;var numCharsToWrite=maxBytesToWrite>1]=codeUnit;outPtr+=2}GROWABLE_HEAP_I16()[outPtr>>1]=0;return outPtr-startPtr};var lengthBytesUTF16=str=>str.length*2;var UTF32ToString=(ptr,maxBytesToRead)=>{var i=0;var str="";while(!(i>=maxBytesToRead/4)){var utf32=GROWABLE_HEAP_I32()[ptr+i*4>>2];if(utf32==0)break;++i;if(utf32>=65536){var ch=utf32-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}else{str+=String.fromCharCode(utf32)}}return str};var stringToUTF32=(str,outPtr,maxBytesToWrite)=>{if(maxBytesToWrite===undefined){maxBytesToWrite=2147483647}if(maxBytesToWrite<4)return 0;var startPtr=outPtr;var endPtr=startPtr+maxBytesToWrite-4;for(var i=0;i=55296&&codeUnit<=57343){var trailSurrogate=str.charCodeAt(++i);codeUnit=65536+((codeUnit&1023)<<10)|trailSurrogate&1023}GROWABLE_HEAP_I32()[outPtr>>2]=codeUnit;outPtr+=4;if(outPtr+4>endPtr)break}GROWABLE_HEAP_I32()[outPtr>>2]=0;return outPtr-startPtr};var lengthBytesUTF32=str=>{var len=0;for(var i=0;i=55296&&codeUnit<=57343)++i;len+=4}return len};var __embind_register_std_wstring=(rawType,charSize,name)=>{name=readLatin1String(name);var decodeString,encodeString,getHeap,lengthBytesUTF,shift;if(charSize===2){decodeString=UTF16ToString;encodeString=stringToUTF16;lengthBytesUTF=lengthBytesUTF16;getHeap=()=>GROWABLE_HEAP_U16();shift=1}else if(charSize===4){decodeString=UTF32ToString;encodeString=stringToUTF32;lengthBytesUTF=lengthBytesUTF32;getHeap=()=>GROWABLE_HEAP_U32();shift=2}registerType(rawType,{name:name,"fromWireType":value=>{var length=GROWABLE_HEAP_U32()[value>>2];var HEAP=getHeap();var str;var decodeStartPtr=value+4;for(var i=0;i<=length;++i){var currentBytePtr=value+4+i*charSize;if(i==length||HEAP[currentBytePtr>>shift]==0){var maxReadBytes=currentBytePtr-decodeStartPtr;var stringSegment=decodeString(decodeStartPtr,maxReadBytes);if(str===undefined){str=stringSegment}else{str+=String.fromCharCode(0);str+=stringSegment}decodeStartPtr=currentBytePtr+charSize}}_free(value);return str},"toWireType":(destructors,value)=>{if(!(typeof value=="string")){throwBindingError(`Cannot pass non-string to C++ string type ${name}`)}var length=lengthBytesUTF(value);var ptr=_malloc(4+length+charSize);GROWABLE_HEAP_U32()[ptr>>2]=length>>shift;encodeString(value,ptr+4,length+charSize);if(destructors!==null){destructors.push(_free,ptr)}return ptr},"argPackAdvance":GenericWireTypeSize,"readValueFromPointer":simpleReadValueFromPointer,destructorFunction:ptr=>_free(ptr)})};var __embind_register_void=(rawType,name)=>{name=readLatin1String(name);registerType(rawType,{isVoid:true,name:name,"argPackAdvance":0,"fromWireType":()=>undefined,"toWireType":(destructors,o)=>undefined})};var nowIsMonotonic=true;var __emscripten_get_now_is_monotonic=()=>nowIsMonotonic;var maybeExit=()=>{if(!keepRuntimeAlive()){try{if(ENVIRONMENT_IS_PTHREAD)__emscripten_thread_exit(EXITSTATUS);else _exit(EXITSTATUS)}catch(e){handleException(e)}}};var callUserCallback=func=>{if(ABORT){return}try{func();maybeExit()}catch(e){handleException(e)}};var __emscripten_thread_mailbox_await=pthread_ptr=>{if(typeof Atomics.waitAsync==="function"){var wait=Atomics.waitAsync(GROWABLE_HEAP_I32(),pthread_ptr>>2,pthread_ptr);wait.value.then(checkMailbox);var waitingAsync=pthread_ptr+128;Atomics.store(GROWABLE_HEAP_I32(),waitingAsync>>2,1)}};Module["__emscripten_thread_mailbox_await"]=__emscripten_thread_mailbox_await;var checkMailbox=()=>{var pthread_ptr=_pthread_self();if(pthread_ptr){__emscripten_thread_mailbox_await(pthread_ptr);callUserCallback(()=>__emscripten_check_mailbox())}};Module["checkMailbox"]=checkMailbox;var __emscripten_notify_mailbox_postmessage=(targetThreadId,currThreadId,mainThreadId)=>{if(targetThreadId==currThreadId){setTimeout(()=>checkMailbox())}else if(ENVIRONMENT_IS_PTHREAD){postMessage({"targetThread":targetThreadId,"cmd":"checkMailbox"})}else{var worker=PThread.pthreads[targetThreadId];if(!worker){return}worker.postMessage({"cmd":"checkMailbox"})}};var withStackSave=f=>{var stack=stackSave();var ret=f();stackRestore(stack);return ret};var proxyToMainThread=function(index,sync){var numCallArgs=arguments.length-2;var outerArgs=arguments;return withStackSave(()=>{var serializedNumCallArgs=numCallArgs;var args=stackAlloc(serializedNumCallArgs*8);var b=args>>3;for(var i=0;i{proxiedJSCallArgs.length=numCallArgs;var b=args>>3;for(var i=0;i{if(ENVIRONMENT_IS_NODE){PThread.pthreads[thread].ref()}};var requireRegisteredType=(rawType,humanName)=>{var impl=registeredTypes[rawType];if(undefined===impl){throwBindingError(humanName+" has unknown type "+getTypeName(rawType))}return impl};var __emval_as=(handle,returnType,destructorsRef)=>{handle=Emval.toValue(handle);returnType=requireRegisteredType(returnType,"emval::as");var destructors=[];var rd=Emval.toHandle(destructors);GROWABLE_HEAP_U32()[destructorsRef>>2]=rd;return returnType["toWireType"](destructors,handle)};var emval_symbols={};var getStringOrSymbol=address=>{var symbol=emval_symbols[address];if(symbol===undefined){return readLatin1String(address)}return symbol};var emval_methodCallers=[];var __emval_call_void_method=(caller,handle,methodName,args)=>{caller=emval_methodCallers[caller];handle=Emval.toValue(handle);methodName=getStringOrSymbol(methodName);caller(handle,methodName,null,args)};var emval_addMethodCaller=caller=>{var id=emval_methodCallers.length;emval_methodCallers.push(caller);return id};var emval_lookupTypes=(argCount,argTypes)=>{var a=new Array(argCount);for(var i=0;i>2],"parameter "+i)}return a};var emval_registeredMethods=[];var __emval_get_method_caller=(argCount,argTypes)=>{var types=emval_lookupTypes(argCount,argTypes);var retType=types[0];var signatureName=retType.name+"_$"+types.slice(1).map(function(t){return t.name}).join("_")+"$";var returnId=emval_registeredMethods[signatureName];if(returnId!==undefined){return returnId}var params=["retType"];var args=[retType];var argsList="";for(var i=0;i{name=getStringOrSymbol(name);return Emval.toHandle(Module[name])};var __emval_get_property=(handle,key)=>{handle=Emval.toValue(handle);key=Emval.toValue(key);return Emval.toHandle(handle[key])};var __emval_incref=handle=>{if(handle>4){emval_handles.get(handle).refcount+=1}};var craftEmvalAllocator=argCount=>{var argsList="";for(var i=0;iGROWABLE_HEAP_U32();var functionBody="return function emval_allocator_"+argCount+"(constructor, argTypes, args) {\n"+" var HEAPU32 = getMemory();\n";for(var i=0;i>2)], 'parameter "+i+"');\n"+"var arg"+i+" = argType"+i+".readValueFromPointer(args);\n"+"args += argType"+i+"['argPackAdvance'];\n"+"argTypes += 4;\n"}functionBody+="var obj = new constructor("+argsList+");\n"+"return valueToHandle(obj);\n"+"}\n";return new Function("requireRegisteredType","Module","valueToHandle","getMemory",functionBody)(requireRegisteredType,Module,Emval.toHandle,getMemory)};var emval_newers={};var __emval_new=(handle,argCount,argTypes,args)=>{handle=Emval.toValue(handle);var newer=emval_newers[argCount];if(!newer){newer=craftEmvalAllocator(argCount);emval_newers[argCount]=newer}return newer(handle,argTypes,args)};var __emval_new_cstring=v=>Emval.toHandle(getStringOrSymbol(v));var __emval_run_destructors=handle=>{var destructors=Emval.toValue(handle);runDestructors(destructors);__emval_decref(handle)};var _abort=()=>{abort("")};var warnOnce=text=>{if(!warnOnce.shown)warnOnce.shown={};if(!warnOnce.shown[text]){warnOnce.shown[text]=1;if(ENVIRONMENT_IS_NODE)text="warning: "+text;err(text)}};var _emscripten_check_blocking_allowed=()=>{};var runtimeKeepalivePush=()=>{runtimeKeepaliveCounter+=1};var _emscripten_exit_with_live_runtime=()=>{runtimeKeepalivePush();throw"unwind"};var getHeapMax=()=>2147483648;var _emscripten_get_heap_max=()=>getHeapMax();var _emscripten_get_now;_emscripten_get_now=()=>performance.timeOrigin+performance.now();var _emscripten_num_logical_cores=()=>{if(ENVIRONMENT_IS_NODE)return require("os").cpus().length;return navigator["hardwareConcurrency"]};var growMemory=size=>{var b=wasmMemory.buffer;var pages=(size-b.byteLength+65535)/65536;try{wasmMemory.grow(pages);updateMemoryViews();return 1}catch(e){}};var _emscripten_resize_heap=requestedSize=>{var oldSize=GROWABLE_HEAP_U8().length;requestedSize>>>=0;if(requestedSize<=oldSize){return false}var maxHeapSize=getHeapMax();if(requestedSize>maxHeapSize){return false}var alignUp=(x,multiple)=>x+(multiple-x%multiple)%multiple;for(var cutDown=1;cutDown<=4;cutDown*=2){var overGrownHeapSize=oldSize*(1+.2/cutDown);overGrownHeapSize=Math.min(overGrownHeapSize,requestedSize+100663296);var newSize=Math.min(maxHeapSize,alignUp(Math.max(requestedSize,overGrownHeapSize),65536));var replacement=growMemory(newSize);if(replacement){return true}}return false};var ENV={};var getExecutableName=()=>thisProgram||"./this.program";var getEnvStrings=()=>{if(!getEnvStrings.strings){var lang=(typeof navigator=="object"&&navigator.languages&&navigator.languages[0]||"C").replace("-","_")+".UTF-8";var env={"USER":"web_user","LOGNAME":"web_user","PATH":"/","PWD":"/","HOME":"/home/web_user","LANG":lang,"_":getExecutableName()};for(var x in ENV){if(ENV[x]===undefined)delete env[x];else env[x]=ENV[x]}var strings=[];for(var x in env){strings.push(`${x}=${env[x]}`)}getEnvStrings.strings=strings}return getEnvStrings.strings};var stringToAscii=(str,buffer)=>{for(var i=0;i>0]=str.charCodeAt(i)}GROWABLE_HEAP_I8()[buffer>>0]=0};var _environ_get=function(__environ,environ_buf){if(ENVIRONMENT_IS_PTHREAD)return proxyToMainThread(6,1,__environ,environ_buf);var bufSize=0;getEnvStrings().forEach((string,i)=>{var ptr=environ_buf+bufSize;GROWABLE_HEAP_U32()[__environ+i*4>>2]=ptr;stringToAscii(string,ptr);bufSize+=string.length+1});return 0};var _environ_sizes_get=function(penviron_count,penviron_buf_size){if(ENVIRONMENT_IS_PTHREAD)return proxyToMainThread(7,1,penviron_count,penviron_buf_size);var strings=getEnvStrings();GROWABLE_HEAP_U32()[penviron_count>>2]=strings.length;var bufSize=0;strings.forEach(string=>bufSize+=string.length+1);GROWABLE_HEAP_U32()[penviron_buf_size>>2]=bufSize;return 0};function _fd_close(fd){if(ENVIRONMENT_IS_PTHREAD)return proxyToMainThread(8,1,fd);try{var stream=SYSCALLS.getStreamFromFD(fd);FS.close(stream);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var doReadv=(stream,iov,iovcnt,offset)=>{var ret=0;for(var i=0;i>2];var len=GROWABLE_HEAP_U32()[iov+4>>2];iov+=8;var curr=FS.read(stream,GROWABLE_HEAP_I8(),ptr,len,offset);if(curr<0)return-1;ret+=curr;if(curr>2]=num;return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var convertI32PairToI53Checked=(lo,hi)=>hi+2097152>>>0<4194305-!!lo?(lo>>>0)+hi*4294967296:NaN;function _fd_seek(fd,offset_low,offset_high,whence,newOffset){if(ENVIRONMENT_IS_PTHREAD)return proxyToMainThread(10,1,fd,offset_low,offset_high,whence,newOffset);var offset=convertI32PairToI53Checked(offset_low,offset_high);try{if(isNaN(offset))return 61;var stream=SYSCALLS.getStreamFromFD(fd);FS.llseek(stream,offset,whence);tempI64=[stream.position>>>0,(tempDouble=stream.position,+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],GROWABLE_HEAP_I32()[newOffset>>2]=tempI64[0],GROWABLE_HEAP_I32()[newOffset+4>>2]=tempI64[1];if(stream.getdents&&offset===0&&whence===0)stream.getdents=null;return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var doWritev=(stream,iov,iovcnt,offset)=>{var ret=0;for(var i=0;i>2];var len=GROWABLE_HEAP_U32()[iov+4>>2];iov+=8;var curr=FS.write(stream,GROWABLE_HEAP_I8(),ptr,len,offset);if(curr<0)return-1;ret+=curr;if(typeof offset!=="undefined"){offset+=curr}}return ret};function _fd_write(fd,iov,iovcnt,pnum){if(ENVIRONMENT_IS_PTHREAD)return proxyToMainThread(11,1,fd,iov,iovcnt,pnum);try{var stream=SYSCALLS.getStreamFromFD(fd);var num=doWritev(stream,iov,iovcnt);GROWABLE_HEAP_U32()[pnum>>2]=num;return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var isLeapYear=year=>year%4===0&&(year%100!==0||year%400===0);var arraySum=(array,index)=>{var sum=0;for(var i=0;i<=index;sum+=array[i++]){}return sum};var MONTH_DAYS_LEAP=[31,29,31,30,31,30,31,31,30,31,30,31];var MONTH_DAYS_REGULAR=[31,28,31,30,31,30,31,31,30,31,30,31];var addDays=(date,days)=>{var newDate=new Date(date.getTime());while(days>0){var leap=isLeapYear(newDate.getFullYear());var currentMonth=newDate.getMonth();var daysInCurrentMonth=(leap?MONTH_DAYS_LEAP:MONTH_DAYS_REGULAR)[currentMonth];if(days>daysInCurrentMonth-newDate.getDate()){days-=daysInCurrentMonth-newDate.getDate()+1;newDate.setDate(1);if(currentMonth<11){newDate.setMonth(currentMonth+1)}else{newDate.setMonth(0);newDate.setFullYear(newDate.getFullYear()+1)}}else{newDate.setDate(newDate.getDate()+days);return newDate}}return newDate};var writeArrayToMemory=(array,buffer)=>{GROWABLE_HEAP_I8().set(array,buffer)};var _strftime=(s,maxsize,format,tm)=>{var tm_zone=GROWABLE_HEAP_U32()[tm+40>>2];var date={tm_sec:GROWABLE_HEAP_I32()[tm>>2],tm_min:GROWABLE_HEAP_I32()[tm+4>>2],tm_hour:GROWABLE_HEAP_I32()[tm+8>>2],tm_mday:GROWABLE_HEAP_I32()[tm+12>>2],tm_mon:GROWABLE_HEAP_I32()[tm+16>>2],tm_year:GROWABLE_HEAP_I32()[tm+20>>2],tm_wday:GROWABLE_HEAP_I32()[tm+24>>2],tm_yday:GROWABLE_HEAP_I32()[tm+28>>2],tm_isdst:GROWABLE_HEAP_I32()[tm+32>>2],tm_gmtoff:GROWABLE_HEAP_I32()[tm+36>>2],tm_zone:tm_zone?UTF8ToString(tm_zone):""};var pattern=UTF8ToString(format);var EXPANSION_RULES_1={"%c":"%a %b %d %H:%M:%S %Y","%D":"%m/%d/%y","%F":"%Y-%m-%d","%h":"%b","%r":"%I:%M:%S %p","%R":"%H:%M","%T":"%H:%M:%S","%x":"%m/%d/%y","%X":"%H:%M:%S","%Ec":"%c","%EC":"%C","%Ex":"%m/%d/%y","%EX":"%H:%M:%S","%Ey":"%y","%EY":"%Y","%Od":"%d","%Oe":"%e","%OH":"%H","%OI":"%I","%Om":"%m","%OM":"%M","%OS":"%S","%Ou":"%u","%OU":"%U","%OV":"%V","%Ow":"%w","%OW":"%W","%Oy":"%y"};for(var rule in EXPANSION_RULES_1){pattern=pattern.replace(new RegExp(rule,"g"),EXPANSION_RULES_1[rule])}var WEEKDAYS=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];var MONTHS=["January","February","March","April","May","June","July","August","September","October","November","December"];function leadingSomething(value,digits,character){var str=typeof value=="number"?value.toString():value||"";while(str.length0?1:0}var compare;if((compare=sgn(date1.getFullYear()-date2.getFullYear()))===0){if((compare=sgn(date1.getMonth()-date2.getMonth()))===0){compare=sgn(date1.getDate()-date2.getDate())}}return compare}function getFirstWeekStartDate(janFourth){switch(janFourth.getDay()){case 0:return new Date(janFourth.getFullYear()-1,11,29);case 1:return janFourth;case 2:return new Date(janFourth.getFullYear(),0,3);case 3:return new Date(janFourth.getFullYear(),0,2);case 4:return new Date(janFourth.getFullYear(),0,1);case 5:return new Date(janFourth.getFullYear()-1,11,31);case 6:return new Date(janFourth.getFullYear()-1,11,30)}}function getWeekBasedYear(date){var thisDate=addDays(new Date(date.tm_year+1900,0,1),date.tm_yday);var janFourthThisYear=new Date(thisDate.getFullYear(),0,4);var janFourthNextYear=new Date(thisDate.getFullYear()+1,0,4);var firstWeekStartThisYear=getFirstWeekStartDate(janFourthThisYear);var firstWeekStartNextYear=getFirstWeekStartDate(janFourthNextYear);if(compareByDay(firstWeekStartThisYear,thisDate)<=0){if(compareByDay(firstWeekStartNextYear,thisDate)<=0){return thisDate.getFullYear()+1}return thisDate.getFullYear()}return thisDate.getFullYear()-1}var EXPANSION_RULES_2={"%a":date=>WEEKDAYS[date.tm_wday].substring(0,3),"%A":date=>WEEKDAYS[date.tm_wday],"%b":date=>MONTHS[date.tm_mon].substring(0,3),"%B":date=>MONTHS[date.tm_mon],"%C":date=>{var year=date.tm_year+1900;return leadingNulls(year/100|0,2)},"%d":date=>leadingNulls(date.tm_mday,2),"%e":date=>leadingSomething(date.tm_mday,2," "),"%g":date=>getWeekBasedYear(date).toString().substring(2),"%G":date=>getWeekBasedYear(date),"%H":date=>leadingNulls(date.tm_hour,2),"%I":date=>{var twelveHour=date.tm_hour;if(twelveHour==0)twelveHour=12;else if(twelveHour>12)twelveHour-=12;return leadingNulls(twelveHour,2)},"%j":date=>leadingNulls(date.tm_mday+arraySum(isLeapYear(date.tm_year+1900)?MONTH_DAYS_LEAP:MONTH_DAYS_REGULAR,date.tm_mon-1),3),"%m":date=>leadingNulls(date.tm_mon+1,2),"%M":date=>leadingNulls(date.tm_min,2),"%n":()=>"\n","%p":date=>{if(date.tm_hour>=0&&date.tm_hour<12){return"AM"}return"PM"},"%S":date=>leadingNulls(date.tm_sec,2),"%t":()=>"\t","%u":date=>date.tm_wday||7,"%U":date=>{var days=date.tm_yday+7-date.tm_wday;return leadingNulls(Math.floor(days/7),2)},"%V":date=>{var val=Math.floor((date.tm_yday+7-(date.tm_wday+6)%7)/7);if((date.tm_wday+371-date.tm_yday-2)%7<=2){val++}if(!val){val=52;var dec31=(date.tm_wday+7-date.tm_yday-1)%7;if(dec31==4||dec31==5&&isLeapYear(date.tm_year%400-1)){val++}}else if(val==53){var jan1=(date.tm_wday+371-date.tm_yday)%7;if(jan1!=4&&(jan1!=3||!isLeapYear(date.tm_year)))val=1}return leadingNulls(val,2)},"%w":date=>date.tm_wday,"%W":date=>{var days=date.tm_yday+7-(date.tm_wday+6)%7;return leadingNulls(Math.floor(days/7),2)},"%y":date=>(date.tm_year+1900).toString().substring(2),"%Y":date=>date.tm_year+1900,"%z":date=>{var off=date.tm_gmtoff;var ahead=off>=0;off=Math.abs(off)/60;off=off/60*100+off%60;return(ahead?"+":"-")+String("0000"+off).slice(-4)},"%Z":date=>date.tm_zone,"%%":()=>"%"};pattern=pattern.replace(/%%/g,"\0\0");for(var rule in EXPANSION_RULES_2){if(pattern.includes(rule)){pattern=pattern.replace(new RegExp(rule,"g"),EXPANSION_RULES_2[rule](date))}}pattern=pattern.replace(/\0\0/g,"%");var bytes=intArrayFromString(pattern,false);if(bytes.length>maxsize){return 0}writeArrayToMemory(bytes,s);return bytes.length-1};var _strftime_l=(s,maxsize,format,tm,loc)=>_strftime(s,maxsize,format,tm);PThread.init();var FSNode=function(parent,name,mode,rdev){if(!parent){parent=this}this.parent=parent;this.mount=parent.mount;this.mounted=null;this.id=FS.nextInode++;this.name=name;this.mode=mode;this.node_ops={};this.stream_ops={};this.rdev=rdev};var readMode=292|73;var writeMode=146;Object.defineProperties(FSNode.prototype,{read:{get:function(){return(this.mode&readMode)===readMode},set:function(val){val?this.mode|=readMode:this.mode&=~readMode}},write:{get:function(){return(this.mode&writeMode)===writeMode},set:function(val){val?this.mode|=writeMode:this.mode&=~writeMode}},isFolder:{get:function(){return FS.isDir(this.mode)}},isDevice:{get:function(){return FS.isChrdev(this.mode)}}});FS.FSNode=FSNode;FS.createPreloadedFile=FS_createPreloadedFile;FS.staticInit();Module["FS_createPath"]=FS.createPath;Module["FS_createDataFile"]=FS.createDataFile;Module["FS_createPreloadedFile"]=FS.createPreloadedFile;Module["FS_unlink"]=FS.unlink;Module["FS_createLazyFile"]=FS.createLazyFile;Module["FS_createDevice"]=FS.createDevice;embind_init_charCodes();BindingError=Module["BindingError"]=class BindingError extends Error{constructor(message){super(message);this.name="BindingError"}};InternalError=Module["InternalError"]=class InternalError extends Error{constructor(message){super(message);this.name="InternalError"}};handleAllocatorInit();init_emval();UnboundTypeError=Module["UnboundTypeError"]=extendError(Error,"UnboundTypeError");var proxiedFunctionTable=[_proc_exit,exitOnMainThread,pthreadCreateProxied,___syscall_fcntl64,___syscall_ioctl,___syscall_openat,_environ_get,_environ_sizes_get,_fd_close,_fd_read,_fd_seek,_fd_write];var wasmImports={d:___cxa_throw,K:___emscripten_init_main_thread_js,n:___emscripten_thread_cleanup,H:___pthread_create_js,r:___syscall_fcntl64,M:___syscall_ioctl,N:___syscall_openat,z:__embind_register_bigint,S:__embind_register_bool,R:__embind_register_emval,t:__embind_register_float,i:__embind_register_function,g:__embind_register_integer,c:__embind_register_memory_view,s:__embind_register_std_string,l:__embind_register_std_wstring,T:__embind_register_void,Q:__emscripten_get_now_is_monotonic,G:__emscripten_notify_mailbox_postmessage,I:__emscripten_receive_on_main_thread_js,J:__emscripten_thread_mailbox_await,P:__emscripten_thread_set_strongref,x:__emval_as,U:__emval_call_void_method,f:__emval_decref,V:__emval_get_method_caller,v:__emval_get_module_property,j:__emval_get_property,m:__emval_incref,u:__emval_new,k:__emval_new_cstring,w:__emval_run_destructors,h:_abort,o:_emscripten_check_blocking_allowed,O:_emscripten_exit_with_live_runtime,A:_emscripten_get_heap_max,e:_emscripten_get_now,B:_emscripten_num_logical_cores,F:_emscripten_resize_heap,D:_environ_get,E:_environ_sizes_get,b:_exit,p:_fd_close,L:_fd_read,y:_fd_seek,q:_fd_write,a:wasmMemory||Module["wasmMemory"],C:_strftime_l};var wasmExports=createWasm();var ___wasm_call_ctors=()=>(___wasm_call_ctors=wasmExports["W"])();var _malloc=a0=>(_malloc=wasmExports["Y"])(a0);var _free=a0=>(_free=wasmExports["Z"])(a0);var __emscripten_tls_init=Module["__emscripten_tls_init"]=()=>(__emscripten_tls_init=Module["__emscripten_tls_init"]=wasmExports["_"])();var _pthread_self=Module["_pthread_self"]=()=>(_pthread_self=Module["_pthread_self"]=wasmExports["$"])();var ___getTypeName=a0=>(___getTypeName=wasmExports["aa"])(a0);var __embind_initialize_bindings=Module["__embind_initialize_bindings"]=()=>(__embind_initialize_bindings=Module["__embind_initialize_bindings"]=wasmExports["ba"])();var ___errno_location=()=>(___errno_location=wasmExports["ca"])();var __emscripten_thread_init=Module["__emscripten_thread_init"]=(a0,a1,a2,a3,a4,a5)=>(__emscripten_thread_init=Module["__emscripten_thread_init"]=wasmExports["da"])(a0,a1,a2,a3,a4,a5);var __emscripten_thread_crashed=Module["__emscripten_thread_crashed"]=()=>(__emscripten_thread_crashed=Module["__emscripten_thread_crashed"]=wasmExports["ea"])();var _emscripten_main_thread_process_queued_calls=()=>(_emscripten_main_thread_process_queued_calls=wasmExports["emscripten_main_thread_process_queued_calls"])();var _emscripten_main_runtime_thread_id=()=>(_emscripten_main_runtime_thread_id=wasmExports["emscripten_main_runtime_thread_id"])();var __emscripten_run_on_main_thread_js=(a0,a1,a2,a3)=>(__emscripten_run_on_main_thread_js=wasmExports["fa"])(a0,a1,a2,a3);var __emscripten_thread_free_data=a0=>(__emscripten_thread_free_data=wasmExports["ga"])(a0);var __emscripten_thread_exit=Module["__emscripten_thread_exit"]=a0=>(__emscripten_thread_exit=Module["__emscripten_thread_exit"]=wasmExports["ha"])(a0);var __emscripten_check_mailbox=Module["__emscripten_check_mailbox"]=()=>(__emscripten_check_mailbox=Module["__emscripten_check_mailbox"]=wasmExports["ia"])();var _emscripten_stack_set_limits=(a0,a1)=>(_emscripten_stack_set_limits=wasmExports["ja"])(a0,a1);var stackSave=()=>(stackSave=wasmExports["ka"])();var stackRestore=a0=>(stackRestore=wasmExports["la"])(a0);var stackAlloc=a0=>(stackAlloc=wasmExports["ma"])(a0);var ___cxa_is_pointer_type=a0=>(___cxa_is_pointer_type=wasmExports["na"])(a0);var dynCall_jiji=Module["dynCall_jiji"]=(a0,a1,a2,a3,a4)=>(dynCall_jiji=Module["dynCall_jiji"]=wasmExports["oa"])(a0,a1,a2,a3,a4);var dynCall_viijii=Module["dynCall_viijii"]=(a0,a1,a2,a3,a4,a5,a6)=>(dynCall_viijii=Module["dynCall_viijii"]=wasmExports["pa"])(a0,a1,a2,a3,a4,a5,a6);var dynCall_iiiiij=Module["dynCall_iiiiij"]=(a0,a1,a2,a3,a4,a5,a6)=>(dynCall_iiiiij=Module["dynCall_iiiiij"]=wasmExports["qa"])(a0,a1,a2,a3,a4,a5,a6);var dynCall_iiiiijj=Module["dynCall_iiiiijj"]=(a0,a1,a2,a3,a4,a5,a6,a7,a8)=>(dynCall_iiiiijj=Module["dynCall_iiiiijj"]=wasmExports["ra"])(a0,a1,a2,a3,a4,a5,a6,a7,a8);var dynCall_iiiiiijj=Module["dynCall_iiiiiijj"]=(a0,a1,a2,a3,a4,a5,a6,a7,a8,a9)=>(dynCall_iiiiiijj=Module["dynCall_iiiiiijj"]=wasmExports["sa"])(a0,a1,a2,a3,a4,a5,a6,a7,a8,a9);function intArrayFromBase64(s){if(typeof ENVIRONMENT_IS_NODE!="undefined"&&ENVIRONMENT_IS_NODE){var buf=Buffer.from(s,"base64");return new Uint8Array(buf.buffer,buf.byteOffset,buf.length)}try{var decoded=atob(s);var bytes=new Uint8Array(decoded.length);for(var i=0;i0){return}if(ENVIRONMENT_IS_PTHREAD){readyPromiseResolve(Module);initRuntime();startWorker(Module);return}preRun();if(runDependencies>0){return}function doRun(){if(calledRun)return;calledRun=true;Module["calledRun"]=true;if(ABORT)return;initRuntime();readyPromiseResolve(Module);if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(function(){setTimeout(function(){Module["setStatus"]("")},1);doRun()},1)}else{doRun()}}if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}run(); + + + return moduleArg.ready +} + +); +})(); +if (typeof exports === 'object' && typeof module === 'object') + module.exports = whisper_factory; +else if (typeof define === 'function' && define['amd']) + define([], () => whisper_factory); diff --git a/sys/whisper.cpp/bindings/ruby/ext/.gitignore b/sys/whisper.cpp/bindings/ruby/ext/.gitignore new file mode 100644 index 0000000..9f9b7ab --- /dev/null +++ b/sys/whisper.cpp/bindings/ruby/ext/.gitignore @@ -0,0 +1,9 @@ +Makefile +ggml.c +ggml.h +ggml-alloc.c +ggml-alloc.h +whisper.bundle +whisper.cpp +whisper.h +dr_wav.h diff --git a/sys/whisper.cpp/bindings/ruby/ext/extconf.rb b/sys/whisper.cpp/bindings/ruby/ext/extconf.rb new file mode 100644 index 0000000..c736d30 --- /dev/null +++ b/sys/whisper.cpp/bindings/ruby/ext/extconf.rb @@ -0,0 +1,29 @@ +require 'mkmf' +system("cp #{File.join(File.dirname(__FILE__),'..','..','..','whisper.cpp')} .") +system("cp #{File.join(File.dirname(__FILE__),'..','..','..','whisper.h')} .") +system("cp #{File.join(File.dirname(__FILE__),'..','..','..','ggml.h')} .") +system("cp #{File.join(File.dirname(__FILE__),'..','..','..','ggml.c')} .") +system("cp #{File.join(File.dirname(__FILE__),'..','..','..','ggml-impl.h')} .") +system("cp #{File.join(File.dirname(__FILE__),'..','..','..','ggml-alloc.h')} .") +system("cp #{File.join(File.dirname(__FILE__),'..','..','..','ggml-alloc.c')} .") +system("cp #{File.join(File.dirname(__FILE__),'..','..','..','ggml-backend-impl.h')} .") +system("cp #{File.join(File.dirname(__FILE__),'..','..','..','ggml-backend.h')} .") +system("cp #{File.join(File.dirname(__FILE__),'..','..','..','ggml-backend.c')} .") +system("cp #{File.join(File.dirname(__FILE__),'..','..','..','ggml-quants.h')} .") +system("cp #{File.join(File.dirname(__FILE__),'..','..','..','ggml-quants.c')} .") +system("cp #{File.join(File.dirname(__FILE__),'..','..','..','examples','dr_wav.h')} .") + + +# need to use c++ compiler flags +$CXXFLAGS << ' -std=c++11' +# Set to true when building binary gems +if enable_config('static-stdlib', false) + $LDFLAGS << ' -static-libgcc -static-libstdc++' +end + +if enable_config('march-tune-native', false) + $CFLAGS << ' -march=native -mtune=native' + $CXXFLAGS << ' -march=native -mtune=native' +end + +create_makefile('whisper') diff --git a/sys/whisper.cpp/bindings/ruby/ext/ggml-backend-impl.h b/sys/whisper.cpp/bindings/ruby/ext/ggml-backend-impl.h new file mode 100644 index 0000000..211e3d4 --- /dev/null +++ b/sys/whisper.cpp/bindings/ruby/ext/ggml-backend-impl.h @@ -0,0 +1,87 @@ +#pragma once + +// ggml-backend internal header + +#include "ggml-backend.h" + +#ifdef __cplusplus +extern "C" { +#endif + + // + // Backend buffer + // + + typedef void * ggml_backend_buffer_context_t; + + struct ggml_backend_buffer_i { + void (*free_buffer) (ggml_backend_buffer_t buffer); + void * (*get_base) (ggml_backend_buffer_t buffer); // get base pointer + size_t (*get_alloc_size)(ggml_backend_buffer_t buffer, struct ggml_tensor * tensor); // pre-allocation callback + void (*init_tensor) (ggml_backend_buffer_t buffer, struct ggml_tensor * tensor); // post-allocation callback + void (*free_tensor) (ggml_backend_buffer_t buffer, struct ggml_tensor * tensor); // pre-free callback + }; + + struct ggml_backend_buffer { + struct ggml_backend_buffer_i iface; + + ggml_backend_t backend; + ggml_backend_buffer_context_t context; + + size_t size; + }; + + GGML_API ggml_backend_buffer_t ggml_backend_buffer_init( + struct ggml_backend * backend, + struct ggml_backend_buffer_i iface, + ggml_backend_buffer_context_t context, + size_t size); + + // + // Backend + // + + typedef void * ggml_backend_context_t; + + struct ggml_backend_i { + const char * (*get_name)(ggml_backend_t backend); + + void (*free)(ggml_backend_t backend); + + // buffer allocation + ggml_backend_buffer_t (*alloc_buffer)(ggml_backend_t backend, size_t size); + + // get buffer alignment + size_t (*get_alignment)(ggml_backend_t backend); + + // tensor data access + // these functions can be asynchronous, helper functions are provided for synchronous access that automatically call synchronize + void (*set_tensor_async)(ggml_backend_t backend, struct ggml_tensor * tensor, const void * data, size_t offset, size_t size); + void (*get_tensor_async)(ggml_backend_t backend, const struct ggml_tensor * tensor, void * data, size_t offset, size_t size); + void (*synchronize) (ggml_backend_t backend); + + // (optional) copy tensor between different backends, allow for single-copy tranfers + void (*cpy_tensor_from)(ggml_backend_t backend, struct ggml_tensor * src, struct ggml_tensor * dst); + void (*cpy_tensor_to) (ggml_backend_t backend, struct ggml_tensor * src, struct ggml_tensor * dst); + + // compute graph with a plan + ggml_backend_graph_plan_t (*graph_plan_create) (ggml_backend_t backend, struct ggml_cgraph * cgraph); + void (*graph_plan_free) (ggml_backend_t backend, ggml_backend_graph_plan_t plan); + void (*graph_plan_compute)(ggml_backend_t backend, ggml_backend_graph_plan_t plan); + + // compute graph without a plan + void (*graph_compute)(ggml_backend_t backend, struct ggml_cgraph * cgraph); + + // check if the backend supports an operation + bool (*supports_op)(ggml_backend_t backend, const struct ggml_tensor * op); + }; + + struct ggml_backend { + struct ggml_backend_i iface; + + ggml_backend_context_t context; + }; + +#ifdef __cplusplus +} +#endif diff --git a/sys/whisper.cpp/bindings/ruby/ext/ggml-backend.c b/sys/whisper.cpp/bindings/ruby/ext/ggml-backend.c new file mode 100644 index 0000000..f6e5fce --- /dev/null +++ b/sys/whisper.cpp/bindings/ruby/ext/ggml-backend.c @@ -0,0 +1,950 @@ +#include "ggml-backend-impl.h" +#include "ggml-alloc.h" +#include "ggml-impl.h" + +#include +#include +#include +#include +#include +#include + +#define UNUSED GGML_UNUSED + +#define MAX(a, b) ((a) > (b) ? (a) : (b)) + +// backend buffer + +ggml_backend_buffer_t ggml_backend_buffer_init( + struct ggml_backend * backend, + struct ggml_backend_buffer_i iface, + ggml_backend_buffer_context_t context, + size_t size) { + ggml_backend_buffer_t buffer = malloc(sizeof(struct ggml_backend_buffer)); + + GGML_ASSERT(iface.get_base != NULL); + + (*buffer) = (struct ggml_backend_buffer) { + /* .interface = */ iface, + /* .backend = */ backend, + /* .context = */ context, + /* .size = */ size, + }; + + return buffer; +} + +void ggml_backend_buffer_free(ggml_backend_buffer_t buffer) { + if (buffer == NULL) { + return; + } + + if (buffer->iface.free_buffer != NULL) { + buffer->iface.free_buffer(buffer); + } + free(buffer); +} + +size_t ggml_backend_buffer_get_alignment(ggml_backend_buffer_t buffer) { + return ggml_backend_get_alignment(buffer->backend); +} + +size_t ggml_backend_buffer_get_size(ggml_backend_buffer_t buffer) { + return buffer->size; +} + +void * ggml_backend_buffer_get_base(ggml_backend_buffer_t buffer) { + void * base = buffer->iface.get_base(buffer); + + GGML_ASSERT(base != NULL && "backend buffer base cannot be NULL"); + + return base; +} + +size_t ggml_backend_buffer_get_alloc_size(ggml_backend_buffer_t buffer, struct ggml_tensor * tensor) { + // get_alloc_size is optional, defaults to ggml_nbytes + if (buffer->iface.get_alloc_size) { + return buffer->iface.get_alloc_size(buffer, tensor); + } + return ggml_nbytes(tensor); +} + +void ggml_backend_buffer_init_tensor(ggml_backend_buffer_t buffer, struct ggml_tensor * tensor) { + // init_tensor is optional + if (buffer->iface.init_tensor) { + buffer->iface.init_tensor(buffer, tensor); + } +} + +void ggml_backend_buffer_free_tensor(ggml_backend_buffer_t buffer, struct ggml_tensor * tensor) { + // free_tensor is optional + if (buffer->iface.free_tensor) { + buffer->iface.free_tensor(buffer, tensor); + } +} + +// backend + +ggml_backend_t ggml_get_backend(const struct ggml_tensor * tensor) { + return tensor->buffer ? tensor->buffer->backend : NULL; +} + +const char * ggml_backend_name(ggml_backend_t backend) { + if (backend == NULL) { + return "NULL"; + } + return backend->iface.get_name(backend); +} + +void ggml_backend_free(ggml_backend_t backend) { + if (backend == NULL) { + return; + } + + backend->iface.free(backend); +} + +ggml_backend_buffer_t ggml_backend_alloc_buffer(ggml_backend_t backend, size_t size) { + return backend->iface.alloc_buffer(backend, size); +} + +size_t ggml_backend_get_alignment(ggml_backend_t backend) { + return backend->iface.get_alignment(backend); +} + +void ggml_backend_tensor_set_async(struct ggml_tensor * tensor, const void * data, size_t offset, size_t size) { + ggml_get_backend(tensor)->iface.set_tensor_async(ggml_get_backend(tensor), tensor, data, offset, size); +} + +void ggml_backend_tensor_get_async(const struct ggml_tensor * tensor, void * data, size_t offset, size_t size) { + ggml_get_backend(tensor)->iface.get_tensor_async(ggml_get_backend(tensor), tensor, data, offset, size); +} + +void ggml_backend_tensor_set(struct ggml_tensor * tensor, const void * data, size_t offset, size_t size) { + ggml_backend_t backend = ggml_get_backend(tensor); + + GGML_ASSERT(tensor->data != NULL && "tensor not allocated"); + GGML_ASSERT(backend != NULL && "tensor backend not set"); + + backend->iface.set_tensor_async(backend, tensor, data, offset, size); + backend->iface.synchronize(backend); +} + +void ggml_backend_tensor_get(const struct ggml_tensor * tensor, void * data, size_t offset, size_t size) { + ggml_backend_t backend = ggml_get_backend(tensor); + + GGML_ASSERT(tensor->data != NULL && "tensor not allocated"); + GGML_ASSERT(backend != NULL && "tensor backend not set"); + + backend->iface.get_tensor_async(backend, tensor, data, offset, size); + backend->iface.synchronize(backend); +} + +void ggml_backend_synchronize(ggml_backend_t backend) { + backend->iface.synchronize(backend); +} + +ggml_backend_graph_plan_t ggml_backend_graph_plan_create(ggml_backend_t backend, struct ggml_cgraph * cgraph) { + return backend->iface.graph_plan_create(backend, cgraph); +} + +void ggml_backend_graph_plan_free(ggml_backend_t backend, ggml_backend_graph_plan_t plan) { + backend->iface.graph_plan_free(backend, plan); +} + +void ggml_backend_graph_plan_compute(ggml_backend_t backend, ggml_backend_graph_plan_t plan) { + backend->iface.graph_plan_compute(backend, plan); +} + +void ggml_backend_graph_compute(ggml_backend_t backend, struct ggml_cgraph * cgraph) { + backend->iface.graph_compute(backend, cgraph); +} + +bool ggml_backend_supports_op(ggml_backend_t backend, const struct ggml_tensor * op) { + return backend->iface.supports_op(backend, op); +} + +// backend copy + +static bool ggml_are_same_layout(const struct ggml_tensor * a, const struct ggml_tensor * b) { + if (a->type != b->type) { + return false; + } + for (int i = 0; i < GGML_MAX_DIMS; i++) { + if (a->ne[i] != b->ne[i]) { + return false; + } + if (a->nb[i] != b->nb[i]) { + return false; + } + } + return true; +} + +void ggml_backend_tensor_copy(struct ggml_tensor * src, struct ggml_tensor * dst) { + //printf("src: %s ne: [%d %d %d %d] nb: [%d %d %d %d]\n", src->name, (int)src->ne[0], (int)src->ne[1], (int)src->ne[2], (int)src->ne[3], (int)src->nb[0], (int)src->nb[1], (int)src->nb[2], (int)src->nb[3]); + //printf("dst: %s ne: [%d %d %d %d] nb: [%d %d %d %d]\n", dst->name, (int)dst->ne[0], (int)dst->ne[1], (int)dst->ne[2], (int)dst->ne[3], (int)dst->nb[0], (int)dst->nb[1], (int)dst->nb[2], (int)dst->nb[3]); + GGML_ASSERT(ggml_are_same_layout(src, dst) && "cannot copy tensors with different layouts"); + + // fprintf(stderr, "cpy tensor %s from %s to %s (%lu bytes)\n", src->name, ggml_backend_name(src->backend), ggml_backend_name(dst->backend), ggml_nbytes(src)); + + if (src == dst) { + return; + } + + // TODO: allow backends to support copy to/from same backend + + if (ggml_get_backend(dst)->iface.cpy_tensor_from != NULL) { + ggml_get_backend(dst)->iface.cpy_tensor_from(ggml_get_backend(dst)->context, src, dst); + } else if (ggml_get_backend(src)->iface.cpy_tensor_to != NULL) { + ggml_get_backend(src)->iface.cpy_tensor_to(ggml_get_backend(src)->context, src, dst); + } else { + // shouldn't be hit when copying from/to CPU + #ifndef NDEBUG + fprintf(stderr, "ggml_backend_tensor_copy: neither cpy_tensor_from nor cpy_tensor_to are implemented for backends %s and %s, falling back to get/set\n", ggml_backend_name(src->buffer->backend), ggml_backend_name(dst->buffer->backend)); + #endif + size_t nbytes = ggml_nbytes(src); + void * data = malloc(nbytes); + ggml_backend_tensor_get(src, data, 0, nbytes); + ggml_backend_tensor_set(dst, data, 0, nbytes); + free(data); + } +} + +// backend CPU + +struct ggml_backend_cpu_context { + int n_threads; + void * work_data; + size_t work_size; +}; + +static const char * ggml_backend_cpu_name(ggml_backend_t backend) { + return "CPU"; + + UNUSED(backend); +} + +static void ggml_backend_cpu_free(ggml_backend_t backend) { + struct ggml_backend_cpu_context * cpu_ctx = (struct ggml_backend_cpu_context *)backend->context; + free(cpu_ctx->work_data); + free(cpu_ctx); + free(backend); +} + +static void * ggml_backend_cpu_buffer_get_base(ggml_backend_buffer_t buffer) { + return (void *)buffer->context; +} + +static void ggml_backend_cpu_buffer_free_buffer(ggml_backend_buffer_t buffer) { + free(buffer->context); + UNUSED(buffer); +} + +static struct ggml_backend_buffer_i cpu_backend_buffer_i = { + /* .free_buffer = */ ggml_backend_cpu_buffer_free_buffer, + /* .get_base = */ ggml_backend_cpu_buffer_get_base, + /* .get_alloc_size = */ NULL, // defaults to ggml_nbytes + /* .init_tensor = */ NULL, // no initialization required + /* .free_tensor = */ NULL, // no cleanup required +}; + +// for buffers from ptr, free is not called +static struct ggml_backend_buffer_i cpu_backend_buffer_i_from_ptr = { + /* .free_buffer = */ NULL, // ptr is not owned by the buffer, so it does not need to be freed + /* .get_base = */ ggml_backend_cpu_buffer_get_base, + /* .get_alloc_size = */ NULL, // defaults to ggml_nbytes + /* .init_tensor = */ NULL, + /* .free_tensor = */ NULL, +}; + +static const size_t TENSOR_ALIGNMENT = 64; // should be enough for AVX 512 + +static ggml_backend_buffer_t ggml_backend_cpu_alloc_buffer(ggml_backend_t backend, size_t size) { + size += TENSOR_ALIGNMENT; // malloc may return an address that is not aligned + void * data = malloc(size); // TODO: maybe use GGML_ALIGNED_MALLOC? + + GGML_ASSERT(data != NULL && "failed to allocate buffer"); + + return ggml_backend_buffer_init(backend, cpu_backend_buffer_i, data, size); +} + +static size_t ggml_backend_cpu_get_alignment(ggml_backend_t backend) { + return TENSOR_ALIGNMENT; + UNUSED(backend); +} + +static void ggml_backend_cpu_set_tensor_async(ggml_backend_t backend, struct ggml_tensor * tensor, const void * data, size_t offset, size_t size) { + GGML_ASSERT(offset + size <= ggml_nbytes(tensor) && "tensor write out of bounds"); + GGML_ASSERT(tensor->data != NULL && "tensor not allocated"); + + memcpy((char *)tensor->data + offset, data, size); + + UNUSED(backend); +} + +static void ggml_backend_cpu_get_tensor_async(ggml_backend_t backend, const struct ggml_tensor * tensor, void * data, size_t offset, size_t size) { + GGML_ASSERT(offset + size <= ggml_nbytes(tensor) && "tensor read out of bounds"); + GGML_ASSERT(tensor->data != NULL && "tensor not allocated"); + + memcpy(data, (const char *)tensor->data + offset, size); + + UNUSED(backend); +} + +static void ggml_backend_cpu_synchronize(ggml_backend_t backend) { + UNUSED(backend); +} + +static void ggml_backend_cpu_cpy_tensor_from(ggml_backend_t backend, struct ggml_tensor * src, struct ggml_tensor * dst) { + ggml_backend_tensor_get(src, dst->data, 0, ggml_nbytes(src)); + + UNUSED(backend); +} + +static void ggml_backend_cpu_cpy_tensor_to(ggml_backend_t backend, struct ggml_tensor * src, struct ggml_tensor * dst) { + ggml_backend_tensor_set(dst, src->data, 0, ggml_nbytes(src)); + + UNUSED(backend); +} + +struct ggml_backend_plan_cpu { + struct ggml_cplan cplan; + struct ggml_cgraph cgraph; +}; + +static ggml_backend_graph_plan_t ggml_backend_cpu_graph_plan_create(ggml_backend_t backend, struct ggml_cgraph * cgraph) { + struct ggml_backend_cpu_context * cpu_ctx = (struct ggml_backend_cpu_context *)backend->context; + + struct ggml_backend_plan_cpu * cpu_plan = malloc(sizeof(struct ggml_backend_plan_cpu)); + + cpu_plan->cplan = ggml_graph_plan(cgraph, cpu_ctx->n_threads); + cpu_plan->cgraph = *cgraph; + + if (cpu_plan->cplan.work_size > 0) { + cpu_plan->cplan.work_data = malloc(cpu_plan->cplan.work_size); + } + + return cpu_plan; +} + +static void ggml_backend_cpu_graph_plan_free(ggml_backend_t backend, ggml_backend_graph_plan_t plan) { + struct ggml_backend_plan_cpu * cpu_plan = (struct ggml_backend_plan_cpu *)plan; + + free(cpu_plan->cplan.work_data); + free(cpu_plan); + + UNUSED(backend); +} + +static void ggml_backend_cpu_graph_plan_compute(ggml_backend_t backend, ggml_backend_graph_plan_t plan) { + struct ggml_backend_plan_cpu * cpu_plan = (struct ggml_backend_plan_cpu *)plan; + + ggml_graph_compute(&cpu_plan->cgraph, &cpu_plan->cplan); + + UNUSED(backend); +} + +static void ggml_backend_cpu_graph_compute(ggml_backend_t backend, struct ggml_cgraph * cgraph) { + struct ggml_backend_cpu_context * cpu_ctx = (struct ggml_backend_cpu_context *)backend->context; + + struct ggml_cplan cplan = ggml_graph_plan(cgraph, cpu_ctx->n_threads); + + if (cpu_ctx->work_size < cplan.work_size) { + // TODO: may be faster to free and use malloc to avoid the copy + cpu_ctx->work_data = realloc(cpu_ctx->work_data, cplan.work_size); + cpu_ctx->work_size = cplan.work_size; + } + + cplan.work_data = cpu_ctx->work_data; + + ggml_graph_compute(cgraph, &cplan); +} + +static bool ggml_backend_cpu_supports_op(ggml_backend_t backend, const struct ggml_tensor * op) { + return true; + UNUSED(backend); + UNUSED(op); +} + +static struct ggml_backend_i cpu_backend_i = { + /* .get_name = */ ggml_backend_cpu_name, + /* .free = */ ggml_backend_cpu_free, + /* .alloc_buffer = */ ggml_backend_cpu_alloc_buffer, + /* .get_alignment = */ ggml_backend_cpu_get_alignment, + /* .set_tensor_async = */ ggml_backend_cpu_set_tensor_async, + /* .get_tensor_async = */ ggml_backend_cpu_get_tensor_async, + /* .synchronize = */ ggml_backend_cpu_synchronize, + /* .cpy_tensor_from = */ ggml_backend_cpu_cpy_tensor_from, + /* .cpy_tensor_to = */ ggml_backend_cpu_cpy_tensor_to, + /* .graph_plan_create = */ ggml_backend_cpu_graph_plan_create, + /* .graph_plan_free = */ ggml_backend_cpu_graph_plan_free, + /* .graph_plan_compute = */ ggml_backend_cpu_graph_plan_compute, + /* .graph_compute = */ ggml_backend_cpu_graph_compute, + /* .supports_op = */ ggml_backend_cpu_supports_op, +}; + +ggml_backend_t ggml_backend_cpu_init(void) { + struct ggml_backend_cpu_context * ctx = malloc(sizeof(struct ggml_backend_cpu_context)); + + ctx->n_threads = GGML_DEFAULT_N_THREADS; + ctx->work_data = NULL; + ctx->work_size = 0; + + ggml_backend_t cpu_backend = malloc(sizeof(struct ggml_backend)); + + *cpu_backend = (struct ggml_backend) { + /* .interface = */ cpu_backend_i, + /* .context = */ ctx + }; + return cpu_backend; +} + +bool ggml_backend_is_cpu(ggml_backend_t backend) { + return backend->iface.get_name == ggml_backend_cpu_name; +} + +void ggml_backend_cpu_set_n_threads(ggml_backend_t backend_cpu, int n_threads) { + GGML_ASSERT(ggml_backend_is_cpu(backend_cpu)); + + struct ggml_backend_cpu_context * ctx = (struct ggml_backend_cpu_context *)backend_cpu->context; + ctx->n_threads = n_threads; +} + +ggml_backend_buffer_t ggml_backend_cpu_buffer_from_ptr(ggml_backend_t backend_cpu, void * ptr, size_t size) { + return ggml_backend_buffer_init(backend_cpu, cpu_backend_buffer_i_from_ptr, ptr, size); +} + +// scheduler + +#define GGML_MAX_BACKENDS 4 +#define GGML_MAX_SPLITS 256 +#define GGML_MAX_SPLIT_INPUTS 16 + +struct ggml_backend_sched_split { + ggml_tallocr_t tallocr; + int i_start; + int i_end; + struct ggml_tensor * inputs[GGML_MAX_SPLIT_INPUTS]; + int n_inputs; + struct ggml_cgraph * graph; +}; + +struct ggml_backend_sched { + int n_backends; + ggml_backend_t backends[GGML_MAX_BACKENDS]; + ggml_tallocr_t tallocs[GGML_MAX_BACKENDS]; + + ggml_gallocr_t galloc; + + struct ggml_hash_set hash_set; + ggml_tallocr_t * node_talloc; // [hash_set.size] + struct ggml_tensor * (* node_copies)[GGML_MAX_BACKENDS]; // [hash_set.size][GGML_MAX_BACKENDS] + + struct ggml_cgraph * graph; + struct ggml_backend_sched_split splits[GGML_MAX_SPLITS]; + int n_splits; + + struct ggml_context * ctx; + + // align context_buffer to GGML_MEM_ALIGN + #ifdef _MSC_VER + __declspec(align(GGML_MEM_ALIGN)) + #else + __attribute__((aligned(GGML_MEM_ALIGN))) + #endif + char context_buffer[GGML_MAX_SPLITS*GGML_MAX_SPLIT_INPUTS*sizeof(struct ggml_tensor) + GGML_MAX_SPLITS*sizeof(struct ggml_cgraph)]; +}; + +#define hash_id(node) ggml_hash_find_or_insert(sched->hash_set, node) +#define node_allocr(node) sched->node_talloc[hash_id(node)] + +static bool ggml_is_view_op(enum ggml_op op) { + return op == GGML_OP_VIEW || op == GGML_OP_RESHAPE || op == GGML_OP_PERMUTE || op == GGML_OP_TRANSPOSE; +} + +// returns the priority of the backend, lower is better +static int sched_backend_prio(ggml_backend_sched_t sched, ggml_backend_t backend) { + for (int i = 0; i < sched->n_backends; i++) { + if (sched->backends[i] == backend) { + return i; + } + } + return INT_MAX; +} + +static int sched_allocr_prio(ggml_backend_sched_t sched, ggml_tallocr_t allocr) { + for (int i = 0; i < sched->n_backends; i++) { + if (sched->tallocs[i] == allocr) { + return i; + } + } + return INT_MAX; +} + +// returns the backend that should be used for the node based on the current locations +char causes[GGML_DEFAULT_GRAPH_SIZE*4 + GGML_MAX_SPLITS*GGML_MAX_SPLIT_INPUTS][128]; // debug, remove +static ggml_backend_t sched_backend_from_cur(ggml_backend_sched_t sched, struct ggml_tensor * node) { + // if the dst tensor is already allocated in a buffer, we must assume that it is critical to keep it there + // ie. kv cache updates + // note that this doesn't allow fallback to CPU. need to add output tensors to the splits to copy the data back to the original backend. + // dst + ggml_backend_t cur_backend = ggml_get_backend(node); + if (cur_backend != NULL) { + sprintf(causes[hash_id(node)], "1.dst"); + return cur_backend; + } + + // view_src + if (node->view_src != NULL && ggml_get_backend(node->view_src) != NULL) { + sprintf(causes[hash_id(node)], "1.vsrc"); + return ggml_get_backend(node->view_src); + } + + // src + int cur_prio = INT_MAX; + size_t cur_size = 0; + + for (int i = 0; i < GGML_MAX_SRC; i++) { + const struct ggml_tensor * src = node->src[i]; + if (src == NULL) { + break; + } + ggml_backend_t src_backend = ggml_get_backend(src); + if (src_backend != NULL) { + int src_prio = sched_backend_prio(sched, src_backend); + size_t src_size = ggml_nbytes(src); + if (src_prio < cur_prio && src_size >= cur_size) { + cur_prio = src_prio; + cur_size = src_size; + cur_backend = src_backend; + sprintf(causes[hash_id(node)], "1.src%d", i); + } + } + } + return cur_backend; +} + +static char * fmt_size(size_t size) { + static char buffer[128]; + if (size >= 1024*1024) { + sprintf(buffer, "%zuM", size/1024/1024); + } else { + sprintf(buffer, "%zuK", size/1024); + } + return buffer; +} + +static void sched_print_assignments(ggml_backend_sched_t sched, struct ggml_cgraph * graph) { + int cur_split = 0; + for (int i = 0; i < graph->n_nodes; i++) { + if (cur_split < sched->n_splits && i == sched->splits[cur_split].i_start) { + ggml_backend_t split_backend = ggml_tallocr_get_buffer(sched->splits[cur_split].tallocr)->backend; + fprintf(stderr, "\n## SPLIT #%d: %s # %d inputs: ", cur_split, ggml_backend_name(split_backend), sched->splits[cur_split].n_inputs); + for (int j = 0; j < sched->splits[cur_split].n_inputs; j++) { + fprintf(stderr, "[%s (%5.5s)] ", sched->splits[cur_split].inputs[j]->name, fmt_size(ggml_nbytes(sched->splits[cur_split].inputs[j]))); + } + fprintf(stderr, "\n"); + cur_split++; + } + struct ggml_tensor * node = graph->nodes[i]; + if (ggml_is_view_op(node->op)) { + continue; + } + ggml_tallocr_t node_allocr = node_allocr(node); + ggml_backend_t node_backend = node_allocr ? ggml_tallocr_get_buffer(node_allocr)->backend : NULL; + fprintf(stderr, "node #%3d (%10.10s): %20.20s (%4.4s) [%4.4s %8.8s]:", i, ggml_op_name(node->op), node->name, fmt_size(ggml_nbytes(node)), node_allocr ? ggml_backend_name(node_backend) : "NULL", causes[hash_id(node)]); + for (int j = 0; j < GGML_MAX_SRC; j++) { + struct ggml_tensor * src = node->src[j]; + if (src == NULL) { + break; + } + ggml_tallocr_t src_allocr = node_allocr(src); + ggml_backend_t src_backend = src_allocr ? ggml_tallocr_get_buffer(src_allocr)->backend : NULL; + fprintf(stderr, " %20.20s (%4.4s) [%4.4s %8.8s]", src->name, fmt_size(ggml_nbytes(src)), src_backend ? ggml_backend_name(src_backend) : "NULL", causes[hash_id(src)]); + } + fprintf(stderr, "\n"); + } +} + +// creates a copy of the tensor with the same memory layout +static struct ggml_tensor * ggml_dup_tensor_layout(struct ggml_context * ctx, const struct ggml_tensor * tensor) { + struct ggml_tensor * dup = ggml_dup_tensor(ctx, tensor); + for (int i = 0; i < GGML_MAX_DIMS; i++) { + dup->nb[i] = tensor->nb[i]; + } + return dup; +} + +// assigns backends to ops and splits the graph into subgraphs that can be computed on the same backend +// TODO: merge passes +static void sched_split_graph(ggml_backend_sched_t sched, struct ggml_cgraph * graph) { + // reset state + size_t hash_size = sched->hash_set.size; + memset(sched->hash_set.keys, 0, sizeof(sched->hash_set.keys[0]) * hash_size); + memset(sched->node_talloc, 0, sizeof(sched->node_talloc[0]) * hash_size); + memset(sched->node_copies, 0, sizeof(sched->node_copies[0]) * hash_size); + sched->n_splits = 0; + + struct ggml_init_params params = { + /*.mem_size = */ sizeof(sched->context_buffer), + /*.mem_buffer = */ sched->context_buffer, + /*.no_alloc = */ true + }; + + if (sched->ctx != NULL) { + ggml_free(sched->ctx); + } + + sched->ctx = ggml_init(params); + + // pass 1: assign backends to ops with allocated inputs + for (int i = 0; i < graph->n_leafs; i++) { + struct ggml_tensor * leaf = graph->leafs[i]; + if (node_allocr(leaf) != NULL) { + // do not overwrite user assignments + continue; + } + ggml_backend_t leaf_backend = ggml_get_backend(leaf); + if (leaf_backend == NULL && leaf->view_src != NULL) { + leaf_backend = ggml_get_backend(leaf->view_src); + } + if (leaf_backend != NULL) { + node_allocr(leaf) = ggml_backend_sched_get_tallocr(sched, leaf_backend); + } + } + + for (int i = 0; i < graph->n_nodes; i++) { + struct ggml_tensor * node = graph->nodes[i]; + if (node_allocr(node) != NULL) { + // do not overwrite user assignments + continue; + } + ggml_backend_t node_backend = sched_backend_from_cur(sched, node); + if (node_backend != NULL) { + node_allocr(node) = ggml_backend_sched_get_tallocr(sched, node_backend); + } + } + //printf("PASS 1 ASSIGNMENTS\n"); sched_print_assignments(sched, graph); + + // pass 2: assign backends to ops from current assignments + // TODO: + // - reuse sched_backend_from_cur + for (int i = 0; i < graph->n_nodes; i++) { + struct ggml_tensor * node = graph->nodes[i]; + ggml_tallocr_t node_allocr = node_allocr(node); + if (node_allocr == NULL) { + int cur_prio = INT_MAX; + size_t cur_size = 0; + for (int j = 0; j < GGML_MAX_SRC; j++) { + struct ggml_tensor * src = node->src[j]; + if (src == NULL) { + break; + } + ggml_tallocr_t src_allocr = node_allocr(src); + if (src_allocr != NULL) { + int src_prio = sched_allocr_prio(sched, src_allocr); + size_t src_size = ggml_nbytes(src); + if (src_prio < cur_prio && src_size >= cur_size) { + cur_prio = src_prio; + cur_size = src_size; + node_allocr = src_allocr; + sprintf(causes[hash_id(node)], "2.src%d", j); + } + } + } + if (node_allocr != NULL) { + node_allocr(node) = node_allocr; + } + } + } + //printf("PASS 2 ASSIGNMENTS\n"); sched_print_assignments(sched, graph); + + // pass 3: assign backends to remaining src from dst (should only be leafs) + for (int i = 0; i < graph->n_nodes; i++) { + struct ggml_tensor * node = graph->nodes[i]; + ggml_tallocr_t node_allocr = node_allocr(node); + for (int j = 0; j < GGML_MAX_SRC; j++) { + struct ggml_tensor * src = node->src[j]; + if (src == NULL) { + break; + } + ggml_tallocr_t src_allocr = node_allocr(src); + if (src_allocr == NULL) { + node_allocr(src) = node_allocr; + } + } + } + //printf("PASS 3 ASSIGNMENTS\n"); sched_print_assignments(sched, graph); + + // pass 4: split graph, find tensors that need to be copied + // TODO: + // - when switching from a less preferred backend to a more preferred backend, check if it is possible to move the switch to an earlier point for the same cost + // find first backend + int cur_split = 0; + for (int i = 0; i < graph->n_nodes; i++) { + struct ggml_tensor * node = graph->nodes[i]; + if (node->view_src == NULL) { + sched->splits[0].tallocr = node_allocr(node); + break; + } + } + sched->splits[0].i_start = 0; + sched->splits[0].n_inputs = 0; + memset(sched->splits[0].inputs, 0, sizeof(sched->splits[0].inputs)); //HACK + ggml_tallocr_t cur_allocr = sched->splits[0].tallocr; + size_t cur_backend_id = sched_allocr_prio(sched, cur_allocr); + for (int i = 0; i < graph->n_nodes; i++) { + struct ggml_tensor * node = graph->nodes[i]; + + if (ggml_is_view_op(node->op)) { + continue; + } + + ggml_tallocr_t node_allocr = node_allocr(node); + + if (node_allocr != cur_allocr) { + sched->splits[cur_split].i_end = i; + cur_split++; + GGML_ASSERT(cur_split < GGML_MAX_SPLITS); + sched->splits[cur_split].tallocr = node_allocr; + sched->splits[cur_split].i_start = i; + sched->splits[cur_split].n_inputs = 0; + memset(sched->splits[cur_split].inputs, 0, sizeof(sched->splits[cur_split].inputs)); //HACK + cur_allocr = node_allocr; + cur_backend_id = sched_allocr_prio(sched, cur_allocr); + } + + // find inputs that are not on the same backend + for (int j = 0; j < GGML_MAX_SRC; j++) { + struct ggml_tensor * src = node->src[j]; + if (src == NULL) { + break; + } + ggml_tallocr_t src_allocr = node_allocr(src); + if (src_allocr != node_allocr) { + int n_inputs = sched->splits[cur_split].n_inputs++; + GGML_ASSERT(n_inputs < GGML_MAX_SPLIT_INPUTS); + sched->splits[cur_split].inputs[n_inputs] = (struct ggml_tensor *)src; + + // create copies + size_t id = hash_id(src); + if (sched->node_copies[id][cur_backend_id] == NULL) { + struct ggml_tensor * tensor_copy = ggml_dup_tensor_layout(sched->ctx, src); + sched->node_copies[id][cur_backend_id] = tensor_copy; + node_allocr(tensor_copy) = cur_allocr; + ggml_backend_t backend = ggml_tallocr_get_buffer(cur_allocr)->backend; + ggml_format_name(tensor_copy, "%s#%s", ggml_backend_name(backend), src->name); + } + node->src[j] = sched->node_copies[id][cur_backend_id]; + } + } + } + sched->splits[cur_split].i_end = graph->n_nodes; + sched->n_splits = cur_split + 1; + + //fprintf(stderr, "PASS 4 ASSIGNMENTS\n"); sched_print_assignments(sched, graph); fflush(stdout); + +#if 1 + // sanity check: all sources should have the same backend as the node + for (int i = 0; i < graph->n_nodes; i++) { + struct ggml_tensor * node = graph->nodes[i]; + ggml_tallocr_t node_allocr = node_allocr(node); + if (node_allocr == NULL) { + fprintf(stderr, "!!!!!!! %s has no backend\n", node->name); + } + for (int j = 0; j < GGML_MAX_SRC; j++) { + struct ggml_tensor * src = node->src[j]; + if (src == NULL) { + break; + } + ggml_tallocr_t src_allocr = node_allocr(src); + if (src_allocr != node_allocr /* && src_backend != NULL */) { // ignore nulls for now + fprintf(stderr, "!!!! %s has backend %s, src %d (%s) has backend %s\n", + node->name, node_allocr ? ggml_backend_name(ggml_tallocr_get_buffer(node_allocr)->backend) : "NULL", + j, src->name, src_allocr ? ggml_backend_name(ggml_tallocr_get_buffer(src_allocr)->backend) : "NULL"); + } + } + } +#endif + + // create copies of the graph for each split + // FIXME: avoid this copy, pass split inputs to ggml_gallocr_alloc_graph_n in some other way + struct ggml_cgraph * graph_copy = ggml_new_graph_custom(sched->ctx, graph->n_nodes + sched->n_splits*GGML_MAX_SPLIT_INPUTS, false); + for (int i = 0; i < sched->n_splits; i++) { + struct ggml_backend_sched_split * split = &sched->splits[i]; + split->graph = ggml_graph_view(sched->ctx, graph, split->i_start, split->i_end); + + // add inputs to the graph copy so that they are allocated by ggml-alloc at the start of the split + for (int j = 0; j < split->n_inputs; j++) { + struct ggml_tensor * input = split->inputs[j]; + struct ggml_tensor * input_cpy = sched->node_copies[hash_id(input)][sched_allocr_prio(sched, split->tallocr)]; + input_cpy->src[0] = input; + graph_copy->nodes[graph_copy->n_nodes++] = input_cpy; + } + + for (int j = split->i_start; j < split->i_end; j++) { + graph_copy->nodes[graph_copy->n_nodes++] = graph->nodes[j]; + } + } + sched->graph = graph_copy; +} + +static void sched_alloc_splits(ggml_backend_sched_t sched) { + ggml_gallocr_alloc_graph_n( + sched->galloc, + sched->graph, + sched->hash_set, + sched->node_talloc); +} + +static void sched_compute_splits(ggml_backend_sched_t sched) { + uint64_t copy_us[GGML_MAX_BACKENDS] = {0}; + uint64_t compute_us[GGML_MAX_BACKENDS] = {0}; + + struct ggml_backend_sched_split * splits = sched->splits; + + for (int i = 0; i < sched->n_splits; i++) { + struct ggml_backend_sched_split * split = &splits[i]; + ggml_backend_t split_backend = ggml_tallocr_get_buffer(split->tallocr)->backend; + int split_backend_id = sched_backend_prio(sched, split_backend); + + // copy the input tensors to the split backend + uint64_t copy_start_us = ggml_time_us(); + for (int j = 0; j < split->n_inputs; j++) { + struct ggml_tensor * input_cpy = sched->node_copies[hash_id(split->inputs[j])][sched_backend_prio(sched, split_backend)]; + if (split->inputs[j]->buffer == NULL) { + if (split->inputs[j]->view_src == NULL) { + fprintf(stderr, "input %s has no buffer and no view_src\n", split->inputs[j]->name); + exit(1); + } + struct ggml_tensor * view = split->inputs[j]; + view->backend = view->view_src->backend; + view->buffer = view->view_src->buffer; + view->data = (char *)view->view_src->data + view->view_offs; + ggml_backend_buffer_init_tensor(ggml_backend_sched_get_buffer(sched, view->buffer->backend), view); + } + if (input_cpy->buffer == NULL) { + fprintf(stderr, "input_cpy %s has no buffer\n", input_cpy->name); + exit(1); + } + GGML_ASSERT(split->inputs[j]->buffer->backend != input_cpy->buffer->backend); + GGML_ASSERT(input_cpy->buffer->backend == split_backend); + ggml_backend_tensor_copy(split->inputs[j], input_cpy); + } + // ggml_backend_synchronize(split_backend); + int64_t copy_end_us = ggml_time_us(); + copy_us[split_backend_id] += copy_end_us - copy_start_us; + +#if 0 + char split_filename[GGML_MAX_NAME]; + snprintf(split_filename, GGML_MAX_NAME, "split_%i_%s.dot", i, ggml_backend_name(split_backend)); + ggml_graph_dump_dot(split->graph, NULL, split_filename); +#endif + + uint64_t compute_start_us = ggml_time_us(); + ggml_backend_graph_compute(split_backend, split->graph); + // ggml_backend_synchronize(split_backend); + uint64_t compute_end_us = ggml_time_us(); + compute_us[split_backend_id] += compute_end_us - compute_start_us; + } + +#if 0 + // per-backend timings + fprintf(stderr, "sched_compute_splits times (%d splits):\n", sched->n_splits); + for (int i = 0; i < sched->n_backends; i++) { + if (copy_us[i] > 0 || compute_us[i] > 0) { + fprintf(stderr, "\t%5.5s: %lu us copy, %lu us compute\n", ggml_backend_name(sched->backends[i]), copy_us[i], compute_us[i]); + } + } +#endif +} + +static void sched_reset(ggml_backend_sched_t sched) { + for (int i = 0; i < sched->n_backends; i++) { + ggml_tallocr_reset(sched->tallocs[i]); + } +} + +ggml_backend_sched_t ggml_backend_sched_new(ggml_backend_t * backends, int n_backends) { + GGML_ASSERT(n_backends <= GGML_MAX_BACKENDS); + + struct ggml_backend_sched * sched = malloc(sizeof(struct ggml_backend_sched)); + memset(sched, 0, sizeof(struct ggml_backend_sched)); + + fprintf(stderr, "ggml_backend_sched size: %lu KB\n", sizeof(struct ggml_backend_sched)/1024); + + sched->n_backends = n_backends; + for (int i = 0; i < n_backends; i++) { + sched->backends[i] = backends[i]; + } + + sched->galloc = ggml_gallocr_new(); + + // init measure allocs for each backend + for (int i = 0; i < n_backends; i++) { + sched->tallocs[i] = ggml_tallocr_new_measure_from_backend(backends[i]); + } + + return sched; +} + +void ggml_backend_sched_free(ggml_backend_sched_t sched) { + if (sched == NULL) { + return; + } + for (int i = 0; i < sched->n_backends; i++) { + ggml_tallocr_free(sched->tallocs[i]); + } + ggml_gallocr_free(sched->galloc); + free(sched->hash_set.keys); + free(sched->node_talloc); + free(sched->node_copies); + free(sched); +} + +void ggml_backend_sched_init_measure(ggml_backend_sched_t sched, struct ggml_cgraph * measure_graph) { + // initialize hash tables + size_t hash_size = measure_graph->visited_hash_table.size + GGML_MAX_SPLITS*GGML_MAX_SPLIT_INPUTS; + sched->hash_set.size = hash_size; + sched->hash_set.keys = malloc(sizeof(sched->hash_set.keys[0]) * hash_size); + sched->node_talloc = malloc(sizeof(sched->node_talloc[0]) * hash_size); + sched->node_copies = malloc(sizeof(sched->node_copies[0]) * hash_size); + + sched_split_graph(sched, measure_graph); + sched_alloc_splits(sched); + + // allocate buffers and reset allocators + for (int i = 0; i < sched->n_backends; i++) { + size_t size = ggml_tallocr_max_size(sched->tallocs[i]); + ggml_tallocr_free(sched->tallocs[i]); + sched->tallocs[i] = ggml_tallocr_new_from_backend(sched->backends[i], size); + } + + sched_reset(sched); +} + +void ggml_backend_sched_graph_compute(ggml_backend_sched_t sched, struct ggml_cgraph * graph) { + GGML_ASSERT(sched->hash_set.size >= graph->visited_hash_table.size + GGML_MAX_SPLITS*GGML_MAX_SPLIT_INPUTS); + + sched_split_graph(sched, graph); + sched_alloc_splits(sched); + sched_compute_splits(sched); + sched_reset(sched); +} + +ggml_tallocr_t ggml_backend_sched_get_tallocr(ggml_backend_sched_t sched, ggml_backend_t backend) { + int backend_index = sched_backend_prio(sched, backend); + return sched->tallocs[backend_index]; +} + +ggml_backend_buffer_t ggml_backend_sched_get_buffer(ggml_backend_sched_t sched, ggml_backend_t backend) { + int backend_index = sched_backend_prio(sched, backend); + return ggml_tallocr_get_buffer(sched->tallocs[backend_index]); +} + +void ggml_backend_sched_set_node_backend(ggml_backend_sched_t sched, struct ggml_tensor * node, ggml_backend_t backend) { + int backend_index = sched_backend_prio(sched, backend); + GGML_ASSERT(backend_index >= 0 && backend_index < sched->n_backends); + node_allocr(node) = sched->tallocs[backend_index]; +} diff --git a/sys/whisper.cpp/bindings/ruby/ext/ggml-backend.h b/sys/whisper.cpp/bindings/ruby/ext/ggml-backend.h new file mode 100644 index 0000000..9666873 --- /dev/null +++ b/sys/whisper.cpp/bindings/ruby/ext/ggml-backend.h @@ -0,0 +1,136 @@ +#pragma once + +#include "ggml.h" +#include "ggml-alloc.h" + +#ifdef __cplusplus +extern "C" { +#endif + + // + // Backend buffer + // + + struct ggml_backend_buffer; + typedef struct ggml_backend_buffer * ggml_backend_buffer_t; + + // backend buffer functions + GGML_API void ggml_backend_buffer_free (ggml_backend_buffer_t buffer); + GGML_API size_t ggml_backend_buffer_get_alignment (ggml_backend_buffer_t buffer); + GGML_API void * ggml_backend_buffer_get_base (ggml_backend_buffer_t buffer); + GGML_API size_t ggml_backend_buffer_get_size (ggml_backend_buffer_t buffer); + GGML_API size_t ggml_backend_buffer_get_alloc_size(ggml_backend_buffer_t buffer, struct ggml_tensor * tensor); + GGML_API void ggml_backend_buffer_init_tensor (ggml_backend_buffer_t buffer, struct ggml_tensor * tensor); + GGML_API void ggml_backend_buffer_free_tensor (ggml_backend_buffer_t buffer, struct ggml_tensor * tensor); + + // + // Backend + // + + struct ggml_backend; + typedef struct ggml_backend * ggml_backend_t; + typedef void * ggml_backend_graph_plan_t; + + GGML_API ggml_backend_t ggml_get_backend(const struct ggml_tensor * tensor); + + GGML_API const char * ggml_backend_name(ggml_backend_t backend); + GGML_API void ggml_backend_free(ggml_backend_t backend); + + GGML_API ggml_backend_buffer_t ggml_backend_alloc_buffer(ggml_backend_t backend, size_t size); + + GGML_API size_t ggml_backend_get_alignment(ggml_backend_t backend); + + GGML_API void ggml_backend_tensor_set_async( struct ggml_tensor * tensor, const void * data, size_t offset, size_t size); + GGML_API void ggml_backend_tensor_get_async(const struct ggml_tensor * tensor, void * data, size_t offset, size_t size); + + GGML_API void ggml_backend_tensor_set( struct ggml_tensor * tensor, const void * data, size_t offset, size_t size); + GGML_API void ggml_backend_tensor_get(const struct ggml_tensor * tensor, void * data, size_t offset, size_t size); + + GGML_API void ggml_backend_synchronize(ggml_backend_t backend); + + GGML_API ggml_backend_graph_plan_t ggml_backend_graph_plan_create (ggml_backend_t backend, struct ggml_cgraph * cgraph); + + GGML_API void ggml_backend_graph_plan_free (ggml_backend_t backend, ggml_backend_graph_plan_t plan); + GGML_API void ggml_backend_graph_plan_compute(ggml_backend_t backend, ggml_backend_graph_plan_t plan); + GGML_API void ggml_backend_graph_compute (ggml_backend_t backend, struct ggml_cgraph * cgraph); + GGML_API bool ggml_backend_supports_op (ggml_backend_t backend, const struct ggml_tensor * op); + + // tensor copy between different backends + GGML_API void ggml_backend_tensor_copy(struct ggml_tensor * src, struct ggml_tensor * dst); + + // + // CPU backend + // + + GGML_API ggml_backend_t ggml_backend_cpu_init(void); + + GGML_API bool ggml_backend_is_cpu(ggml_backend_t backend); + GGML_API void ggml_backend_cpu_set_n_threads(ggml_backend_t backend_cpu, int n_threads); + + // Create a backend buffer from an existing pointer + GGML_API ggml_backend_buffer_t ggml_backend_cpu_buffer_from_ptr(ggml_backend_t backend_cpu, void * ptr, size_t size); + + + // + // Backend scheduler + // + + // The backend scheduler allows for multiple backends to be used together + // Handles compute buffer allocation, assignment of tensors to backends, and copying of tensors between backends + // The backends are selected based on: + // - the backend that supports the operation + // - the location of the pre-allocated tensors (e.g. the weights) + /* + Example usage: + + sched = ggml_backend_sched_new({backend_gpu, backend_gpu2, backend_cpu}, num_backends); + // sched is initialized with measure allocators and cannot be used until allocated with a measure graph + + // initialize buffers from a measure graph + measure_graph = build_graph(sched); // use the allocr to allocate inputs as needed + + // in build_graph: + build_graph(...) { + // allocating tensors in a specific backend (optional, recommended: pre-allocate inputs in a different buffer) + alloc_cpu = ggml_backend_sched_get_allocr(sched, backend_cpu); + ggml_allocr_alloc(alloc_cpu, tensor); + + // manually assigning nodes to a backend (optional, shouldn't be needed in most cases) + struct ggml_tensor * node = ggml_mul_mat(ctx, ...); + ggml_backend_sched_set_node_backend(sched, node, backend_gpu); + } + + // allocate backend buffers from measure graph + ggml_backend_sched_init_measure(sched, measure_graph); + + // the scheduler is now ready to compute graphs + + // compute + graph = build_graph(sched); + ggml_backend_sched_graph_compute(sched, graph); + */ + + struct ggml_backend_sched; + typedef struct ggml_backend_sched * ggml_backend_sched_t; + + // Initialize a backend scheduler + GGML_API ggml_backend_sched_t ggml_backend_sched_new(ggml_backend_t * backends, int n_backends); + + GGML_API void ggml_backend_sched_free(ggml_backend_sched_t sched); + + // Initialize backend buffers from a measure graph + GGML_API void ggml_backend_sched_init_measure(ggml_backend_sched_t sched, struct ggml_cgraph * measure_graph); + + GGML_API ggml_tallocr_t ggml_backend_sched_get_tallocr(ggml_backend_sched_t sched, ggml_backend_t backend); + GGML_API ggml_backend_buffer_t ggml_backend_sched_get_buffer (ggml_backend_sched_t sched, ggml_backend_t backend); + + GGML_API void ggml_backend_sched_set_node_backend(ggml_backend_sched_t sched, struct ggml_tensor * node, ggml_backend_t backend); + + // Allocate a graph on the backend scheduler + GGML_API void ggml_backend_sched_graph_compute( + ggml_backend_sched_t sched, + struct ggml_cgraph * graph); + +#ifdef __cplusplus +} +#endif diff --git a/sys/whisper.cpp/bindings/ruby/ext/ggml-impl.h b/sys/whisper.cpp/bindings/ruby/ext/ggml-impl.h new file mode 100644 index 0000000..d88f261 --- /dev/null +++ b/sys/whisper.cpp/bindings/ruby/ext/ggml-impl.h @@ -0,0 +1,249 @@ +#pragma once + +#include "ggml.h" + +// GGML internal header + +#include +#include +#include +#include // memcpy +#include // fabsf + +#ifdef __cplusplus +extern "C" { +#endif + +// static_assert should be a #define, but if it's not, +// fall back to the _Static_assert C11 keyword. +// if C99 - static_assert is noop +// ref: https://stackoverflow.com/a/53923785/4039976 +#ifndef static_assert +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201100L) +#define static_assert(cond, msg) _Static_assert(cond, msg) +#else +#define static_assert(cond, msg) struct global_scope_noop_trick +#endif +#endif + +// __FMA__ and __F16C__ are not defined in MSVC, however they are implied with AVX2/AVX512 +#if defined(_MSC_VER) && (defined(__AVX2__) || defined(__AVX512F__)) +#ifndef __FMA__ +#define __FMA__ +#endif +#ifndef __F16C__ +#define __F16C__ +#endif +#ifndef __SSE3__ +#define __SSE3__ +#endif +#endif + +#undef MIN +#undef MAX + +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#define MAX(a, b) ((a) > (b) ? (a) : (b)) + +// 16-bit float +// on Arm, we use __fp16 +// on x86, we use uint16_t +#if defined(__ARM_NEON) && !defined(_MSC_VER) + +// if YCM cannot find , make a symbolic link to it, for example: +// +// $ ln -sfn /Library/Developer/CommandLineTools/usr/lib/clang/13.1.6/include/arm_neon.h ./src/ +// +#include + +#define GGML_COMPUTE_FP16_TO_FP32(x) ((float) (x)) +#define GGML_COMPUTE_FP32_TO_FP16(x) (x) + +#define GGML_FP16_TO_FP32(x) ((float) (x)) +#define GGML_FP32_TO_FP16(x) (x) + +#else + +#ifdef __wasm_simd128__ +#include +#else +#ifdef __POWER9_VECTOR__ +#include +#undef bool +#define bool _Bool +#else +#if defined(_MSC_VER) || defined(__MINGW32__) +#include +#else +#if defined(__AVX__) || defined(__AVX2__) || defined(__AVX512F__) || defined(__SSSE3__) || defined(__SSE3__) +#if !defined(__riscv) +#include +#endif +#endif +#endif +#endif +#endif + +#ifdef __riscv_v_intrinsic +#include +#endif + +#ifdef __F16C__ + +#ifdef _MSC_VER +#define GGML_COMPUTE_FP16_TO_FP32(x) _mm_cvtss_f32(_mm_cvtph_ps(_mm_cvtsi32_si128(x))) +#define GGML_COMPUTE_FP32_TO_FP16(x) _mm_extract_epi16(_mm_cvtps_ph(_mm_set_ss(x), 0), 0) +#else +#define GGML_COMPUTE_FP16_TO_FP32(x) _cvtsh_ss(x) +#define GGML_COMPUTE_FP32_TO_FP16(x) _cvtss_sh(x, 0) +#endif + +#elif defined(__POWER9_VECTOR__) + +#define GGML_COMPUTE_FP16_TO_FP32(x) ggml_compute_fp16_to_fp32(x) +#define GGML_COMPUTE_FP32_TO_FP16(x) ggml_compute_fp32_to_fp16(x) +/* the inline asm below is about 12% faster than the lookup method */ +#define GGML_FP16_TO_FP32(x) GGML_COMPUTE_FP16_TO_FP32(x) +#define GGML_FP32_TO_FP16(x) GGML_COMPUTE_FP32_TO_FP16(x) + +static inline float ggml_compute_fp16_to_fp32(ggml_fp16_t h) { + register float f; + register double d; + __asm__( + "mtfprd %0,%2\n" + "xscvhpdp %0,%0\n" + "frsp %1,%0\n" : + /* temp */ "=d"(d), + /* out */ "=f"(f): + /* in */ "r"(h)); + return f; +} + +static inline ggml_fp16_t ggml_compute_fp32_to_fp16(float f) { + register double d; + register ggml_fp16_t r; + __asm__( /* xscvdphp can work on double or single precision */ + "xscvdphp %0,%2\n" + "mffprd %1,%0\n" : + /* temp */ "=d"(d), + /* out */ "=r"(r): + /* in */ "f"(f)); + return r; +} + +#else + +// FP16 <-> FP32 +// ref: https://github.com/Maratyszcza/FP16 + +static inline float fp32_from_bits(uint32_t w) { + union { + uint32_t as_bits; + float as_value; + } fp32; + fp32.as_bits = w; + return fp32.as_value; +} + +static inline uint32_t fp32_to_bits(float f) { + union { + float as_value; + uint32_t as_bits; + } fp32; + fp32.as_value = f; + return fp32.as_bits; +} + +static inline float ggml_compute_fp16_to_fp32(ggml_fp16_t h) { + const uint32_t w = (uint32_t) h << 16; + const uint32_t sign = w & UINT32_C(0x80000000); + const uint32_t two_w = w + w; + + const uint32_t exp_offset = UINT32_C(0xE0) << 23; +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) || defined(__GNUC__) && !defined(__STRICT_ANSI__) + const float exp_scale = 0x1.0p-112f; +#else + const float exp_scale = fp32_from_bits(UINT32_C(0x7800000)); +#endif + const float normalized_value = fp32_from_bits((two_w >> 4) + exp_offset) * exp_scale; + + const uint32_t magic_mask = UINT32_C(126) << 23; + const float magic_bias = 0.5f; + const float denormalized_value = fp32_from_bits((two_w >> 17) | magic_mask) - magic_bias; + + const uint32_t denormalized_cutoff = UINT32_C(1) << 27; + const uint32_t result = sign | + (two_w < denormalized_cutoff ? fp32_to_bits(denormalized_value) : fp32_to_bits(normalized_value)); + return fp32_from_bits(result); +} + +static inline ggml_fp16_t ggml_compute_fp32_to_fp16(float f) { +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) || defined(__GNUC__) && !defined(__STRICT_ANSI__) + const float scale_to_inf = 0x1.0p+112f; + const float scale_to_zero = 0x1.0p-110f; +#else + const float scale_to_inf = fp32_from_bits(UINT32_C(0x77800000)); + const float scale_to_zero = fp32_from_bits(UINT32_C(0x08800000)); +#endif + float base = (fabsf(f) * scale_to_inf) * scale_to_zero; + + const uint32_t w = fp32_to_bits(f); + const uint32_t shl1_w = w + w; + const uint32_t sign = w & UINT32_C(0x80000000); + uint32_t bias = shl1_w & UINT32_C(0xFF000000); + if (bias < UINT32_C(0x71000000)) { + bias = UINT32_C(0x71000000); + } + + base = fp32_from_bits((bias >> 1) + UINT32_C(0x07800000)) + base; + const uint32_t bits = fp32_to_bits(base); + const uint32_t exp_bits = (bits >> 13) & UINT32_C(0x00007C00); + const uint32_t mantissa_bits = bits & UINT32_C(0x00000FFF); + const uint32_t nonsign = exp_bits + mantissa_bits; + return (sign >> 16) | (shl1_w > UINT32_C(0xFF000000) ? UINT16_C(0x7E00) : nonsign); +} + +#define GGML_COMPUTE_FP16_TO_FP32(x) ggml_compute_fp16_to_fp32(x) +#define GGML_COMPUTE_FP32_TO_FP16(x) ggml_compute_fp32_to_fp16(x) + +#endif // __F16C__ + +#endif // __ARM_NEON + +// precomputed f32 table for f16 (256 KB) +// defined in ggml.c, initialized in ggml_init() +extern float ggml_table_f32_f16[1 << 16]; + +// On ARM NEON, it's quicker to directly convert x -> x instead of calling into ggml_lookup_fp16_to_fp32, +// so we define GGML_FP16_TO_FP32 and GGML_FP32_TO_FP16 elsewhere for NEON. +// This is also true for POWER9. +#if !defined(GGML_FP16_TO_FP32) || !defined(GGML_FP32_TO_FP16) + +inline static float ggml_lookup_fp16_to_fp32(ggml_fp16_t f) { + uint16_t s; + memcpy(&s, &f, sizeof(uint16_t)); + return ggml_table_f32_f16[s]; +} + +#define GGML_FP16_TO_FP32(x) ggml_lookup_fp16_to_fp32(x) +#define GGML_FP32_TO_FP16(x) GGML_COMPUTE_FP32_TO_FP16(x) + +#endif + +#define GGML_HASHTABLE_FULL ((size_t)-1) +#define GGML_HASHTABLE_ALREADY_EXISTS ((size_t)-2) + +bool ggml_hash_contains (const struct ggml_hash_set hash_set, struct ggml_tensor * key); + +// returns GGML_HASHTABLE_FULL if table is full, otherwise the current index of the key or where it should be inserted +size_t ggml_hash_find (const struct ggml_hash_set hash_set, struct ggml_tensor * key); + +// returns GGML_HAHSHTABLE_ALREADY_EXISTS if key already exists, index otherwise, asserts if table is full +size_t ggml_hash_insert ( struct ggml_hash_set hash_set, struct ggml_tensor * key); + +// return index, asserts if table is full +size_t ggml_hash_find_or_insert( struct ggml_hash_set hash_set, struct ggml_tensor * key); + +#ifdef __cplusplus +} +#endif diff --git a/sys/whisper.cpp/bindings/ruby/ext/ggml-quants.c b/sys/whisper.cpp/bindings/ruby/ext/ggml-quants.c new file mode 100644 index 0000000..740be6d --- /dev/null +++ b/sys/whisper.cpp/bindings/ruby/ext/ggml-quants.c @@ -0,0 +1,7282 @@ +#include "ggml-quants.h" +#include "ggml-impl.h" + +#include +#include +#include +#include + +#ifdef __ARM_NEON + +// if YCM cannot find , make a symbolic link to it, for example: +// +// $ ln -sfn /Library/Developer/CommandLineTools/usr/lib/clang/13.1.6/include/arm_neon.h ./src/ +// +#include + +#if !defined(__aarch64__) +inline static int32_t vaddvq_s16(int16x8_t v) { + return + (int32_t)vgetq_lane_s16(v, 0) + (int32_t)vgetq_lane_s16(v, 1) + + (int32_t)vgetq_lane_s16(v, 2) + (int32_t)vgetq_lane_s16(v, 3) + + (int32_t)vgetq_lane_s16(v, 4) + (int32_t)vgetq_lane_s16(v, 5) + + (int32_t)vgetq_lane_s16(v, 6) + (int32_t)vgetq_lane_s16(v, 7); +} + +inline static int16x8_t vpaddq_s16(int16x8_t a, int16x8_t b) { + int16x4_t a0 = vpadd_s16(vget_low_s16(a), vget_high_s16(a)); + int16x4_t b0 = vpadd_s16(vget_low_s16(b), vget_high_s16(b)); + return vcombine_s16(a0, b0); +} + +inline static int32_t vaddvq_s32(int32x4_t v) { + return vgetq_lane_s32(v, 0) + vgetq_lane_s32(v, 1) + vgetq_lane_s32(v, 2) + vgetq_lane_s32(v, 3); +} +#endif + +#else + +#ifdef __wasm_simd128__ +#include +#else +#ifdef __POWER9_VECTOR__ +#include +#undef bool +#define bool _Bool +#else +#if defined(_MSC_VER) || defined(__MINGW32__) +#include +#else +#if !defined(__riscv) && !defined(__s390__) +#include +#endif +#endif +#endif +#endif +#endif + +#ifdef __riscv_v_intrinsic +#include +#endif + +#undef MIN +#undef MAX +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#define MAX(a, b) ((a) > (b) ? (a) : (b)) + +#define MM256_SET_M128I(a, b) _mm256_insertf128_si256(_mm256_castsi128_si256(b), (a), 1) + +#if defined(__AVX__) || defined(__AVX2__) || defined(__AVX512F__) || defined(__SSSE3__) +// multiply int8_t, add results pairwise twice +static inline __m128i mul_sum_i8_pairs(const __m128i x, const __m128i y) { + // Get absolute values of x vectors + const __m128i ax = _mm_sign_epi8(x, x); + // Sign the values of the y vectors + const __m128i sy = _mm_sign_epi8(y, x); + // Perform multiplication and create 16-bit values + const __m128i dot = _mm_maddubs_epi16(ax, sy); + const __m128i ones = _mm_set1_epi16(1); + return _mm_madd_epi16(ones, dot); +} + +#if __AVX__ || __AVX2__ || __AVX512F__ +// horizontally add 8 floats +static inline float hsum_float_8(const __m256 x) { + __m128 res = _mm256_extractf128_ps(x, 1); + res = _mm_add_ps(res, _mm256_castps256_ps128(x)); + res = _mm_add_ps(res, _mm_movehl_ps(res, res)); + res = _mm_add_ss(res, _mm_movehdup_ps(res)); + return _mm_cvtss_f32(res); +} + +// horizontally add 8 int32_t +static inline int hsum_i32_8(const __m256i a) { + const __m128i sum128 = _mm_add_epi32(_mm256_castsi256_si128(a), _mm256_extractf128_si256(a, 1)); + const __m128i hi64 = _mm_unpackhi_epi64(sum128, sum128); + const __m128i sum64 = _mm_add_epi32(hi64, sum128); + const __m128i hi32 = _mm_shuffle_epi32(sum64, _MM_SHUFFLE(2, 3, 0, 1)); + return _mm_cvtsi128_si32(_mm_add_epi32(sum64, hi32)); +} + +// horizontally add 4 int32_t +static inline int hsum_i32_4(const __m128i a) { + const __m128i hi64 = _mm_unpackhi_epi64(a, a); + const __m128i sum64 = _mm_add_epi32(hi64, a); + const __m128i hi32 = _mm_shuffle_epi32(sum64, _MM_SHUFFLE(2, 3, 0, 1)); + return _mm_cvtsi128_si32(_mm_add_epi32(sum64, hi32)); +} + +#if defined(__AVX2__) || defined(__AVX512F__) +// spread 32 bits to 32 bytes { 0x00, 0xFF } +static inline __m256i bytes_from_bits_32(const uint8_t * x) { + uint32_t x32; + memcpy(&x32, x, sizeof(uint32_t)); + const __m256i shuf_mask = _mm256_set_epi64x( + 0x0303030303030303, 0x0202020202020202, + 0x0101010101010101, 0x0000000000000000); + __m256i bytes = _mm256_shuffle_epi8(_mm256_set1_epi32(x32), shuf_mask); + const __m256i bit_mask = _mm256_set1_epi64x(0x7fbfdfeff7fbfdfe); + bytes = _mm256_or_si256(bytes, bit_mask); + return _mm256_cmpeq_epi8(bytes, _mm256_set1_epi64x(-1)); +} + +// Unpack 32 4-bit fields into 32 bytes +// The output vector contains 32 bytes, each one in [ 0 .. 15 ] interval +static inline __m256i bytes_from_nibbles_32(const uint8_t * rsi) +{ + const __m128i tmp = _mm_loadu_si128((const __m128i *)rsi); + const __m256i bytes = MM256_SET_M128I(_mm_srli_epi16(tmp, 4), tmp); + const __m256i lowMask = _mm256_set1_epi8( 0xF ); + return _mm256_and_si256(lowMask, bytes); +} + +// add int16_t pairwise and return as float vector +static inline __m256 sum_i16_pairs_float(const __m256i x) { + const __m256i ones = _mm256_set1_epi16(1); + const __m256i summed_pairs = _mm256_madd_epi16(ones, x); + return _mm256_cvtepi32_ps(summed_pairs); +} + +static inline __m256 mul_sum_us8_pairs_float(const __m256i ax, const __m256i sy) { +#if __AVXVNNI__ + const __m256i zero = _mm256_setzero_si256(); + const __m256i summed_pairs = _mm256_dpbusd_epi32(zero, ax, sy); + return _mm256_cvtepi32_ps(summed_pairs); +#else + // Perform multiplication and create 16-bit values + const __m256i dot = _mm256_maddubs_epi16(ax, sy); + return sum_i16_pairs_float(dot); +#endif +} + +// multiply int8_t, add results pairwise twice and return as float vector +static inline __m256 mul_sum_i8_pairs_float(const __m256i x, const __m256i y) { +#if __AVXVNNIINT8__ + const __m256i zero = _mm256_setzero_si256(); + const __m256i summed_pairs = _mm256_dpbssd_epi32(zero, x, y); + return _mm256_cvtepi32_ps(summed_pairs); +#else + // Get absolute values of x vectors + const __m256i ax = _mm256_sign_epi8(x, x); + // Sign the values of the y vectors + const __m256i sy = _mm256_sign_epi8(y, x); + return mul_sum_us8_pairs_float(ax, sy); +#endif +} + +static inline __m128i packNibbles( __m256i bytes ) +{ + // Move bits within 16-bit lanes from 0000_abcd_0000_efgh into 0000_0000_abcd_efgh +#if __AVX512F__ + const __m256i bytes_srli_4 = _mm256_srli_epi16(bytes, 4); // 0000_0000_abcd_0000 + bytes = _mm256_or_si256(bytes, bytes_srli_4); // 0000_abcd_abcd_efgh + return _mm256_cvtepi16_epi8(bytes); // abcd_efgh +#else + const __m256i lowByte = _mm256_set1_epi16( 0xFF ); + __m256i high = _mm256_andnot_si256( lowByte, bytes ); + __m256i low = _mm256_and_si256( lowByte, bytes ); + high = _mm256_srli_epi16( high, 4 ); + bytes = _mm256_or_si256( low, high ); + + // Compress uint16_t lanes into bytes + __m128i r0 = _mm256_castsi256_si128( bytes ); + __m128i r1 = _mm256_extracti128_si256( bytes, 1 ); + return _mm_packus_epi16( r0, r1 ); +#endif +} +#elif defined(__AVX__) +// spread 32 bits to 32 bytes { 0x00, 0xFF } +static inline __m256i bytes_from_bits_32(const uint8_t * x) { + uint32_t x32; + memcpy(&x32, x, sizeof(uint32_t)); + const __m128i shuf_maskl = _mm_set_epi64x(0x0101010101010101, 0x0000000000000000); + const __m128i shuf_maskh = _mm_set_epi64x(0x0303030303030303, 0x0202020202020202); + __m128i bytesl = _mm_shuffle_epi8(_mm_set1_epi32(x32), shuf_maskl); + __m128i bytesh = _mm_shuffle_epi8(_mm_set1_epi32(x32), shuf_maskh); + const __m128i bit_mask = _mm_set1_epi64x(0x7fbfdfeff7fbfdfe); + bytesl = _mm_or_si128(bytesl, bit_mask); + bytesh = _mm_or_si128(bytesh, bit_mask); + bytesl = _mm_cmpeq_epi8(bytesl, _mm_set1_epi64x(-1)); + bytesh = _mm_cmpeq_epi8(bytesh, _mm_set1_epi64x(-1)); + return MM256_SET_M128I(bytesh, bytesl); +} + +// Unpack 32 4-bit fields into 32 bytes +// The output vector contains 32 bytes, each one in [ 0 .. 15 ] interval +static inline __m256i bytes_from_nibbles_32(const uint8_t * rsi) +{ + // Load 16 bytes from memory + __m128i tmpl = _mm_loadu_si128((const __m128i *)rsi); + __m128i tmph = _mm_srli_epi16(tmpl, 4); + const __m128i lowMask = _mm_set1_epi8(0xF); + tmpl = _mm_and_si128(lowMask, tmpl); + tmph = _mm_and_si128(lowMask, tmph); + return MM256_SET_M128I(tmph, tmpl); +} + +// add int16_t pairwise and return as float vector +static inline __m256 sum_i16_pairs_float(const __m128i xh, const __m128i xl) { + const __m128i ones = _mm_set1_epi16(1); + const __m128i summed_pairsl = _mm_madd_epi16(ones, xl); + const __m128i summed_pairsh = _mm_madd_epi16(ones, xh); + const __m256i summed_pairs = MM256_SET_M128I(summed_pairsh, summed_pairsl); + return _mm256_cvtepi32_ps(summed_pairs); +} + +static inline __m256 mul_sum_us8_pairs_float(const __m256i ax, const __m256i sy) { + const __m128i axl = _mm256_castsi256_si128(ax); + const __m128i axh = _mm256_extractf128_si256(ax, 1); + const __m128i syl = _mm256_castsi256_si128(sy); + const __m128i syh = _mm256_extractf128_si256(sy, 1); + // Perform multiplication and create 16-bit values + const __m128i dotl = _mm_maddubs_epi16(axl, syl); + const __m128i doth = _mm_maddubs_epi16(axh, syh); + return sum_i16_pairs_float(doth, dotl); +} + +// multiply int8_t, add results pairwise twice and return as float vector +static inline __m256 mul_sum_i8_pairs_float(const __m256i x, const __m256i y) { + const __m128i xl = _mm256_castsi256_si128(x); + const __m128i xh = _mm256_extractf128_si256(x, 1); + const __m128i yl = _mm256_castsi256_si128(y); + const __m128i yh = _mm256_extractf128_si256(y, 1); + // Get absolute values of x vectors + const __m128i axl = _mm_sign_epi8(xl, xl); + const __m128i axh = _mm_sign_epi8(xh, xh); + // Sign the values of the y vectors + const __m128i syl = _mm_sign_epi8(yl, xl); + const __m128i syh = _mm_sign_epi8(yh, xh); + // Perform multiplication and create 16-bit values + const __m128i dotl = _mm_maddubs_epi16(axl, syl); + const __m128i doth = _mm_maddubs_epi16(axh, syh); + return sum_i16_pairs_float(doth, dotl); +} + +static inline __m128i packNibbles( __m128i bytes1, __m128i bytes2 ) +{ + // Move bits within 16-bit lanes from 0000_abcd_0000_efgh into 0000_0000_abcd_efgh + const __m128i lowByte = _mm_set1_epi16( 0xFF ); + __m128i high = _mm_andnot_si128( lowByte, bytes1 ); + __m128i low = _mm_and_si128( lowByte, bytes1 ); + high = _mm_srli_epi16( high, 4 ); + bytes1 = _mm_or_si128( low, high ); + high = _mm_andnot_si128( lowByte, bytes2 ); + low = _mm_and_si128( lowByte, bytes2 ); + high = _mm_srli_epi16( high, 4 ); + bytes2 = _mm_or_si128( low, high ); + + return _mm_packus_epi16( bytes1, bytes2); +} +#endif +#elif defined(__SSSE3__) +// horizontally add 4x4 floats +static inline float hsum_float_4x4(const __m128 a, const __m128 b, const __m128 c, const __m128 d) { + __m128 res_0 =_mm_hadd_ps(a, b); + __m128 res_1 =_mm_hadd_ps(c, d); + __m128 res =_mm_hadd_ps(res_0, res_1); + res =_mm_hadd_ps(res, res); + res =_mm_hadd_ps(res, res); + + return _mm_cvtss_f32(res); +} +#endif // __AVX__ || __AVX2__ || __AVX512F__ +#endif // defined(__AVX__) || defined(__AVX2__) || defined(__AVX512F__) || defined(__SSSE3__) + +#if defined(__ARM_NEON) + +#if !defined(__aarch64__) + +inline static int32_t vaddvq_s32(int32x4_t v) { + return vgetq_lane_s32(v, 0) + vgetq_lane_s32(v, 1) + vgetq_lane_s32(v, 2) + vgetq_lane_s32(v, 3); +} + +inline static float vaddvq_f32(float32x4_t v) { + return vgetq_lane_f32(v, 0) + vgetq_lane_f32(v, 1) + vgetq_lane_f32(v, 2) + vgetq_lane_f32(v, 3); +} + +inline static float vmaxvq_f32(float32x4_t v) { + return + MAX(MAX(vgetq_lane_f32(v, 0), vgetq_lane_f32(v, 1)), + MAX(vgetq_lane_f32(v, 2), vgetq_lane_f32(v, 3))); +} + +inline static int32x4_t vcvtnq_s32_f32(float32x4_t v) { + int32x4_t res; + + res[0] = roundf(vgetq_lane_f32(v, 0)); + res[1] = roundf(vgetq_lane_f32(v, 1)); + res[2] = roundf(vgetq_lane_f32(v, 2)); + res[3] = roundf(vgetq_lane_f32(v, 3)); + + return res; +} + +#endif +#endif + +#if defined(__ARM_NEON) || defined(__wasm_simd128__) +#define B1(c,s,n) 0x ## n ## c , 0x ## n ## s +#define B2(c,s,n) B1(c,s,n ## c), B1(c,s,n ## s) +#define B3(c,s,n) B2(c,s,n ## c), B2(c,s,n ## s) +#define B4(c,s,n) B3(c,s,n ## c), B3(c,s,n ## s) +#define B5(c,s,n) B4(c,s,n ## c), B4(c,s,n ## s) +#define B6(c,s,n) B5(c,s,n ## c), B5(c,s,n ## s) +#define B7(c,s,n) B6(c,s,n ## c), B6(c,s,n ## s) +#define B8(c,s ) B7(c,s, c), B7(c,s, s) + +// precomputed tables for expanding 8bits to 8 bytes: +static const uint64_t table_b2b_0[1 << 8] = { B8(00, 10) }; // ( b) << 4 +static const uint64_t table_b2b_1[1 << 8] = { B8(10, 00) }; // (!b) << 4 +#endif + +// reference implementation for deterministic creation of model files +void quantize_row_q4_0_reference(const float * restrict x, block_q4_0 * restrict y, int k) { + static const int qk = QK4_0; + + assert(k % qk == 0); + + const int nb = k / qk; + + for (int i = 0; i < nb; i++) { + float amax = 0.0f; // absolute max + float max = 0.0f; + + for (int j = 0; j < qk; j++) { + const float v = x[i*qk + j]; + if (amax < fabsf(v)) { + amax = fabsf(v); + max = v; + } + } + + const float d = max / -8; + const float id = d ? 1.0f/d : 0.0f; + + y[i].d = GGML_FP32_TO_FP16(d); + + for (int j = 0; j < qk/2; ++j) { + const float x0 = x[i*qk + 0 + j]*id; + const float x1 = x[i*qk + qk/2 + j]*id; + + const uint8_t xi0 = MIN(15, (int8_t)(x0 + 8.5f)); + const uint8_t xi1 = MIN(15, (int8_t)(x1 + 8.5f)); + + y[i].qs[j] = xi0; + y[i].qs[j] |= xi1 << 4; + } + } +} + +void quantize_row_q4_0(const float * restrict x, void * restrict y, int k) { + quantize_row_q4_0_reference(x, y, k); +} + +void quantize_row_q4_1_reference(const float * restrict x, block_q4_1 * restrict y, int k) { + const int qk = QK4_1; + + assert(k % qk == 0); + + const int nb = k / qk; + + for (int i = 0; i < nb; i++) { + float min = FLT_MAX; + float max = -FLT_MAX; + + for (int j = 0; j < qk; j++) { + const float v = x[i*qk + j]; + + if (v < min) min = v; + if (v > max) max = v; + } + + const float d = (max - min) / ((1 << 4) - 1); + const float id = d ? 1.0f/d : 0.0f; + + y[i].d = GGML_FP32_TO_FP16(d); + y[i].m = GGML_FP32_TO_FP16(min); + + for (int j = 0; j < qk/2; ++j) { + const float x0 = (x[i*qk + 0 + j] - min)*id; + const float x1 = (x[i*qk + qk/2 + j] - min)*id; + + const uint8_t xi0 = MIN(15, (int8_t)(x0 + 0.5f)); + const uint8_t xi1 = MIN(15, (int8_t)(x1 + 0.5f)); + + y[i].qs[j] = xi0; + y[i].qs[j] |= xi1 << 4; + } + } +} + +void quantize_row_q4_1(const float * restrict x, void * restrict y, int k) { + quantize_row_q4_1_reference(x, y, k); +} + +void quantize_row_q5_0_reference(const float * restrict x, block_q5_0 * restrict y, int k) { + static const int qk = QK5_0; + + assert(k % qk == 0); + + const int nb = k / qk; + + for (int i = 0; i < nb; i++) { + float amax = 0.0f; // absolute max + float max = 0.0f; + + for (int j = 0; j < qk; j++) { + const float v = x[i*qk + j]; + if (amax < fabsf(v)) { + amax = fabsf(v); + max = v; + } + } + + const float d = max / -16; + const float id = d ? 1.0f/d : 0.0f; + + y[i].d = GGML_FP32_TO_FP16(d); + + uint32_t qh = 0; + + for (int j = 0; j < qk/2; ++j) { + const float x0 = x[i*qk + 0 + j]*id; + const float x1 = x[i*qk + qk/2 + j]*id; + + const uint8_t xi0 = MIN(31, (int8_t)(x0 + 16.5f)); + const uint8_t xi1 = MIN(31, (int8_t)(x1 + 16.5f)); + + y[i].qs[j] = (xi0 & 0x0F) | ((xi1 & 0x0F) << 4); + + // get the 5-th bit and store it in qh at the right position + qh |= ((xi0 & 0x10u) >> 4) << (j + 0); + qh |= ((xi1 & 0x10u) >> 4) << (j + qk/2); + } + + memcpy(&y[i].qh, &qh, sizeof(qh)); + } +} + +void quantize_row_q5_0(const float * restrict x, void * restrict y, int k) { + quantize_row_q5_0_reference(x, y, k); +} + +void quantize_row_q5_1_reference(const float * restrict x, block_q5_1 * restrict y, int k) { + const int qk = QK5_1; + + assert(k % qk == 0); + + const int nb = k / qk; + + for (int i = 0; i < nb; i++) { + float min = FLT_MAX; + float max = -FLT_MAX; + + for (int j = 0; j < qk; j++) { + const float v = x[i*qk + j]; + + if (v < min) min = v; + if (v > max) max = v; + } + + const float d = (max - min) / ((1 << 5) - 1); + const float id = d ? 1.0f/d : 0.0f; + + y[i].d = GGML_FP32_TO_FP16(d); + y[i].m = GGML_FP32_TO_FP16(min); + + uint32_t qh = 0; + + for (int j = 0; j < qk/2; ++j) { + const float x0 = (x[i*qk + 0 + j] - min)*id; + const float x1 = (x[i*qk + qk/2 + j] - min)*id; + + const uint8_t xi0 = (uint8_t)(x0 + 0.5f); + const uint8_t xi1 = (uint8_t)(x1 + 0.5f); + + y[i].qs[j] = (xi0 & 0x0F) | ((xi1 & 0x0F) << 4); + + // get the 5-th bit and store it in qh at the right position + qh |= ((xi0 & 0x10u) >> 4) << (j + 0); + qh |= ((xi1 & 0x10u) >> 4) << (j + qk/2); + } + + memcpy(&y[i].qh, &qh, sizeof(y[i].qh)); + } +} + +void quantize_row_q5_1(const float * restrict x, void * restrict y, int k) { + quantize_row_q5_1_reference(x, y, k); +} + +// reference implementation for deterministic creation of model files +void quantize_row_q8_0_reference(const float * restrict x, block_q8_0 * restrict y, int k) { + assert(k % QK8_0 == 0); + const int nb = k / QK8_0; + + for (int i = 0; i < nb; i++) { + float amax = 0.0f; // absolute max + + for (int j = 0; j < QK8_0; j++) { + const float v = x[i*QK8_0 + j]; + amax = MAX(amax, fabsf(v)); + } + + const float d = amax / ((1 << 7) - 1); + const float id = d ? 1.0f/d : 0.0f; + + y[i].d = GGML_FP32_TO_FP16(d); + + for (int j = 0; j < QK8_0; ++j) { + const float x0 = x[i*QK8_0 + j]*id; + + y[i].qs[j] = roundf(x0); + } + } +} + +void quantize_row_q8_0(const float * restrict x, void * restrict vy, int k) { + assert(QK8_0 == 32); + assert(k % QK8_0 == 0); + const int nb = k / QK8_0; + + block_q8_0 * restrict y = vy; + +#if defined(__ARM_NEON) + for (int i = 0; i < nb; i++) { + float32x4_t srcv [8]; + float32x4_t asrcv[8]; + float32x4_t amaxv[8]; + + for (int j = 0; j < 8; j++) srcv[j] = vld1q_f32(x + i*32 + 4*j); + for (int j = 0; j < 8; j++) asrcv[j] = vabsq_f32(srcv[j]); + + for (int j = 0; j < 4; j++) amaxv[2*j] = vmaxq_f32(asrcv[2*j], asrcv[2*j+1]); + for (int j = 0; j < 2; j++) amaxv[4*j] = vmaxq_f32(amaxv[4*j], amaxv[4*j+2]); + for (int j = 0; j < 1; j++) amaxv[8*j] = vmaxq_f32(amaxv[8*j], amaxv[8*j+4]); + + const float amax = vmaxvq_f32(amaxv[0]); + + const float d = amax / ((1 << 7) - 1); + const float id = d ? 1.0f/d : 0.0f; + + y[i].d = GGML_FP32_TO_FP16(d); + + for (int j = 0; j < 8; j++) { + const float32x4_t v = vmulq_n_f32(srcv[j], id); + const int32x4_t vi = vcvtnq_s32_f32(v); + + y[i].qs[4*j + 0] = vgetq_lane_s32(vi, 0); + y[i].qs[4*j + 1] = vgetq_lane_s32(vi, 1); + y[i].qs[4*j + 2] = vgetq_lane_s32(vi, 2); + y[i].qs[4*j + 3] = vgetq_lane_s32(vi, 3); + } + } +#elif defined(__wasm_simd128__) + for (int i = 0; i < nb; i++) { + v128_t srcv [8]; + v128_t asrcv[8]; + v128_t amaxv[8]; + + for (int j = 0; j < 8; j++) srcv[j] = wasm_v128_load(x + i*32 + 4*j); + for (int j = 0; j < 8; j++) asrcv[j] = wasm_f32x4_abs(srcv[j]); + + for (int j = 0; j < 4; j++) amaxv[2*j] = wasm_f32x4_max(asrcv[2*j], asrcv[2*j+1]); + for (int j = 0; j < 2; j++) amaxv[4*j] = wasm_f32x4_max(amaxv[4*j], amaxv[4*j+2]); + for (int j = 0; j < 1; j++) amaxv[8*j] = wasm_f32x4_max(amaxv[8*j], amaxv[8*j+4]); + + const float amax = MAX(MAX(wasm_f32x4_extract_lane(amaxv[0], 0), + wasm_f32x4_extract_lane(amaxv[0], 1)), + MAX(wasm_f32x4_extract_lane(amaxv[0], 2), + wasm_f32x4_extract_lane(amaxv[0], 3))); + + const float d = amax / ((1 << 7) - 1); + const float id = d ? 1.0f/d : 0.0f; + + y[i].d = GGML_FP32_TO_FP16(d); + + for (int j = 0; j < 8; j++) { + const v128_t v = wasm_f32x4_mul(srcv[j], wasm_f32x4_splat(id)); + const v128_t vi = wasm_i32x4_trunc_sat_f32x4(v); + + y[i].qs[4*j + 0] = wasm_i32x4_extract_lane(vi, 0); + y[i].qs[4*j + 1] = wasm_i32x4_extract_lane(vi, 1); + y[i].qs[4*j + 2] = wasm_i32x4_extract_lane(vi, 2); + y[i].qs[4*j + 3] = wasm_i32x4_extract_lane(vi, 3); + } + } +#elif defined(__AVX2__) || defined(__AVX__) + for (int i = 0; i < nb; i++) { + // Load elements into 4 AVX vectors + __m256 v0 = _mm256_loadu_ps( x ); + __m256 v1 = _mm256_loadu_ps( x + 8 ); + __m256 v2 = _mm256_loadu_ps( x + 16 ); + __m256 v3 = _mm256_loadu_ps( x + 24 ); + x += 32; + + // Compute max(abs(e)) for the block + const __m256 signBit = _mm256_set1_ps( -0.0f ); + __m256 maxAbs = _mm256_andnot_ps( signBit, v0 ); + maxAbs = _mm256_max_ps( maxAbs, _mm256_andnot_ps( signBit, v1 ) ); + maxAbs = _mm256_max_ps( maxAbs, _mm256_andnot_ps( signBit, v2 ) ); + maxAbs = _mm256_max_ps( maxAbs, _mm256_andnot_ps( signBit, v3 ) ); + + __m128 max4 = _mm_max_ps( _mm256_extractf128_ps( maxAbs, 1 ), _mm256_castps256_ps128( maxAbs ) ); + max4 = _mm_max_ps( max4, _mm_movehl_ps( max4, max4 ) ); + max4 = _mm_max_ss( max4, _mm_movehdup_ps( max4 ) ); + const float maxScalar = _mm_cvtss_f32( max4 ); + + // Quantize these floats + const float d = maxScalar / 127.f; + y[i].d = GGML_FP32_TO_FP16(d); + const float id = ( maxScalar != 0.0f ) ? 127.f / maxScalar : 0.0f; + const __m256 mul = _mm256_set1_ps( id ); + + // Apply the multiplier + v0 = _mm256_mul_ps( v0, mul ); + v1 = _mm256_mul_ps( v1, mul ); + v2 = _mm256_mul_ps( v2, mul ); + v3 = _mm256_mul_ps( v3, mul ); + + // Round to nearest integer + v0 = _mm256_round_ps( v0, _MM_ROUND_NEAREST ); + v1 = _mm256_round_ps( v1, _MM_ROUND_NEAREST ); + v2 = _mm256_round_ps( v2, _MM_ROUND_NEAREST ); + v3 = _mm256_round_ps( v3, _MM_ROUND_NEAREST ); + + // Convert floats to integers + __m256i i0 = _mm256_cvtps_epi32( v0 ); + __m256i i1 = _mm256_cvtps_epi32( v1 ); + __m256i i2 = _mm256_cvtps_epi32( v2 ); + __m256i i3 = _mm256_cvtps_epi32( v3 ); + +#if defined(__AVX2__) + // Convert int32 to int16 + i0 = _mm256_packs_epi32( i0, i1 ); // 0, 1, 2, 3, 8, 9, 10, 11, 4, 5, 6, 7, 12, 13, 14, 15 + i2 = _mm256_packs_epi32( i2, i3 ); // 16, 17, 18, 19, 24, 25, 26, 27, 20, 21, 22, 23, 28, 29, 30, 31 + // Convert int16 to int8 + i0 = _mm256_packs_epi16( i0, i2 ); // 0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19, 24, 25, 26, 27, 4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31 + + // We got our precious signed bytes, but the order is now wrong + // These AVX2 pack instructions process 16-byte pieces independently + // The following instruction is fixing the order + const __m256i perm = _mm256_setr_epi32( 0, 4, 1, 5, 2, 6, 3, 7 ); + i0 = _mm256_permutevar8x32_epi32( i0, perm ); + + _mm256_storeu_si256((__m256i *)y[i].qs, i0); +#else + // Since we don't have in AVX some necessary functions, + // we split the registers in half and call AVX2 analogs from SSE + __m128i ni0 = _mm256_castsi256_si128( i0 ); + __m128i ni1 = _mm256_extractf128_si256( i0, 1); + __m128i ni2 = _mm256_castsi256_si128( i1 ); + __m128i ni3 = _mm256_extractf128_si256( i1, 1); + __m128i ni4 = _mm256_castsi256_si128( i2 ); + __m128i ni5 = _mm256_extractf128_si256( i2, 1); + __m128i ni6 = _mm256_castsi256_si128( i3 ); + __m128i ni7 = _mm256_extractf128_si256( i3, 1); + + // Convert int32 to int16 + ni0 = _mm_packs_epi32( ni0, ni1 ); + ni2 = _mm_packs_epi32( ni2, ni3 ); + ni4 = _mm_packs_epi32( ni4, ni5 ); + ni6 = _mm_packs_epi32( ni6, ni7 ); + // Convert int16 to int8 + ni0 = _mm_packs_epi16( ni0, ni2 ); + ni4 = _mm_packs_epi16( ni4, ni6 ); + + _mm_storeu_si128((__m128i *)(y[i].qs + 0), ni0); + _mm_storeu_si128((__m128i *)(y[i].qs + 16), ni4); +#endif + } +#elif defined(__riscv_v_intrinsic) + + size_t vl = __riscv_vsetvl_e32m4(QK8_0); + + for (int i = 0; i < nb; i++) { + // load elements + vfloat32m4_t v_x = __riscv_vle32_v_f32m4(x+i*QK8_0, vl); + + vfloat32m4_t vfabs = __riscv_vfabs_v_f32m4(v_x, vl); + vfloat32m1_t tmp = __riscv_vfmv_v_f_f32m1(0.0f, vl); + vfloat32m1_t vmax = __riscv_vfredmax_vs_f32m4_f32m1(vfabs, tmp, vl); + float amax = __riscv_vfmv_f_s_f32m1_f32(vmax); + + const float d = amax / ((1 << 7) - 1); + const float id = d ? 1.0f/d : 0.0f; + + y[i].d = GGML_FP32_TO_FP16(d); + + vfloat32m4_t x0 = __riscv_vfmul_vf_f32m4(v_x, id, vl); + + // convert to integer + vint16m2_t vi = __riscv_vfncvt_x_f_w_i16m2(x0, vl); + vint8m1_t vs = __riscv_vncvt_x_x_w_i8m1(vi, vl); + + // store result + __riscv_vse8_v_i8m1(y[i].qs , vs, vl); + } +#else + GGML_UNUSED(nb); + // scalar + quantize_row_q8_0_reference(x, y, k); +#endif +} + +// reference implementation for deterministic creation of model files +void quantize_row_q8_1_reference(const float * restrict x, block_q8_1 * restrict y, int k) { + assert(QK8_1 == 32); + assert(k % QK8_1 == 0); + const int nb = k / QK8_1; + + for (int i = 0; i < nb; i++) { + float amax = 0.0f; // absolute max + + for (int j = 0; j < QK8_1; j++) { + const float v = x[i*QK8_1 + j]; + amax = MAX(amax, fabsf(v)); + } + + const float d = amax / ((1 << 7) - 1); + const float id = d ? 1.0f/d : 0.0f; + + y[i].d = d; + + int sum = 0; + + for (int j = 0; j < QK8_1/2; ++j) { + const float v0 = x[i*QK8_1 + j]*id; + const float v1 = x[i*QK8_1 + QK8_1/2 + j]*id; + + y[i].qs[ j] = roundf(v0); + y[i].qs[QK8_1/2 + j] = roundf(v1); + + sum += y[i].qs[ j]; + sum += y[i].qs[QK8_1/2 + j]; + } + + y[i].s = sum*d; + } +} + +void quantize_row_q8_1(const float * restrict x, void * restrict vy, int k) { + assert(k % QK8_1 == 0); + const int nb = k / QK8_1; + + block_q8_1 * restrict y = vy; + +#if defined(__ARM_NEON) + for (int i = 0; i < nb; i++) { + float32x4_t srcv [8]; + float32x4_t asrcv[8]; + float32x4_t amaxv[8]; + + for (int j = 0; j < 8; j++) srcv[j] = vld1q_f32(x + i*32 + 4*j); + for (int j = 0; j < 8; j++) asrcv[j] = vabsq_f32(srcv[j]); + + for (int j = 0; j < 4; j++) amaxv[2*j] = vmaxq_f32(asrcv[2*j], asrcv[2*j+1]); + for (int j = 0; j < 2; j++) amaxv[4*j] = vmaxq_f32(amaxv[4*j], amaxv[4*j+2]); + for (int j = 0; j < 1; j++) amaxv[8*j] = vmaxq_f32(amaxv[8*j], amaxv[8*j+4]); + + const float amax = vmaxvq_f32(amaxv[0]); + + const float d = amax / ((1 << 7) - 1); + const float id = d ? 1.0f/d : 0.0f; + + y[i].d = d; + + int32x4_t accv = vdupq_n_s32(0); + + for (int j = 0; j < 8; j++) { + const float32x4_t v = vmulq_n_f32(srcv[j], id); + const int32x4_t vi = vcvtnq_s32_f32(v); + + y[i].qs[4*j + 0] = vgetq_lane_s32(vi, 0); + y[i].qs[4*j + 1] = vgetq_lane_s32(vi, 1); + y[i].qs[4*j + 2] = vgetq_lane_s32(vi, 2); + y[i].qs[4*j + 3] = vgetq_lane_s32(vi, 3); + + accv = vaddq_s32(accv, vi); + } + + y[i].s = d * vaddvq_s32(accv); + } +#elif defined(__wasm_simd128__) + for (int i = 0; i < nb; i++) { + v128_t srcv [8]; + v128_t asrcv[8]; + v128_t amaxv[8]; + + for (int j = 0; j < 8; j++) srcv[j] = wasm_v128_load(x + i*32 + 4*j); + for (int j = 0; j < 8; j++) asrcv[j] = wasm_f32x4_abs(srcv[j]); + + for (int j = 0; j < 4; j++) amaxv[2*j] = wasm_f32x4_max(asrcv[2*j], asrcv[2*j+1]); + for (int j = 0; j < 2; j++) amaxv[4*j] = wasm_f32x4_max(amaxv[4*j], amaxv[4*j+2]); + for (int j = 0; j < 1; j++) amaxv[8*j] = wasm_f32x4_max(amaxv[8*j], amaxv[8*j+4]); + + const float amax = MAX(MAX(wasm_f32x4_extract_lane(amaxv[0], 0), + wasm_f32x4_extract_lane(amaxv[0], 1)), + MAX(wasm_f32x4_extract_lane(amaxv[0], 2), + wasm_f32x4_extract_lane(amaxv[0], 3))); + + const float d = amax / ((1 << 7) - 1); + const float id = d ? 1.0f/d : 0.0f; + + y[i].d = d; + + v128_t accv = wasm_i32x4_splat(0); + + for (int j = 0; j < 8; j++) { + const v128_t v = wasm_f32x4_mul(srcv[j], wasm_f32x4_splat(id)); + const v128_t vi = wasm_i32x4_trunc_sat_f32x4(v); + + y[i].qs[4*j + 0] = wasm_i32x4_extract_lane(vi, 0); + y[i].qs[4*j + 1] = wasm_i32x4_extract_lane(vi, 1); + y[i].qs[4*j + 2] = wasm_i32x4_extract_lane(vi, 2); + y[i].qs[4*j + 3] = wasm_i32x4_extract_lane(vi, 3); + + accv = wasm_i32x4_add(accv, vi); + } + + y[i].s = d * (wasm_i32x4_extract_lane(accv, 0) + + wasm_i32x4_extract_lane(accv, 1) + + wasm_i32x4_extract_lane(accv, 2) + + wasm_i32x4_extract_lane(accv, 3)); + } +#elif defined(__AVX2__) || defined(__AVX__) + for (int i = 0; i < nb; i++) { + // Load elements into 4 AVX vectors + __m256 v0 = _mm256_loadu_ps( x ); + __m256 v1 = _mm256_loadu_ps( x + 8 ); + __m256 v2 = _mm256_loadu_ps( x + 16 ); + __m256 v3 = _mm256_loadu_ps( x + 24 ); + x += 32; + + // Compute max(abs(e)) for the block + const __m256 signBit = _mm256_set1_ps( -0.0f ); + __m256 maxAbs = _mm256_andnot_ps( signBit, v0 ); + maxAbs = _mm256_max_ps( maxAbs, _mm256_andnot_ps( signBit, v1 ) ); + maxAbs = _mm256_max_ps( maxAbs, _mm256_andnot_ps( signBit, v2 ) ); + maxAbs = _mm256_max_ps( maxAbs, _mm256_andnot_ps( signBit, v3 ) ); + + __m128 max4 = _mm_max_ps( _mm256_extractf128_ps( maxAbs, 1 ), _mm256_castps256_ps128( maxAbs ) ); + max4 = _mm_max_ps( max4, _mm_movehl_ps( max4, max4 ) ); + max4 = _mm_max_ss( max4, _mm_movehdup_ps( max4 ) ); + const float maxScalar = _mm_cvtss_f32( max4 ); + + // Quantize these floats + const float d = maxScalar / 127.f; + y[i].d = d; + const float id = ( maxScalar != 0.0f ) ? 127.f / maxScalar : 0.0f; + const __m256 mul = _mm256_set1_ps( id ); + + // Apply the multiplier + v0 = _mm256_mul_ps( v0, mul ); + v1 = _mm256_mul_ps( v1, mul ); + v2 = _mm256_mul_ps( v2, mul ); + v3 = _mm256_mul_ps( v3, mul ); + + // Round to nearest integer + v0 = _mm256_round_ps( v0, _MM_ROUND_NEAREST ); + v1 = _mm256_round_ps( v1, _MM_ROUND_NEAREST ); + v2 = _mm256_round_ps( v2, _MM_ROUND_NEAREST ); + v3 = _mm256_round_ps( v3, _MM_ROUND_NEAREST ); + + // Convert floats to integers + __m256i i0 = _mm256_cvtps_epi32( v0 ); + __m256i i1 = _mm256_cvtps_epi32( v1 ); + __m256i i2 = _mm256_cvtps_epi32( v2 ); + __m256i i3 = _mm256_cvtps_epi32( v3 ); + +#if defined(__AVX2__) + // Compute the sum of the quants and set y[i].s + y[i].s = d * hsum_i32_8(_mm256_add_epi32(_mm256_add_epi32(i0, i1), _mm256_add_epi32(i2, i3))); + + // Convert int32 to int16 + i0 = _mm256_packs_epi32( i0, i1 ); // 0, 1, 2, 3, 8, 9, 10, 11, 4, 5, 6, 7, 12, 13, 14, 15 + i2 = _mm256_packs_epi32( i2, i3 ); // 16, 17, 18, 19, 24, 25, 26, 27, 20, 21, 22, 23, 28, 29, 30, 31 + // Convert int16 to int8 + i0 = _mm256_packs_epi16( i0, i2 ); // 0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19, 24, 25, 26, 27, 4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31 + + // We got our precious signed bytes, but the order is now wrong + // These AVX2 pack instructions process 16-byte pieces independently + // The following instruction is fixing the order + const __m256i perm = _mm256_setr_epi32( 0, 4, 1, 5, 2, 6, 3, 7 ); + i0 = _mm256_permutevar8x32_epi32( i0, perm ); + + _mm256_storeu_si256((__m256i *)y[i].qs, i0); +#else + // Since we don't have in AVX some necessary functions, + // we split the registers in half and call AVX2 analogs from SSE + __m128i ni0 = _mm256_castsi256_si128( i0 ); + __m128i ni1 = _mm256_extractf128_si256( i0, 1); + __m128i ni2 = _mm256_castsi256_si128( i1 ); + __m128i ni3 = _mm256_extractf128_si256( i1, 1); + __m128i ni4 = _mm256_castsi256_si128( i2 ); + __m128i ni5 = _mm256_extractf128_si256( i2, 1); + __m128i ni6 = _mm256_castsi256_si128( i3 ); + __m128i ni7 = _mm256_extractf128_si256( i3, 1); + + // Compute the sum of the quants and set y[i].s + const __m128i s0 = _mm_add_epi32(_mm_add_epi32(ni0, ni1), _mm_add_epi32(ni2, ni3)); + const __m128i s1 = _mm_add_epi32(_mm_add_epi32(ni4, ni5), _mm_add_epi32(ni6, ni7)); + y[i].s = d * hsum_i32_4(_mm_add_epi32(s0, s1)); + + // Convert int32 to int16 + ni0 = _mm_packs_epi32( ni0, ni1 ); + ni2 = _mm_packs_epi32( ni2, ni3 ); + ni4 = _mm_packs_epi32( ni4, ni5 ); + ni6 = _mm_packs_epi32( ni6, ni7 ); + // Convert int16 to int8 + ni0 = _mm_packs_epi16( ni0, ni2 ); + ni4 = _mm_packs_epi16( ni4, ni6 ); + + _mm_storeu_si128((__m128i *)(y[i].qs + 0), ni0); + _mm_storeu_si128((__m128i *)(y[i].qs + 16), ni4); +#endif + } +#elif defined(__riscv_v_intrinsic) + + size_t vl = __riscv_vsetvl_e32m4(QK8_1); + + for (int i = 0; i < nb; i++) { + // load elements + vfloat32m4_t v_x = __riscv_vle32_v_f32m4(x+i*QK8_1, vl); + + vfloat32m4_t vfabs = __riscv_vfabs_v_f32m4(v_x, vl); + vfloat32m1_t tmp = __riscv_vfmv_v_f_f32m1(0.0, vl); + vfloat32m1_t vmax = __riscv_vfredmax_vs_f32m4_f32m1(vfabs, tmp, vl); + float amax = __riscv_vfmv_f_s_f32m1_f32(vmax); + + const float d = amax / ((1 << 7) - 1); + const float id = d ? 1.0f/d : 0.0f; + + y[i].d = d; + + vfloat32m4_t x0 = __riscv_vfmul_vf_f32m4(v_x, id, vl); + + // convert to integer + vint16m2_t vi = __riscv_vfncvt_x_f_w_i16m2(x0, vl); + vint8m1_t vs = __riscv_vncvt_x_x_w_i8m1(vi, vl); + + // store result + __riscv_vse8_v_i8m1(y[i].qs , vs, vl); + + // compute sum for y[i].s + vint16m1_t tmp2 = __riscv_vmv_v_x_i16m1(0, vl); + vint16m1_t vwrs = __riscv_vwredsum_vs_i8m1_i16m1(vs, tmp2, vl); + + // set y[i].s + int sum = __riscv_vmv_x_s_i16m1_i16(vwrs); + y[i].s = sum*d; + } +#else + GGML_UNUSED(nb); + // scalar + quantize_row_q8_1_reference(x, y, k); +#endif +} + +void dequantize_row_q4_0(const block_q4_0 * restrict x, float * restrict y, int k) { + static const int qk = QK4_0; + + assert(k % qk == 0); + + const int nb = k / qk; + + for (int i = 0; i < nb; i++) { + const float d = GGML_FP16_TO_FP32(x[i].d); + + for (int j = 0; j < qk/2; ++j) { + const int x0 = (x[i].qs[j] & 0x0F) - 8; + const int x1 = (x[i].qs[j] >> 4) - 8; + + y[i*qk + j + 0 ] = x0*d; + y[i*qk + j + qk/2] = x1*d; + } + } +} + +void dequantize_row_q4_1(const block_q4_1 * restrict x, float * restrict y, int k) { + static const int qk = QK4_1; + + assert(k % qk == 0); + + const int nb = k / qk; + + for (int i = 0; i < nb; i++) { + const float d = GGML_FP16_TO_FP32(x[i].d); + const float m = GGML_FP16_TO_FP32(x[i].m); + + for (int j = 0; j < qk/2; ++j) { + const int x0 = (x[i].qs[j] & 0x0F); + const int x1 = (x[i].qs[j] >> 4); + + y[i*qk + j + 0 ] = x0*d + m; + y[i*qk + j + qk/2] = x1*d + m; + } + } +} + +void dequantize_row_q5_0(const block_q5_0 * restrict x, float * restrict y, int k) { + static const int qk = QK5_0; + + assert(k % qk == 0); + + const int nb = k / qk; + + for (int i = 0; i < nb; i++) { + const float d = GGML_FP16_TO_FP32(x[i].d); + + uint32_t qh; + memcpy(&qh, x[i].qh, sizeof(qh)); + + for (int j = 0; j < qk/2; ++j) { + const uint8_t xh_0 = ((qh >> (j + 0)) << 4) & 0x10; + const uint8_t xh_1 = ((qh >> (j + 12)) ) & 0x10; + + const int32_t x0 = ((x[i].qs[j] & 0x0F) | xh_0) - 16; + const int32_t x1 = ((x[i].qs[j] >> 4) | xh_1) - 16; + + y[i*qk + j + 0 ] = x0*d; + y[i*qk + j + qk/2] = x1*d; + } + } +} + +void dequantize_row_q5_1(const block_q5_1 * restrict x, float * restrict y, int k) { + static const int qk = QK5_1; + + assert(k % qk == 0); + + const int nb = k / qk; + + for (int i = 0; i < nb; i++) { + const float d = GGML_FP16_TO_FP32(x[i].d); + const float m = GGML_FP16_TO_FP32(x[i].m); + + uint32_t qh; + memcpy(&qh, x[i].qh, sizeof(qh)); + + for (int j = 0; j < qk/2; ++j) { + const uint8_t xh_0 = ((qh >> (j + 0)) << 4) & 0x10; + const uint8_t xh_1 = ((qh >> (j + 12)) ) & 0x10; + + const int x0 = (x[i].qs[j] & 0x0F) | xh_0; + const int x1 = (x[i].qs[j] >> 4) | xh_1; + + y[i*qk + j + 0 ] = x0*d + m; + y[i*qk + j + qk/2] = x1*d + m; + } + } +} + +void dequantize_row_q8_0(const block_q8_0 * restrict x, float * restrict y, int k) { + static const int qk = QK8_0; + + assert(k % qk == 0); + + const int nb = k / qk; + + for (int i = 0; i < nb; i++) { + const float d = GGML_FP16_TO_FP32(x[i].d); + + for (int j = 0; j < qk; ++j) { + y[i*qk + j] = x[i].qs[j]*d; + } + } +} + +// +// 2-6 bit quantization in super-blocks +// + +// +// ===================== Helper functions +// +static inline int nearest_int(float fval) { + assert(fval <= 4194303.f); + float val = fval + 12582912.f; + int i; memcpy(&i, &val, sizeof(int)); + return (i & 0x007fffff) - 0x00400000; +} + +static float make_qx_quants(int n, int nmax, const float * restrict x, int8_t * restrict L, int rmse_type) { + float max = 0; + float amax = 0; + for (int i = 0; i < n; ++i) { + float ax = fabsf(x[i]); + if (ax > amax) { amax = ax; max = x[i]; } + } + if (amax < 1e-30f) { // all zero + for (int i = 0; i < n; ++i) { + L[i] = 0; + } + return 0.f; + } + float iscale = -nmax / max; + if (rmse_type == 0) { + for (int i = 0; i < n; ++i) { + int l = nearest_int(iscale * x[i]); + L[i] = nmax + MAX(-nmax, MIN(nmax-1, l)); + } + return 1/iscale; + } + bool return_early = false; + if (rmse_type < 0) { + rmse_type = -rmse_type; + return_early = true; + } + int weight_type = rmse_type%2; + float sumlx = 0; + float suml2 = 0; + for (int i = 0; i < n; ++i) { + int l = nearest_int(iscale * x[i]); + l = MAX(-nmax, MIN(nmax-1, l)); + L[i] = l + nmax; + float w = weight_type == 1 ? x[i] * x[i] : 1; + sumlx += w*x[i]*l; + suml2 += w*l*l; + } + float scale = sumlx/suml2; + if (return_early) return suml2 > 0 ? 0.5f*(scale + 1/iscale) : 1/iscale; + float best = scale * sumlx; + for (int is = -9; is <= 9; ++is) { + if (is == 0) { + continue; + } + iscale = -(nmax + 0.1f*is) / max; + sumlx = suml2 = 0; + for (int i = 0; i < n; ++i) { + int l = nearest_int(iscale * x[i]); + l = MAX(-nmax, MIN(nmax-1, l)); + float w = weight_type == 1 ? x[i] * x[i] : 1; + sumlx += w*x[i]*l; + suml2 += w*l*l; + } + if (suml2 > 0 && sumlx*sumlx > best*suml2) { + for (int i = 0; i < n; ++i) { + int l = nearest_int(iscale * x[i]); + L[i] = nmax + MAX(-nmax, MIN(nmax-1, l)); + } + scale = sumlx/suml2; best = scale*sumlx; + } + } + return scale; +} + +static float make_q3_quants(int n, int nmax, const float * restrict x, int8_t * restrict L, bool do_rmse) { + float max = 0; + float amax = 0; + for (int i = 0; i < n; ++i) { + float ax = fabsf(x[i]); + if (ax > amax) { amax = ax; max = x[i]; } + } + if (!amax) { // all zero + for (int i = 0; i < n; ++i) { L[i] = 0; } + return 0.f; + } + float iscale = -nmax / max; + if (do_rmse) { + float sumlx = 0; + float suml2 = 0; + for (int i = 0; i < n; ++i) { + int l = nearest_int(iscale * x[i]); + l = MAX(-nmax, MIN(nmax-1, l)); + L[i] = l; + float w = x[i]*x[i]; + sumlx += w*x[i]*l; + suml2 += w*l*l; + } + for (int itry = 0; itry < 5; ++itry) { + int n_changed = 0; + for (int i = 0; i < n; ++i) { + float w = x[i]*x[i]; + float slx = sumlx - w*x[i]*L[i]; + if (slx > 0) { + float sl2 = suml2 - w*L[i]*L[i]; + int new_l = nearest_int(x[i] * sl2 / slx); + new_l = MAX(-nmax, MIN(nmax-1, new_l)); + if (new_l != L[i]) { + slx += w*x[i]*new_l; + sl2 += w*new_l*new_l; + if (sl2 > 0 && slx*slx*suml2 > sumlx*sumlx*sl2) { + L[i] = new_l; sumlx = slx; suml2 = sl2; + ++n_changed; + } + } + } + } + if (!n_changed) { + break; + } + } + for (int i = 0; i < n; ++i) { + L[i] += nmax; + } + return sumlx / suml2; + } + for (int i = 0; i < n; ++i) { + int l = nearest_int(iscale * x[i]); + l = MAX(-nmax, MIN(nmax-1, l)); + L[i] = l + nmax; + } + return 1/iscale; +} + +static float make_qkx1_quants(int n, int nmax, const float * restrict x, uint8_t * restrict L, float * restrict the_min, + int ntry, float alpha) { + float min = x[0]; + float max = x[0]; + for (int i = 1; i < n; ++i) { + if (x[i] < min) min = x[i]; + if (x[i] > max) max = x[i]; + } + if (max == min) { + for (int i = 0; i < n; ++i) L[i] = 0; + *the_min = 0; + return 0.f; + } + if (min > 0) min = 0; + float iscale = nmax/(max - min); + float scale = 1/iscale; + for (int itry = 0; itry < ntry; ++itry) { + float sumlx = 0; int suml2 = 0; + bool did_change = false; + for (int i = 0; i < n; ++i) { + int l = nearest_int(iscale*(x[i] - min)); + l = MAX(0, MIN(nmax, l)); + if (l != L[i]) { + L[i] = l; + did_change = true; + } + sumlx += (x[i] - min)*l; + suml2 += l*l; + } + scale = sumlx/suml2; + float sum = 0; + for (int i = 0; i < n; ++i) { + sum += x[i] - scale*L[i]; + } + min = alpha*min + (1 - alpha)*sum/n; + if (min > 0) min = 0; + iscale = 1/scale; + if (!did_change) break; + } + *the_min = -min; + return scale; +} + +static float make_qkx2_quants(int n, int nmax, const float * restrict x, const float * restrict weights, + uint8_t * restrict L, float * restrict the_min, uint8_t * restrict Laux, + float rmin, float rdelta, int nstep, bool use_mad) { + float min = x[0]; + float max = x[0]; + float sum_w = weights[0]; + float sum_x = sum_w * x[0]; + for (int i = 1; i < n; ++i) { + if (x[i] < min) min = x[i]; + if (x[i] > max) max = x[i]; + float w = weights[i]; + sum_w += w; + sum_x += w * x[i]; + } + if (min > 0) min = 0; + if (max == min) { + for (int i = 0; i < n; ++i) L[i] = 0; + *the_min = -min; + return 0.f; + } + float iscale = nmax/(max - min); + float scale = 1/iscale; + float best_mad = 0; + for (int i = 0; i < n; ++i) { + int l = nearest_int(iscale*(x[i] - min)); + L[i] = MAX(0, MIN(nmax, l)); + float diff = scale * L[i] + min - x[i]; + diff = use_mad ? fabsf(diff) : diff * diff; + float w = weights[i]; + best_mad += w * diff; + } + if (nstep < 1) { + *the_min = -min; + return scale; + } + for (int is = 0; is <= nstep; ++is) { + iscale = (rmin + rdelta*is + nmax)/(max - min); + float sum_l = 0, sum_l2 = 0, sum_xl = 0; + for (int i = 0; i < n; ++i) { + int l = nearest_int(iscale*(x[i] - min)); + l = MAX(0, MIN(nmax, l)); + Laux[i] = l; + float w = weights[i]; + sum_l += w*l; + sum_l2 += w*l*l; + sum_xl += w*l*x[i]; + } + float D = sum_w * sum_l2 - sum_l * sum_l; + if (D > 0) { + float this_scale = (sum_w * sum_xl - sum_x * sum_l)/D; + float this_min = (sum_l2 * sum_x - sum_l * sum_xl)/D; + if (this_min > 0) { + this_min = 0; + this_scale = sum_xl / sum_l2; + } + float mad = 0; + for (int i = 0; i < n; ++i) { + float diff = this_scale * Laux[i] + this_min - x[i]; + diff = use_mad ? fabsf(diff) : diff * diff; + float w = weights[i]; + mad += w * diff; + } + if (mad < best_mad) { + for (int i = 0; i < n; ++i) { + L[i] = Laux[i]; + } + best_mad = mad; + scale = this_scale; + min = this_min; + } + } + } + *the_min = -min; + return scale; +} + +#if QK_K == 256 +static inline void get_scale_min_k4(int j, const uint8_t * restrict q, uint8_t * restrict d, uint8_t * restrict m) { + if (j < 4) { + *d = q[j] & 63; *m = q[j + 4] & 63; + } else { + *d = (q[j+4] & 0xF) | ((q[j-4] >> 6) << 4); + *m = (q[j+4] >> 4) | ((q[j-0] >> 6) << 4); + } +} +#endif + +//========================- 2-bit (de)-quantization + +void quantize_row_q2_K_reference(const float * restrict x, block_q2_K * restrict y, int k) { + assert(k % QK_K == 0); + const int nb = k / QK_K; + + uint8_t L[QK_K]; + uint8_t Laux[16]; + float weights[16]; + float mins[QK_K/16]; + float scales[QK_K/16]; + + const float q4scale = 15.f; + + for (int i = 0; i < nb; i++) { + float max_scale = 0; // as we are deducting the min, scales are always positive + float max_min = 0; + for (int j = 0; j < QK_K/16; ++j) { + for (int l = 0; l < 16; ++l) weights[l] = fabsf(x[16*j + l]); + scales[j] = make_qkx2_quants(16, 3, x + 16*j, weights, L + 16*j, &mins[j], Laux, -0.5f, 0.1f, 15, true); + float scale = scales[j]; + if (scale > max_scale) { + max_scale = scale; + } + float min = mins[j]; + if (min > max_min) { + max_min = min; + } + } + + if (max_scale > 0) { + float iscale = q4scale/max_scale; + for (int j = 0; j < QK_K/16; ++j) { + int l = nearest_int(iscale*scales[j]); + y[i].scales[j] = l; + } + y[i].d = GGML_FP32_TO_FP16(max_scale/q4scale); + } else { + for (int j = 0; j < QK_K/16; ++j) y[i].scales[j] = 0; + y[i].d = GGML_FP32_TO_FP16(0.f); + } + if (max_min > 0) { + float iscale = q4scale/max_min; + for (int j = 0; j < QK_K/16; ++j) { + int l = nearest_int(iscale*mins[j]); + y[i].scales[j] |= (l << 4); + } + y[i].dmin = GGML_FP32_TO_FP16(max_min/q4scale); + } else { + y[i].dmin = GGML_FP32_TO_FP16(0.f); + } + for (int j = 0; j < QK_K/16; ++j) { + const float d = GGML_FP16_TO_FP32(y[i].d) * (y[i].scales[j] & 0xF); + if (!d) continue; + const float dm = GGML_FP16_TO_FP32(y[i].dmin) * (y[i].scales[j] >> 4); + for (int ii = 0; ii < 16; ++ii) { + int l = nearest_int((x[16*j + ii] + dm)/d); + l = MAX(0, MIN(3, l)); + L[16*j + ii] = l; + } + } + +#if QK_K == 256 + for (int j = 0; j < QK_K; j += 128) { + for (int l = 0; l < 32; ++l) { + y[i].qs[j/4 + l] = L[j + l] | (L[j + l + 32] << 2) | (L[j + l + 64] << 4) | (L[j + l + 96] << 6); + } + } +#else + for (int l = 0; l < 16; ++l) { + y[i].qs[l] = L[l] | (L[l + 16] << 2) | (L[l + 32] << 4) | (L[l + 48] << 6); + } +#endif + + x += QK_K; + + } +} + +void dequantize_row_q2_K(const block_q2_K * restrict x, float * restrict y, int k) { + assert(k % QK_K == 0); + const int nb = k / QK_K; + + for (int i = 0; i < nb; i++) { + + const float d = GGML_FP16_TO_FP32(x[i].d); + const float min = GGML_FP16_TO_FP32(x[i].dmin); + + const uint8_t * q = x[i].qs; + +#if QK_K == 256 + int is = 0; + float dl, ml; + for (int n = 0; n < QK_K; n += 128) { + int shift = 0; + for (int j = 0; j < 4; ++j) { + + uint8_t sc = x[i].scales[is++]; + dl = d * (sc & 0xF); ml = min * (sc >> 4); + for (int l = 0; l < 16; ++l) *y++ = dl * ((int8_t)((q[l] >> shift) & 3)) - ml; + + sc = x[i].scales[is++]; + dl = d * (sc & 0xF); ml = min * (sc >> 4); + for (int l = 0; l < 16; ++l) *y++ = dl * ((int8_t)((q[l+16] >> shift) & 3)) - ml; + + shift += 2; + } + q += 32; + } +#else + float dl1 = d * (x[i].scales[0] & 0xF), ml1 = min * (x[i].scales[0] >> 4); + float dl2 = d * (x[i].scales[1] & 0xF), ml2 = min * (x[i].scales[1] >> 4); + float dl3 = d * (x[i].scales[2] & 0xF), ml3 = min * (x[i].scales[2] >> 4); + float dl4 = d * (x[i].scales[3] & 0xF), ml4 = min * (x[i].scales[3] >> 4); + for (int l = 0; l < 16; ++l) { + y[l+ 0] = dl1 * ((int8_t)((q[l] >> 0) & 3)) - ml1; + y[l+16] = dl2 * ((int8_t)((q[l] >> 2) & 3)) - ml2; + y[l+32] = dl3 * ((int8_t)((q[l] >> 4) & 3)) - ml3; + y[l+48] = dl4 * ((int8_t)((q[l] >> 6) & 3)) - ml4; + } + y += QK_K; +#endif + } +} + +void quantize_row_q2_K(const float * restrict x, void * restrict vy, int k) { + quantize_row_q2_K_reference(x, vy, k); +} + +size_t ggml_quantize_q2_K(const float * restrict src, void * restrict dst, int n, int k, int64_t * restrict hist) { + (void)hist; // TODO: collect histograms + + for (int j = 0; j < n; j += k) { + block_q2_K * restrict y = (block_q2_K *)dst + j/QK_K; + quantize_row_q2_K_reference(src + j, y, k); + } + return (n/QK_K*sizeof(block_q2_K)); +} + +//========================= 3-bit (de)-quantization + +void quantize_row_q3_K_reference(const float * restrict x, block_q3_K * restrict y, int k) { + assert(k % QK_K == 0); + const int nb = k / QK_K; + + int8_t L[QK_K]; + float scales[QK_K / 16]; + + for (int i = 0; i < nb; i++) { + + float max_scale = 0; + float amax = 0; + for (int j = 0; j < QK_K/16; ++j) { + scales[j] = make_q3_quants(16, 4, x + 16*j, L + 16*j, true); + float scale = fabsf(scales[j]); + if (scale > amax) { + amax = scale; max_scale = scales[j]; + } + } + +#if QK_K == 256 + memset(y[i].scales, 0, 12); + if (max_scale) { + float iscale = -32.f/max_scale; + for (int j = 0; j < QK_K/16; ++j) { + int8_t l = nearest_int(iscale*scales[j]); + l = MAX(-32, MIN(31, l)) + 32; + if (j < 8) { + y[i].scales[j] = l & 0xF; + } else { + y[i].scales[j-8] |= ((l & 0xF) << 4); + } + l >>= 4; + y[i].scales[j%4 + 8] |= (l << (2*(j/4))); + } + y[i].d = GGML_FP32_TO_FP16(1/iscale); + } else { + y[i].d = GGML_FP32_TO_FP16(0.f); + } + + int8_t sc; + for (int j = 0; j < QK_K/16; ++j) { + sc = j < 8 ? y[i].scales[j] & 0xF : y[i].scales[j-8] >> 4; + sc = (sc | (((y[i].scales[8 + j%4] >> (2*(j/4))) & 3) << 4)) - 32; + float d = GGML_FP16_TO_FP32(y[i].d) * sc; + if (!d) { + continue; + } + for (int ii = 0; ii < 16; ++ii) { + int l = nearest_int(x[16*j + ii]/d); + l = MAX(-4, MIN(3, l)); + L[16*j + ii] = l + 4; + } + } +#else + if (max_scale) { + float iscale = -8.f/max_scale; + for (int j = 0; j < QK_K/16; j+=2) { + int l1 = nearest_int(iscale*scales[j]); + l1 = 8 + MAX(-8, MIN(7, l1)); + int l2 = nearest_int(iscale*scales[j+1]); + l2 = 8 + MAX(-8, MIN(7, l2)); + y[i].scales[j/2] = l1 | (l2 << 4); + } + y[i].d = GGML_FP32_TO_FP16(1/iscale); + } else { + for (int j = 0; j < QK_K/16; j+=2) { + y[i].scales[j/2] = 0; + } + y[i].d = GGML_FP32_TO_FP16(0.f); + } + for (int j = 0; j < QK_K/16; ++j) { + int s = j%2 == 0 ? y[i].scales[j/2] & 0xF : y[i].scales[j/2] >> 4; + float d = GGML_FP16_TO_FP32(y[i].d) * (s - 8); + if (!d) { + continue; + } + for (int ii = 0; ii < 16; ++ii) { + int l = nearest_int(x[16*j + ii]/d); + l = MAX(-4, MIN(3, l)); + L[16*j + ii] = l + 4; + } + } +#endif + + memset(y[i].hmask, 0, QK_K/8); + // We put the high-bit for the 1st 8 quants into bit 0, the next 8 into bit 1, etc. + int m = 0; + uint8_t hm = 1; + for (int j = 0; j < QK_K; ++j) { + if (L[j] > 3) { + y[i].hmask[m] |= hm; + L[j] -= 4; + } + if (++m == QK_K/8) { + m = 0; hm <<= 1; + } + } +#if QK_K == 256 + for (int j = 0; j < QK_K; j += 128) { + for (int l = 0; l < 32; ++l) { + y[i].qs[j/4 + l] = L[j + l] | (L[j + l + 32] << 2) | (L[j + l + 64] << 4) | (L[j + l + 96] << 6); + } + } +#else + for (int l = 0; l < 16; ++l) { + y[i].qs[l] = L[l] | (L[l + 16] << 2) | (L[l + 32] << 4) | (L[l + 48] << 6); + } +#endif + + x += QK_K; + } +} + +#if QK_K == 256 +void dequantize_row_q3_K(const block_q3_K * restrict x, float * restrict y, int k) { + assert(k % QK_K == 0); + const int nb = k / QK_K; + + const uint32_t kmask1 = 0x03030303; + const uint32_t kmask2 = 0x0f0f0f0f; + + uint32_t aux[4]; + const int8_t * scales = (const int8_t*)aux; + + for (int i = 0; i < nb; i++) { + + const float d_all = GGML_FP16_TO_FP32(x[i].d); + + const uint8_t * restrict q = x[i].qs; + const uint8_t * restrict hm = x[i].hmask; + uint8_t m = 1; + + memcpy(aux, x[i].scales, 12); + uint32_t tmp = aux[2]; + aux[2] = ((aux[0] >> 4) & kmask2) | (((tmp >> 4) & kmask1) << 4); + aux[3] = ((aux[1] >> 4) & kmask2) | (((tmp >> 6) & kmask1) << 4); + aux[0] = (aux[0] & kmask2) | (((tmp >> 0) & kmask1) << 4); + aux[1] = (aux[1] & kmask2) | (((tmp >> 2) & kmask1) << 4); + + int is = 0; + float dl; + for (int n = 0; n < QK_K; n += 128) { + int shift = 0; + for (int j = 0; j < 4; ++j) { + + dl = d_all * (scales[is++] - 32); + for (int l = 0; l < 16; ++l) { + *y++ = dl * ((int8_t)((q[l+ 0] >> shift) & 3) - ((hm[l+ 0] & m) ? 0 : 4)); + } + + dl = d_all * (scales[is++] - 32); + for (int l = 0; l < 16; ++l) { + *y++ = dl * ((int8_t)((q[l+16] >> shift) & 3) - ((hm[l+16] & m) ? 0 : 4)); + } + + shift += 2; + m <<= 1; + } + q += 32; + } + + } +} +#else +void dequantize_row_q3_K(const block_q3_K * restrict x, float * restrict y, int k) { + assert(k % QK_K == 0); + assert(QK_K == 64); + const int nb = k / QK_K; + + for (int i = 0; i < nb; i++) { + + const float d_all = GGML_FP16_TO_FP32(x[i].d); + + const uint8_t * restrict q = x[i].qs; + const uint8_t * restrict hm = x[i].hmask; + + const float d1 = d_all * ((x[i].scales[0] & 0xF) - 8); + const float d2 = d_all * ((x[i].scales[0] >> 4) - 8); + const float d3 = d_all * ((x[i].scales[1] & 0xF) - 8); + const float d4 = d_all * ((x[i].scales[1] >> 4) - 8); + + for (int l=0; l<8; ++l) { + uint8_t h = hm[l]; + y[l+ 0] = d1 * ((int8_t)((q[l+0] >> 0) & 3) - ((h & 0x01) ? 0 : 4)); + y[l+ 8] = d1 * ((int8_t)((q[l+8] >> 0) & 3) - ((h & 0x02) ? 0 : 4)); + y[l+16] = d2 * ((int8_t)((q[l+0] >> 2) & 3) - ((h & 0x04) ? 0 : 4)); + y[l+24] = d2 * ((int8_t)((q[l+8] >> 2) & 3) - ((h & 0x08) ? 0 : 4)); + y[l+32] = d3 * ((int8_t)((q[l+0] >> 4) & 3) - ((h & 0x10) ? 0 : 4)); + y[l+40] = d3 * ((int8_t)((q[l+8] >> 4) & 3) - ((h & 0x20) ? 0 : 4)); + y[l+48] = d4 * ((int8_t)((q[l+0] >> 6) & 3) - ((h & 0x40) ? 0 : 4)); + y[l+56] = d4 * ((int8_t)((q[l+8] >> 6) & 3) - ((h & 0x80) ? 0 : 4)); + } + y += QK_K; + } +} +#endif + +void quantize_row_q3_K(const float * restrict x, void * restrict vy, int k) { + quantize_row_q3_K_reference(x, vy, k); +} + +size_t ggml_quantize_q3_K(const float * restrict src, void * restrict dst, int n, int k, int64_t * restrict hist) { + (void)hist; // TODO: collect histograms + + for (int j = 0; j < n; j += k) { + block_q3_K * restrict y = (block_q3_K *)dst + j/QK_K; + quantize_row_q3_K_reference(src + j, y, k); + } + return (n/QK_K*sizeof(block_q3_K)); +} + +// ====================== 4-bit (de)-quantization + +void quantize_row_q4_K_reference(const float * restrict x, block_q4_K * restrict y, int k) { + assert(k % QK_K == 0); + const int nb = k / QK_K; + + uint8_t L[QK_K]; + uint8_t Laux[32]; + float weights[32]; + float mins[QK_K/32]; + float scales[QK_K/32]; + + for (int i = 0; i < nb; i++) { + + float max_scale = 0; // as we are deducting the min, scales are always positive + float max_min = 0; + for (int j = 0; j < QK_K/32; ++j) { + //scales[j] = make_qkx1_quants(32, 15, x + 32*j, L + 32*j, &mins[j], 9, 0.5f); + float sum_x2 = 0; + for (int l = 0; l < 32; ++l) sum_x2 += x[32*j + l] * x[32*j + l]; + float av_x = sqrtf(sum_x2/32); + for (int l = 0; l < 32; ++l) weights[l] = av_x + fabsf(x[32*j + l]); + scales[j] = make_qkx2_quants(32, 15, x + 32*j, weights, L + 32*j, &mins[j], Laux, -1.f, 0.1f, 20, false); + float scale = scales[j]; + if (scale > max_scale) { + max_scale = scale; + } + float min = mins[j]; + if (min > max_min) { + max_min = min; + } + } + +#if QK_K == 256 + float inv_scale = max_scale > 0 ? 63.f/max_scale : 0.f; + float inv_min = max_min > 0 ? 63.f/max_min : 0.f; + for (int j = 0; j < QK_K/32; ++j) { + uint8_t ls = nearest_int(inv_scale*scales[j]); + uint8_t lm = nearest_int(inv_min*mins[j]); + ls = MIN(63, ls); + lm = MIN(63, lm); + if (j < 4) { + y[i].scales[j] = ls; + y[i].scales[j+4] = lm; + } else { + y[i].scales[j+4] = (ls & 0xF) | ((lm & 0xF) << 4); + y[i].scales[j-4] |= ((ls >> 4) << 6); + y[i].scales[j-0] |= ((lm >> 4) << 6); + } + } + y[i].d = GGML_FP32_TO_FP16(max_scale/63.f); + y[i].dmin = GGML_FP32_TO_FP16(max_min/63.f); + + uint8_t sc, m; + for (int j = 0; j < QK_K/32; ++j) { + get_scale_min_k4(j, y[i].scales, &sc, &m); + const float d = GGML_FP16_TO_FP32(y[i].d) * sc; + if (!d) continue; + const float dm = GGML_FP16_TO_FP32(y[i].dmin) * m; + for (int ii = 0; ii < 32; ++ii) { + int l = nearest_int((x[32*j + ii] + dm)/d); + l = MAX(0, MIN(15, l)); + L[32*j + ii] = l; + } + } +#else + const float s_factor = 15.f; + float inv_scale = max_scale > 0 ? s_factor/max_scale : 0.f; + float inv_min = max_min > 0 ? s_factor/max_min : 0.f; + int d1 = nearest_int(inv_scale*scales[0]); + int m1 = nearest_int(inv_min*mins[0]); + int d2 = nearest_int(inv_scale*scales[1]); + int m2 = nearest_int(inv_min*mins[1]); + y[i].scales[0] = d1 | (m1 << 4); + y[i].scales[1] = d2 | (m2 << 4); + y[i].d[0] = GGML_FP32_TO_FP16(max_scale/s_factor); + y[i].d[1] = GGML_FP32_TO_FP16(max_min/s_factor); + + float sumlx = 0; + int suml2 = 0; + for (int j = 0; j < QK_K/32; ++j) { + const uint8_t sd = y[i].scales[j] & 0xF; + const uint8_t sm = y[i].scales[j] >> 4; + const float d = GGML_FP16_TO_FP32(y[i].d[0]) * sd; + if (!d) continue; + const float m = GGML_FP16_TO_FP32(y[i].d[1]) * sm; + for (int ii = 0; ii < 32; ++ii) { + int l = nearest_int((x[32*j + ii] + m)/d); + l = MAX(0, MIN(15, l)); + L[32*j + ii] = l; + sumlx += (x[32*j + ii] + m)*l*sd; + suml2 += l*l*sd*sd; + } + } + if (suml2) { + y[i].d[0] = GGML_FP32_TO_FP16(sumlx/suml2); + } +#endif + uint8_t * q = y[i].qs; + for (int j = 0; j < QK_K; j += 64) { + for (int l = 0; l < 32; ++l) q[l] = L[j + l] | (L[j + l + 32] << 4); + q += 32; + } + + x += QK_K; + + } +} + +void dequantize_row_q4_K(const block_q4_K * restrict x, float * restrict y, int k) { + assert(k % QK_K == 0); + const int nb = k / QK_K; + + for (int i = 0; i < nb; i++) { + + const uint8_t * q = x[i].qs; + +#if QK_K == 256 + + const float d = GGML_FP16_TO_FP32(x[i].d); + const float min = GGML_FP16_TO_FP32(x[i].dmin); + + int is = 0; + uint8_t sc, m; + for (int j = 0; j < QK_K; j += 64) { + get_scale_min_k4(is + 0, x[i].scales, &sc, &m); + const float d1 = d * sc; const float m1 = min * m; + get_scale_min_k4(is + 1, x[i].scales, &sc, &m); + const float d2 = d * sc; const float m2 = min * m; + for (int l = 0; l < 32; ++l) *y++ = d1 * (q[l] & 0xF) - m1; + for (int l = 0; l < 32; ++l) *y++ = d2 * (q[l] >> 4) - m2; + q += 32; is += 2; + } +#else + const float dall = GGML_FP16_TO_FP32(x[i].d[0]); + const float mall = GGML_FP16_TO_FP32(x[i].d[1]); + const float d1 = dall * (x[i].scales[0] & 0xF), m1 = mall * (x[i].scales[0] >> 4); + const float d2 = dall * (x[i].scales[1] & 0xF), m2 = mall * (x[i].scales[1] >> 4); + for (int l = 0; l < 32; ++l) { + y[l+ 0] = d1 * (q[l] & 0xF) - m1; + y[l+32] = d2 * (q[l] >> 4) - m2; + } + y += QK_K; +#endif + + } +} + +void quantize_row_q4_K(const float * restrict x, void * restrict vy, int k) { + assert(k % QK_K == 0); + block_q4_K * restrict y = vy; + quantize_row_q4_K_reference(x, y, k); +} + +size_t ggml_quantize_q4_K(const float * restrict src, void * restrict dst, int n, int k, int64_t * restrict hist) { + assert(k % QK_K == 0); + (void)hist; // TODO: collect histograms + + for (int j = 0; j < n; j += k) { + block_q4_K * restrict y = (block_q4_K *)dst + j/QK_K; + quantize_row_q4_K_reference(src + j, y, k); + } + return (n/QK_K*sizeof(block_q4_K)); +} + +// ====================== 5-bit (de)-quantization + +void quantize_row_q5_K_reference(const float * restrict x, block_q5_K * restrict y, int k) { + assert(k % QK_K == 0); + const int nb = k / QK_K; + +#if QK_K == 256 + uint8_t L[QK_K]; + float mins[QK_K/32]; + float scales[QK_K/32]; + float weights[32]; + uint8_t Laux[32]; +#else + int8_t L[QK_K]; + float scales[QK_K/16]; +#endif + + for (int i = 0; i < nb; i++) { + +#if QK_K == 256 + + float max_scale = 0; // as we are deducting the min, scales are always positive + float max_min = 0; + for (int j = 0; j < QK_K/32; ++j) { + //scales[j] = make_qkx1_quants(32, 31, x + 32*j, L + 32*j, &mins[j], 9, 0.5f); + float sum_x2 = 0; + for (int l = 0; l < 32; ++l) sum_x2 += x[32*j + l] * x[32*j + l]; + float av_x = sqrtf(sum_x2/32); + for (int l = 0; l < 32; ++l) weights[l] = av_x + fabsf(x[32*j + l]); + scales[j] = make_qkx2_quants(32, 31, x + 32*j, weights, L + 32*j, &mins[j], Laux, -0.5f, 0.1f, 15, false); + float scale = scales[j]; + if (scale > max_scale) { + max_scale = scale; + } + float min = mins[j]; + if (min > max_min) { + max_min = min; + } + } + + float inv_scale = max_scale > 0 ? 63.f/max_scale : 0.f; + float inv_min = max_min > 0 ? 63.f/max_min : 0.f; + for (int j = 0; j < QK_K/32; ++j) { + uint8_t ls = nearest_int(inv_scale*scales[j]); + uint8_t lm = nearest_int(inv_min*mins[j]); + ls = MIN(63, ls); + lm = MIN(63, lm); + if (j < 4) { + y[i].scales[j] = ls; + y[i].scales[j+4] = lm; + } else { + y[i].scales[j+4] = (ls & 0xF) | ((lm & 0xF) << 4); + y[i].scales[j-4] |= ((ls >> 4) << 6); + y[i].scales[j-0] |= ((lm >> 4) << 6); + } + } + y[i].d = GGML_FP32_TO_FP16(max_scale/63.f); + y[i].dmin = GGML_FP32_TO_FP16(max_min/63.f); + + uint8_t sc, m; + for (int j = 0; j < QK_K/32; ++j) { + get_scale_min_k4(j, y[i].scales, &sc, &m); + const float d = GGML_FP16_TO_FP32(y[i].d) * sc; + if (!d) continue; + const float dm = GGML_FP16_TO_FP32(y[i].dmin) * m; + for (int ii = 0; ii < 32; ++ii) { + int l = nearest_int((x[32*j + ii] + dm)/d); + l = MAX(0, MIN(31, l)); + L[32*j + ii] = l; + } + } + + uint8_t * restrict qh = y[i].qh; + uint8_t * restrict ql = y[i].qs; + memset(qh, 0, QK_K/8); + + uint8_t m1 = 1, m2 = 2; + for (int n = 0; n < QK_K; n += 64) { + for (int j = 0; j < 32; ++j) { + int l1 = L[n + j]; + if (l1 > 15) { + l1 -= 16; qh[j] |= m1; + } + int l2 = L[n + j + 32]; + if (l2 > 15) { + l2 -= 16; qh[j] |= m2; + } + ql[j] = l1 | (l2 << 4); + } + m1 <<= 2; m2 <<= 2; + ql += 32; + } +#else + float max_scale = 0, amax = 0; + for (int j = 0; j < QK_K/16; ++j) { + scales[j] = make_qx_quants(16, 16, x + 16*j, L + 16*j, 1); + float abs_scale = fabsf(scales[j]); + if (abs_scale > amax) { + amax = abs_scale; + max_scale = scales[j]; + } + } + + float iscale = -128.f/max_scale; + for (int j = 0; j < QK_K/16; ++j) { + int l = nearest_int(iscale*scales[j]); + y[i].scales[j] = MAX(-128, MIN(127, l)); + } + y[i].d = GGML_FP32_TO_FP16(1/iscale); + + for (int j = 0; j < QK_K/16; ++j) { + const float d = GGML_FP16_TO_FP32(y[i].d) * y[i].scales[j]; + if (!d) continue; + for (int ii = 0; ii < 16; ++ii) { + int l = nearest_int(x[16*j + ii]/d); + l = MAX(-16, MIN(15, l)); + L[16*j + ii] = l + 16; + } + } + + uint8_t * restrict qh = y[i].qh; + uint8_t * restrict ql = y[i].qs; + memset(qh, 0, QK_K/8); + + for (int j = 0; j < 32; ++j) { + int jm = j%8; + int is = j/8; + int l1 = L[j]; + if (l1 > 15) { + l1 -= 16; qh[jm] |= (1 << is); + } + int l2 = L[j + 32]; + if (l2 > 15) { + l2 -= 16; qh[jm] |= (1 << (4 + is)); + } + ql[j] = l1 | (l2 << 4); + } +#endif + + x += QK_K; + + } +} + +void dequantize_row_q5_K(const block_q5_K * restrict x, float * restrict y, int k) { + assert(k % QK_K == 0); + const int nb = k / QK_K; + + for (int i = 0; i < nb; i++) { + + const uint8_t * ql = x[i].qs; + const uint8_t * qh = x[i].qh; + +#if QK_K == 256 + + const float d = GGML_FP16_TO_FP32(x[i].d); + const float min = GGML_FP16_TO_FP32(x[i].dmin); + + int is = 0; + uint8_t sc, m; + uint8_t u1 = 1, u2 = 2; + for (int j = 0; j < QK_K; j += 64) { + get_scale_min_k4(is + 0, x[i].scales, &sc, &m); + const float d1 = d * sc; const float m1 = min * m; + get_scale_min_k4(is + 1, x[i].scales, &sc, &m); + const float d2 = d * sc; const float m2 = min * m; + for (int l = 0; l < 32; ++l) *y++ = d1 * ((ql[l] & 0xF) + (qh[l] & u1 ? 16 : 0)) - m1; + for (int l = 0; l < 32; ++l) *y++ = d2 * ((ql[l] >> 4) + (qh[l] & u2 ? 16 : 0)) - m2; + ql += 32; is += 2; + u1 <<= 2; u2 <<= 2; + } +#else + float d = GGML_FP16_TO_FP32(x[i].d); + const int8_t * restrict s = x[i].scales; + for (int l = 0; l < 8; ++l) { + y[l+ 0] = d * s[0] * ((ql[l+ 0] & 0xF) - (qh[l] & 0x01 ? 0 : 16)); + y[l+ 8] = d * s[0] * ((ql[l+ 8] & 0xF) - (qh[l] & 0x02 ? 0 : 16)); + y[l+16] = d * s[1] * ((ql[l+16] & 0xF) - (qh[l] & 0x04 ? 0 : 16)); + y[l+24] = d * s[1] * ((ql[l+24] & 0xF) - (qh[l] & 0x08 ? 0 : 16)); + y[l+32] = d * s[2] * ((ql[l+ 0] >> 4) - (qh[l] & 0x10 ? 0 : 16)); + y[l+40] = d * s[2] * ((ql[l+ 8] >> 4) - (qh[l] & 0x20 ? 0 : 16)); + y[l+48] = d * s[3] * ((ql[l+16] >> 4) - (qh[l] & 0x40 ? 0 : 16)); + y[l+56] = d * s[3] * ((ql[l+24] >> 4) - (qh[l] & 0x80 ? 0 : 16)); + } + y += QK_K; +#endif + } +} + +void quantize_row_q5_K(const float * restrict x, void * restrict vy, int k) { + assert(k % QK_K == 0); + block_q5_K * restrict y = vy; + quantize_row_q5_K_reference(x, y, k); +} + +size_t ggml_quantize_q5_K(const float * restrict src, void * restrict dst, int n, int k, int64_t * restrict hist) { + assert(k % QK_K == 0); + (void)hist; // TODO: collect histograms + + for (int j = 0; j < n; j += k) { + block_q5_K * restrict y = (block_q5_K *)dst + j/QK_K; + quantize_row_q5_K_reference(src + j, y, k); + } + return (n/QK_K*sizeof(block_q5_K)); +} + +// ====================== 6-bit (de)-quantization + +void quantize_row_q6_K_reference(const float * restrict x, block_q6_K * restrict y, int k) { + assert(k % QK_K == 0); + const int nb = k / QK_K; + + int8_t L[QK_K]; + float scales[QK_K/16]; + + for (int i = 0; i < nb; i++) { + + float max_scale = 0; + float max_abs_scale = 0; + + for (int ib = 0; ib < QK_K/16; ++ib) { + + const float scale = make_qx_quants(16, 32, x + 16*ib, L + 16*ib, 1); + scales[ib] = scale; + + const float abs_scale = fabsf(scale); + if (abs_scale > max_abs_scale) { + max_abs_scale = abs_scale; + max_scale = scale; + } + + } + + if (!max_abs_scale) { + memset(&y[i], 0, sizeof(block_q6_K)); + y[i].d = GGML_FP32_TO_FP16(0.f); + x += QK_K; + continue; + } + + float iscale = -128.f/max_scale; + y[i].d = GGML_FP32_TO_FP16(1/iscale); + for (int ib = 0; ib < QK_K/16; ++ib) { + y[i].scales[ib] = MIN(127, nearest_int(iscale*scales[ib])); + } + + for (int j = 0; j < QK_K/16; ++j) { + float d = GGML_FP16_TO_FP32(y[i].d) * y[i].scales[j]; + if (!d) { + continue; + } + for (int ii = 0; ii < 16; ++ii) { + int l = nearest_int(x[16*j + ii]/d); + l = MAX(-32, MIN(31, l)); + L[16*j + ii] = l + 32; + } + } + + uint8_t * restrict ql = y[i].ql; + uint8_t * restrict qh = y[i].qh; +#if QK_K == 256 + for (int j = 0; j < QK_K; j += 128) { + for (int l = 0; l < 32; ++l) { + const uint8_t q1 = L[j + l + 0] & 0xF; + const uint8_t q2 = L[j + l + 32] & 0xF; + const uint8_t q3 = L[j + l + 64] & 0xF; + const uint8_t q4 = L[j + l + 96] & 0xF; + ql[l+ 0] = q1 | (q3 << 4); + ql[l+32] = q2 | (q4 << 4); + qh[l] = (L[j + l] >> 4) | ((L[j + l + 32] >> 4) << 2) | ((L[j + l + 64] >> 4) << 4) | ((L[j + l + 96] >> 4) << 6); + } + ql += 64; + qh += 32; + } +#else + for (int l = 0; l < 32; ++l) { + const uint8_t q1 = L[l + 0] & 0xF; + const uint8_t q2 = L[l + 32] & 0xF; + ql[l] = q1 | (q2 << 4); + } + for (int l = 0; l < 16; ++l) { + qh[l] = (L[l] >> 4) | ((L[l + 16] >> 4) << 2) | ((L[l + 32] >> 4) << 4) | ((L[l + 48] >> 4) << 6); + } +#endif + + x += QK_K; + + } +} + +void dequantize_row_q6_K(const block_q6_K * restrict x, float * restrict y, int k) { + assert(k % QK_K == 0); + const int nb = k / QK_K; + + for (int i = 0; i < nb; i++) { + + const float d = GGML_FP16_TO_FP32(x[i].d); + + const uint8_t * restrict ql = x[i].ql; + const uint8_t * restrict qh = x[i].qh; + const int8_t * restrict sc = x[i].scales; + +#if QK_K == 256 + for (int n = 0; n < QK_K; n += 128) { + for (int l = 0; l < 32; ++l) { + int is = l/16; + const int8_t q1 = (int8_t)((ql[l + 0] & 0xF) | (((qh[l] >> 0) & 3) << 4)) - 32; + const int8_t q2 = (int8_t)((ql[l + 32] & 0xF) | (((qh[l] >> 2) & 3) << 4)) - 32; + const int8_t q3 = (int8_t)((ql[l + 0] >> 4) | (((qh[l] >> 4) & 3) << 4)) - 32; + const int8_t q4 = (int8_t)((ql[l + 32] >> 4) | (((qh[l] >> 6) & 3) << 4)) - 32; + y[l + 0] = d * sc[is + 0] * q1; + y[l + 32] = d * sc[is + 2] * q2; + y[l + 64] = d * sc[is + 4] * q3; + y[l + 96] = d * sc[is + 6] * q4; + } + y += 128; + ql += 64; + qh += 32; + sc += 8; + } +#else + for (int l = 0; l < 16; ++l) { + const int8_t q1 = (int8_t)((ql[l+ 0] & 0xF) | (((qh[l] >> 0) & 3) << 4)) - 32; + const int8_t q2 = (int8_t)((ql[l+16] & 0xF) | (((qh[l] >> 2) & 3) << 4)) - 32; + const int8_t q3 = (int8_t)((ql[l+ 0] >> 4) | (((qh[l] >> 4) & 3) << 4)) - 32; + const int8_t q4 = (int8_t)((ql[l+16] >> 4) | (((qh[l] >> 6) & 3) << 4)) - 32; + y[l+ 0] = d * sc[0] * q1; + y[l+16] = d * sc[1] * q2; + y[l+32] = d * sc[2] * q3; + y[l+48] = d * sc[3] * q4; + } + y += 64; +#endif + + } +} + +void quantize_row_q6_K(const float * restrict x, void * restrict vy, int k) { + assert(k % QK_K == 0); + block_q6_K * restrict y = vy; + quantize_row_q6_K_reference(x, y, k); +} + +size_t ggml_quantize_q6_K(const float * src, void * dst, int n, int k, int64_t * hist) { + assert(k % QK_K == 0); + (void)hist; // TODO: collect histograms + + for (int j = 0; j < n; j += k) { + block_q6_K * restrict y = (block_q6_K *)dst + j/QK_K; + quantize_row_q6_K_reference(src + j, y, k); + } + return (n/QK_K*sizeof(block_q6_K)); +} + +//===================================== Q8_K ============================================== + +void quantize_row_q8_K_reference(const float * restrict x, block_q8_K * restrict y, int k) { + assert(k % QK_K == 0); + const int nb = k / QK_K; + + for (int i = 0; i < nb; i++) { + + float max = 0; + float amax = 0; + for (int j = 0; j < QK_K; ++j) { + float ax = fabsf(x[j]); + if (ax > amax) { + amax = ax; max = x[j]; + } + } + if (!amax) { + y[i].d = 0; + memset(y[i].qs, 0, QK_K); + x += QK_K; + continue; + } + const float iscale = -128.f/max; + for (int j = 0; j < QK_K; ++j) { + int v = nearest_int(iscale*x[j]); + y[i].qs[j] = MIN(127, v); + } + for (int j = 0; j < QK_K/16; ++j) { + int sum = 0; + for (int ii = 0; ii < 16; ++ii) { + sum += y[i].qs[j*16 + ii]; + } + y[i].bsums[j] = sum; + } + y[i].d = 1/iscale; + x += QK_K; + } +} + +void dequantize_row_q8_K(const block_q8_K * restrict x, float * restrict y, int k) { + assert(k % QK_K == 0); + const int nb = k / QK_K; + + for (int i = 0; i < nb; i++) { + for (int j = 0; j < QK_K; ++j) { + *y++ = x[i].d * x[i].qs[j]; + } + } +} + +void quantize_row_q8_K(const float * restrict x, void * restrict y, int k) { + quantize_row_q8_K_reference(x, y, k); +} + +//===================================== Dot ptoducts ================================= + +// +// Helper functions +// +#if __AVX__ || __AVX2__ || __AVX512F__ + +// shuffles to pick the required scales in dot products +static inline __m256i get_scale_shuffle_q3k(int i) { + static const uint8_t k_shuffle[128] = { + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, + 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, + 8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11, + 12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13, 14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15, + }; + return _mm256_loadu_si256((const __m256i*)k_shuffle + i); +} +static inline __m256i get_scale_shuffle_k4(int i) { + static const uint8_t k_shuffle[256] = { + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, + 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, + 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, + 8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9, + 10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11, + 12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13,12,13, + 14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15,14,15 + }; + return _mm256_loadu_si256((const __m256i*)k_shuffle + i); +} +static inline __m128i get_scale_shuffle(int i) { + static const uint8_t k_shuffle[128] = { + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, + 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, + 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, + 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, + 10,10,10,10,10,10,10,10, 11,11,11,11,11,11,11,11, + 12,12,12,12,12,12,12,12, 13,13,13,13,13,13,13,13, + 14,14,14,14,14,14,14,14, 15,15,15,15,15,15,15,15 + }; + return _mm_loadu_si128((const __m128i*)k_shuffle + i); +} +#endif + +void ggml_vec_dot_q4_0_q8_0(int n, float * restrict s, const void * restrict vx, const void * restrict vy) { + const int qk = QK8_0; + const int nb = n / qk; + + assert(n % qk == 0); + + const block_q4_0 * restrict x = vx; + const block_q8_0 * restrict y = vy; + +#if defined(__ARM_NEON) + float32x4_t sumv0 = vdupq_n_f32(0.0f); + float32x4_t sumv1 = vdupq_n_f32(0.0f); + + assert(nb % 2 == 0); // TODO: handle odd nb + + for (int i = 0; i < nb; i += 2) { + const block_q4_0 * restrict x0 = &x[i + 0]; + const block_q4_0 * restrict x1 = &x[i + 1]; + const block_q8_0 * restrict y0 = &y[i + 0]; + const block_q8_0 * restrict y1 = &y[i + 1]; + + const uint8x16_t m4b = vdupq_n_u8(0x0F); + const int8x16_t s8b = vdupq_n_s8(0x8); + + const uint8x16_t v0_0 = vld1q_u8(x0->qs); + const uint8x16_t v0_1 = vld1q_u8(x1->qs); + + // 4-bit -> 8-bit + const int8x16_t v0_0l = vreinterpretq_s8_u8(vandq_u8 (v0_0, m4b)); + const int8x16_t v0_0h = vreinterpretq_s8_u8(vshrq_n_u8(v0_0, 4)); + const int8x16_t v0_1l = vreinterpretq_s8_u8(vandq_u8 (v0_1, m4b)); + const int8x16_t v0_1h = vreinterpretq_s8_u8(vshrq_n_u8(v0_1, 4)); + + // sub 8 + const int8x16_t v0_0ls = vsubq_s8(v0_0l, s8b); + const int8x16_t v0_0hs = vsubq_s8(v0_0h, s8b); + const int8x16_t v0_1ls = vsubq_s8(v0_1l, s8b); + const int8x16_t v0_1hs = vsubq_s8(v0_1h, s8b); + + // load y + const int8x16_t v1_0l = vld1q_s8(y0->qs); + const int8x16_t v1_0h = vld1q_s8(y0->qs + 16); + const int8x16_t v1_1l = vld1q_s8(y1->qs); + const int8x16_t v1_1h = vld1q_s8(y1->qs + 16); + +#if defined(__ARM_FEATURE_DOTPROD) + // dot product into int32x4_t + const int32x4_t p_0 = vdotq_s32(vdotq_s32(vdupq_n_s32(0), v0_0ls, v1_0l), v0_0hs, v1_0h); + const int32x4_t p_1 = vdotq_s32(vdotq_s32(vdupq_n_s32(0), v0_1ls, v1_1l), v0_1hs, v1_1h); + + sumv0 = vmlaq_n_f32(sumv0, vcvtq_f32_s32(p_0), GGML_FP16_TO_FP32(x0->d)*GGML_FP16_TO_FP32(y0->d)); + sumv1 = vmlaq_n_f32(sumv1, vcvtq_f32_s32(p_1), GGML_FP16_TO_FP32(x1->d)*GGML_FP16_TO_FP32(y1->d)); +#else + const int16x8_t pl0l = vmull_s8(vget_low_s8 (v0_0ls), vget_low_s8 (v1_0l)); + const int16x8_t pl0h = vmull_s8(vget_high_s8(v0_0ls), vget_high_s8(v1_0l)); + const int16x8_t ph0l = vmull_s8(vget_low_s8 (v0_0hs), vget_low_s8 (v1_0h)); + const int16x8_t ph0h = vmull_s8(vget_high_s8(v0_0hs), vget_high_s8(v1_0h)); + + const int16x8_t pl1l = vmull_s8(vget_low_s8 (v0_1ls), vget_low_s8 (v1_1l)); + const int16x8_t pl1h = vmull_s8(vget_high_s8(v0_1ls), vget_high_s8(v1_1l)); + const int16x8_t ph1l = vmull_s8(vget_low_s8 (v0_1hs), vget_low_s8 (v1_1h)); + const int16x8_t ph1h = vmull_s8(vget_high_s8(v0_1hs), vget_high_s8(v1_1h)); + + const int32x4_t pl0 = vaddq_s32(vpaddlq_s16(pl0l), vpaddlq_s16(pl0h)); + const int32x4_t ph0 = vaddq_s32(vpaddlq_s16(ph0l), vpaddlq_s16(ph0h)); + const int32x4_t pl1 = vaddq_s32(vpaddlq_s16(pl1l), vpaddlq_s16(pl1h)); + const int32x4_t ph1 = vaddq_s32(vpaddlq_s16(ph1l), vpaddlq_s16(ph1h)); + + sumv0 = vmlaq_n_f32(sumv0, vcvtq_f32_s32(vaddq_s32(pl0, ph0)), GGML_FP16_TO_FP32(x0->d)*GGML_FP16_TO_FP32(y0->d)); + sumv1 = vmlaq_n_f32(sumv1, vcvtq_f32_s32(vaddq_s32(pl1, ph1)), GGML_FP16_TO_FP32(x1->d)*GGML_FP16_TO_FP32(y1->d)); +#endif + } + + *s = vaddvq_f32(sumv0) + vaddvq_f32(sumv1); +#elif defined(__AVX2__) + // Initialize accumulator with zeros + __m256 acc = _mm256_setzero_ps(); + + // Main loop + for (int i = 0; i < nb; ++i) { + /* Compute combined scale for the block */ + const __m256 d = _mm256_set1_ps( GGML_FP16_TO_FP32(x[i].d) * GGML_FP16_TO_FP32(y[i].d) ); + + __m256i bx = bytes_from_nibbles_32(x[i].qs); + + // Now we have a vector with bytes in [ 0 .. 15 ] interval. Offset them into [ -8 .. +7 ] interval. + const __m256i off = _mm256_set1_epi8( 8 ); + bx = _mm256_sub_epi8( bx, off ); + + __m256i by = _mm256_loadu_si256((const __m256i *)y[i].qs); + + const __m256 q = mul_sum_i8_pairs_float(bx, by); + + /* Multiply q with scale and accumulate */ + acc = _mm256_fmadd_ps( d, q, acc ); + } + + *s = hsum_float_8(acc); +#elif defined(__AVX__) + // Initialize accumulator with zeros + __m256 acc = _mm256_setzero_ps(); + + // Main loop + for (int i = 0; i < nb; ++i) { + // Compute combined scale for the block + const __m256 d = _mm256_set1_ps( GGML_FP16_TO_FP32(x[i].d) * GGML_FP16_TO_FP32(y[i].d) ); + + const __m128i lowMask = _mm_set1_epi8(0xF); + const __m128i off = _mm_set1_epi8(8); + + const __m128i tmp = _mm_loadu_si128((const __m128i *)x[i].qs); + + __m128i bx = _mm_and_si128(lowMask, tmp); + __m128i by = _mm_loadu_si128((const __m128i *)y[i].qs); + bx = _mm_sub_epi8(bx, off); + const __m128i i32_0 = mul_sum_i8_pairs(bx, by); + + bx = _mm_and_si128(lowMask, _mm_srli_epi64(tmp, 4)); + by = _mm_loadu_si128((const __m128i *)(y[i].qs + 16)); + bx = _mm_sub_epi8(bx, off); + const __m128i i32_1 = mul_sum_i8_pairs(bx, by); + + // Convert int32_t to float + __m256 p = _mm256_cvtepi32_ps(MM256_SET_M128I(i32_0, i32_1)); + + // Apply the scale, and accumulate + acc = _mm256_add_ps(_mm256_mul_ps( d, p ), acc); + } + + *s = hsum_float_8(acc); +#elif defined(__SSSE3__) + // set constants + const __m128i lowMask = _mm_set1_epi8(0xF); + const __m128i off = _mm_set1_epi8(8); + + // Initialize accumulator with zeros + __m128 acc_0 = _mm_setzero_ps(); + __m128 acc_1 = _mm_setzero_ps(); + __m128 acc_2 = _mm_setzero_ps(); + __m128 acc_3 = _mm_setzero_ps(); + + // First round without accumulation + { + _mm_prefetch(&x[0] + sizeof(block_q4_0), _MM_HINT_T0); + _mm_prefetch(&y[0] + sizeof(block_q8_0), _MM_HINT_T0); + + // Compute combined scale for the block 0 and 1 + const __m128 d_0_1 = _mm_set1_ps( GGML_FP16_TO_FP32(x[0].d) * GGML_FP16_TO_FP32(y[0].d) ); + + const __m128i tmp_0_1 = _mm_loadu_si128((const __m128i *)x[0].qs); + + __m128i bx_0 = _mm_and_si128(lowMask, tmp_0_1); + __m128i by_0 = _mm_loadu_si128((const __m128i *)y[0].qs); + bx_0 = _mm_sub_epi8(bx_0, off); + const __m128i i32_0 = mul_sum_i8_pairs(bx_0, by_0); + + __m128i bx_1 = _mm_and_si128(lowMask, _mm_srli_epi64(tmp_0_1, 4)); + __m128i by_1 = _mm_loadu_si128((const __m128i *)(y[0].qs + 16)); + bx_1 = _mm_sub_epi8(bx_1, off); + const __m128i i32_1 = mul_sum_i8_pairs(bx_1, by_1); + + _mm_prefetch(&x[1] + sizeof(block_q4_0), _MM_HINT_T0); + _mm_prefetch(&y[1] + sizeof(block_q8_0), _MM_HINT_T0); + + // Compute combined scale for the block 2 and 3 + const __m128 d_2_3 = _mm_set1_ps( GGML_FP16_TO_FP32(x[1].d) * GGML_FP16_TO_FP32(y[1].d) ); + + const __m128i tmp_2_3 = _mm_loadu_si128((const __m128i *)x[1].qs); + + __m128i bx_2 = _mm_and_si128(lowMask, tmp_2_3); + __m128i by_2 = _mm_loadu_si128((const __m128i *)y[1].qs); + bx_2 = _mm_sub_epi8(bx_2, off); + const __m128i i32_2 = mul_sum_i8_pairs(bx_2, by_2); + + __m128i bx_3 = _mm_and_si128(lowMask, _mm_srli_epi64(tmp_2_3, 4)); + __m128i by_3 = _mm_loadu_si128((const __m128i *)(y[1].qs + 16)); + bx_3 = _mm_sub_epi8(bx_3, off); + const __m128i i32_3 = mul_sum_i8_pairs(bx_3, by_3); + + // Convert int32_t to float + __m128 p0 = _mm_cvtepi32_ps(i32_0); + __m128 p1 = _mm_cvtepi32_ps(i32_1); + __m128 p2 = _mm_cvtepi32_ps(i32_2); + __m128 p3 = _mm_cvtepi32_ps(i32_3); + + // Apply the scale + acc_0 = _mm_mul_ps( d_0_1, p0 ); + acc_1 = _mm_mul_ps( d_0_1, p1 ); + acc_2 = _mm_mul_ps( d_2_3, p2 ); + acc_3 = _mm_mul_ps( d_2_3, p3 ); + } + + assert(nb % 2 == 0); // TODO: handle odd nb + + // Main loop + for (int i = 2; i < nb; i+=2) { + _mm_prefetch(&x[i] + sizeof(block_q4_0), _MM_HINT_T0); + _mm_prefetch(&y[i] + sizeof(block_q8_0), _MM_HINT_T0); + + // Compute combined scale for the block 0 and 1 + const __m128 d_0_1 = _mm_set1_ps( GGML_FP16_TO_FP32(x[i].d) * GGML_FP16_TO_FP32(y[i].d) ); + + const __m128i tmp_0_1 = _mm_loadu_si128((const __m128i *)x[i].qs); + + __m128i bx_0 = _mm_and_si128(lowMask, tmp_0_1); + __m128i by_0 = _mm_loadu_si128((const __m128i *)y[i].qs); + bx_0 = _mm_sub_epi8(bx_0, off); + const __m128i i32_0 = mul_sum_i8_pairs(bx_0, by_0); + + __m128i bx_1 = _mm_and_si128(lowMask, _mm_srli_epi64(tmp_0_1, 4)); + __m128i by_1 = _mm_loadu_si128((const __m128i *)(y[i].qs + 16)); + bx_1 = _mm_sub_epi8(bx_1, off); + const __m128i i32_1 = mul_sum_i8_pairs(bx_1, by_1); + + _mm_prefetch(&x[i] + 2 * sizeof(block_q4_0), _MM_HINT_T0); + _mm_prefetch(&y[i] + 2 * sizeof(block_q8_0), _MM_HINT_T0); + + // Compute combined scale for the block 2 and 3 + const __m128 d_2_3 = _mm_set1_ps( GGML_FP16_TO_FP32(x[i + 1].d) * GGML_FP16_TO_FP32(y[i + 1].d) ); + + const __m128i tmp_2_3 = _mm_loadu_si128((const __m128i *)x[i + 1].qs); + + __m128i bx_2 = _mm_and_si128(lowMask, tmp_2_3); + __m128i by_2 = _mm_loadu_si128((const __m128i *)y[i + 1].qs); + bx_2 = _mm_sub_epi8(bx_2, off); + const __m128i i32_2 = mul_sum_i8_pairs(bx_2, by_2); + + __m128i bx_3 = _mm_and_si128(lowMask, _mm_srli_epi64(tmp_2_3, 4)); + __m128i by_3 = _mm_loadu_si128((const __m128i *)(y[i + 1].qs + 16)); + bx_3 = _mm_sub_epi8(bx_3, off); + const __m128i i32_3 = mul_sum_i8_pairs(bx_3, by_3); + + // Convert int32_t to float + __m128 p0 = _mm_cvtepi32_ps(i32_0); + __m128 p1 = _mm_cvtepi32_ps(i32_1); + __m128 p2 = _mm_cvtepi32_ps(i32_2); + __m128 p3 = _mm_cvtepi32_ps(i32_3); + + // Apply the scale + __m128 p0_d = _mm_mul_ps( d_0_1, p0 ); + __m128 p1_d = _mm_mul_ps( d_0_1, p1 ); + __m128 p2_d = _mm_mul_ps( d_2_3, p2 ); + __m128 p3_d = _mm_mul_ps( d_2_3, p3 ); + + // Acummulate + acc_0 = _mm_add_ps(p0_d, acc_0); + acc_1 = _mm_add_ps(p1_d, acc_1); + acc_2 = _mm_add_ps(p2_d, acc_2); + acc_3 = _mm_add_ps(p3_d, acc_3); + } + + *s = hsum_float_4x4(acc_0, acc_1, acc_2, acc_3); +#elif defined(__riscv_v_intrinsic) + float sumf = 0.0; + + size_t vl = __riscv_vsetvl_e8m1(qk/2); + + for (int i = 0; i < nb; i++) { + // load elements + vuint8mf2_t tx = __riscv_vle8_v_u8mf2(x[i].qs, vl); + + vint8mf2_t y0 = __riscv_vle8_v_i8mf2(y[i].qs, vl); + vint8mf2_t y1 = __riscv_vle8_v_i8mf2(y[i].qs+16, vl); + + // mask and store lower part of x, and then upper part + vuint8mf2_t x_a = __riscv_vand_vx_u8mf2(tx, 0x0F, vl); + vuint8mf2_t x_l = __riscv_vsrl_vx_u8mf2(tx, 0x04, vl); + + vint8mf2_t x_ai = __riscv_vreinterpret_v_u8mf2_i8mf2(x_a); + vint8mf2_t x_li = __riscv_vreinterpret_v_u8mf2_i8mf2(x_l); + + // subtract offset + vint8mf2_t v0 = __riscv_vsub_vx_i8mf2(x_ai, 8, vl); + vint8mf2_t v1 = __riscv_vsub_vx_i8mf2(x_li, 8, vl); + + vint16m1_t vec_mul1 = __riscv_vwmul_vv_i16m1(v0, y0, vl); + vint16m1_t vec_mul2 = __riscv_vwmul_vv_i16m1(v1, y1, vl); + + vint32m1_t vec_zero = __riscv_vmv_v_x_i32m1(0, vl); + + vint32m1_t vs1 = __riscv_vwredsum_vs_i16m1_i32m1(vec_mul1, vec_zero, vl); + vint32m1_t vs2 = __riscv_vwredsum_vs_i16m1_i32m1(vec_mul2, vs1, vl); + + int sumi = __riscv_vmv_x_s_i32m1_i32(vs2); + + sumf += sumi*GGML_FP16_TO_FP32(x[i].d)*GGML_FP16_TO_FP32(y[i].d); + } + + *s = sumf; +#else + // scalar + float sumf = 0.0; + + for (int i = 0; i < nb; i++) { + int sumi = 0; + + for (int j = 0; j < qk/2; ++j) { + const int v0 = (x[i].qs[j] & 0x0F) - 8; + const int v1 = (x[i].qs[j] >> 4) - 8; + + sumi += (v0 * y[i].qs[j]) + (v1 * y[i].qs[j + qk/2]); + } + + sumf += sumi*GGML_FP16_TO_FP32(x[i].d)*GGML_FP16_TO_FP32(y[i].d); + } + + *s = sumf; +#endif +} + +void ggml_vec_dot_q4_1_q8_1(const int n, float * restrict s, const void * restrict vx, const void * restrict vy) { + const int qk = QK8_1; + const int nb = n / qk; + + assert(n % qk == 0); + + const block_q4_1 * restrict x = vx; + const block_q8_1 * restrict y = vy; + + // TODO: add WASM SIMD +#if defined(__ARM_NEON) + float32x4_t sumv0 = vdupq_n_f32(0.0f); + float32x4_t sumv1 = vdupq_n_f32(0.0f); + + float summs = 0; + + assert(nb % 2 == 0); // TODO: handle odd nb + + for (int i = 0; i < nb; i += 2) { + const block_q4_1 * restrict x0 = &x[i + 0]; + const block_q4_1 * restrict x1 = &x[i + 1]; + const block_q8_1 * restrict y0 = &y[i + 0]; + const block_q8_1 * restrict y1 = &y[i + 1]; + + summs += GGML_FP16_TO_FP32(x0->m) * y0->s + GGML_FP16_TO_FP32(x1->m) * y1->s; + + const uint8x16_t m4b = vdupq_n_u8(0x0F); + + const uint8x16_t v0_0 = vld1q_u8(x0->qs); + const uint8x16_t v0_1 = vld1q_u8(x1->qs); + + // 4-bit -> 8-bit + const int8x16_t v0_0l = vreinterpretq_s8_u8(vandq_u8 (v0_0, m4b)); + const int8x16_t v0_0h = vreinterpretq_s8_u8(vshrq_n_u8(v0_0, 4)); + const int8x16_t v0_1l = vreinterpretq_s8_u8(vandq_u8 (v0_1, m4b)); + const int8x16_t v0_1h = vreinterpretq_s8_u8(vshrq_n_u8(v0_1, 4)); + + // load y + const int8x16_t v1_0l = vld1q_s8(y0->qs); + const int8x16_t v1_0h = vld1q_s8(y0->qs + 16); + const int8x16_t v1_1l = vld1q_s8(y1->qs); + const int8x16_t v1_1h = vld1q_s8(y1->qs + 16); + +#if defined(__ARM_FEATURE_DOTPROD) + // dot product into int32x4_t + const int32x4_t p_0 = vdotq_s32(vdotq_s32(vdupq_n_s32(0), v0_0l, v1_0l), v0_0h, v1_0h); + const int32x4_t p_1 = vdotq_s32(vdotq_s32(vdupq_n_s32(0), v0_1l, v1_1l), v0_1h, v1_1h); + + sumv0 = vmlaq_n_f32(sumv0, vcvtq_f32_s32(p_0), GGML_FP16_TO_FP32(x0->d)*y0->d); + sumv1 = vmlaq_n_f32(sumv1, vcvtq_f32_s32(p_1), GGML_FP16_TO_FP32(x1->d)*y1->d); +#else + const int16x8_t pl0l = vmull_s8(vget_low_s8 (v0_0l), vget_low_s8 (v1_0l)); + const int16x8_t pl0h = vmull_s8(vget_high_s8(v0_0l), vget_high_s8(v1_0l)); + const int16x8_t ph0l = vmull_s8(vget_low_s8 (v0_0h), vget_low_s8 (v1_0h)); + const int16x8_t ph0h = vmull_s8(vget_high_s8(v0_0h), vget_high_s8(v1_0h)); + + const int16x8_t pl1l = vmull_s8(vget_low_s8 (v0_1l), vget_low_s8 (v1_1l)); + const int16x8_t pl1h = vmull_s8(vget_high_s8(v0_1l), vget_high_s8(v1_1l)); + const int16x8_t ph1l = vmull_s8(vget_low_s8 (v0_1h), vget_low_s8 (v1_1h)); + const int16x8_t ph1h = vmull_s8(vget_high_s8(v0_1h), vget_high_s8(v1_1h)); + + const int32x4_t pl0 = vaddq_s32(vpaddlq_s16(pl0l), vpaddlq_s16(pl0h)); + const int32x4_t ph0 = vaddq_s32(vpaddlq_s16(ph0l), vpaddlq_s16(ph0h)); + const int32x4_t pl1 = vaddq_s32(vpaddlq_s16(pl1l), vpaddlq_s16(pl1h)); + const int32x4_t ph1 = vaddq_s32(vpaddlq_s16(ph1l), vpaddlq_s16(ph1h)); + + sumv0 = vmlaq_n_f32(sumv0, vcvtq_f32_s32(vaddq_s32(pl0, ph0)), GGML_FP16_TO_FP32(x0->d)*y0->d); + sumv1 = vmlaq_n_f32(sumv1, vcvtq_f32_s32(vaddq_s32(pl1, ph1)), GGML_FP16_TO_FP32(x1->d)*y1->d); +#endif + } + + *s = vaddvq_f32(sumv0) + vaddvq_f32(sumv1) + summs; +#elif defined(__AVX2__) || defined(__AVX__) + // Initialize accumulator with zeros + __m256 acc = _mm256_setzero_ps(); + + float summs = 0; + + // Main loop + for (int i = 0; i < nb; ++i) { + const float d0 = GGML_FP16_TO_FP32(x[i].d); + const float d1 = y[i].d; + + summs += GGML_FP16_TO_FP32(x[i].m) * y[i].s; + + const __m256 d0v = _mm256_set1_ps( d0 ); + const __m256 d1v = _mm256_set1_ps( d1 ); + + // Compute combined scales + const __m256 d0d1 = _mm256_mul_ps( d0v, d1v ); + + // Load 16 bytes, and unpack 4 bit fields into bytes, making 32 bytes + const __m256i bx = bytes_from_nibbles_32(x[i].qs); + const __m256i by = _mm256_loadu_si256( (const __m256i *)y[i].qs ); + + const __m256 xy = mul_sum_us8_pairs_float(bx, by); + + // Accumulate d0*d1*x*y +#if defined(__AVX2__) + acc = _mm256_fmadd_ps( d0d1, xy, acc ); +#else + acc = _mm256_add_ps( _mm256_mul_ps( d0d1, xy ), acc ); +#endif + } + + *s = hsum_float_8(acc) + summs; +#elif defined(__riscv_v_intrinsic) + float sumf = 0.0; + + size_t vl = __riscv_vsetvl_e8m1(qk/2); + + for (int i = 0; i < nb; i++) { + // load elements + vuint8mf2_t tx = __riscv_vle8_v_u8mf2(x[i].qs, vl); + + vint8mf2_t y0 = __riscv_vle8_v_i8mf2(y[i].qs, vl); + vint8mf2_t y1 = __riscv_vle8_v_i8mf2(y[i].qs+16, vl); + + // mask and store lower part of x, and then upper part + vuint8mf2_t x_a = __riscv_vand_vx_u8mf2(tx, 0x0F, vl); + vuint8mf2_t x_l = __riscv_vsrl_vx_u8mf2(tx, 0x04, vl); + + vint8mf2_t v0 = __riscv_vreinterpret_v_u8mf2_i8mf2(x_a); + vint8mf2_t v1 = __riscv_vreinterpret_v_u8mf2_i8mf2(x_l); + + vint16m1_t vec_mul1 = __riscv_vwmul_vv_i16m1(v0, y0, vl); + vint16m1_t vec_mul2 = __riscv_vwmul_vv_i16m1(v1, y1, vl); + + vint32m1_t vec_zero = __riscv_vmv_v_x_i32m1(0, vl); + + vint32m1_t vs1 = __riscv_vwredsum_vs_i16m1_i32m1(vec_mul1, vec_zero, vl); + vint32m1_t vs2 = __riscv_vwredsum_vs_i16m1_i32m1(vec_mul2, vs1, vl); + + int sumi = __riscv_vmv_x_s_i32m1_i32(vs2); + + sumf += (GGML_FP16_TO_FP32(x[i].d)*y[i].d)*sumi + GGML_FP16_TO_FP32(x[i].m)*y[i].s; + } + + *s = sumf; +#else + // scalar + float sumf = 0.0; + + for (int i = 0; i < nb; i++) { + int sumi = 0; + + for (int j = 0; j < qk/2; ++j) { + const int v0 = (x[i].qs[j] & 0x0F); + const int v1 = (x[i].qs[j] >> 4); + + sumi += (v0 * y[i].qs[j]) + (v1 * y[i].qs[j + qk/2]); + } + + sumf += (GGML_FP16_TO_FP32(x[i].d)*y[i].d)*sumi + GGML_FP16_TO_FP32(x[i].m)*y[i].s; + } + + *s = sumf; +#endif +} + +void ggml_vec_dot_q5_0_q8_0(const int n, float * restrict s, const void * restrict vx, const void * restrict vy) { + const int qk = QK8_0; + const int nb = n / qk; + + assert(n % qk == 0); + assert(qk == QK5_0); + + const block_q5_0 * restrict x = vx; + const block_q8_0 * restrict y = vy; + +#if defined(__ARM_NEON) + float32x4_t sumv0 = vdupq_n_f32(0.0f); + float32x4_t sumv1 = vdupq_n_f32(0.0f); + + uint32_t qh0; + uint32_t qh1; + + uint64_t tmp0[4]; + uint64_t tmp1[4]; + + assert(nb % 2 == 0); // TODO: handle odd nb + + for (int i = 0; i < nb; i += 2) { + const block_q5_0 * restrict x0 = &x[i]; + const block_q5_0 * restrict x1 = &x[i + 1]; + const block_q8_0 * restrict y0 = &y[i]; + const block_q8_0 * restrict y1 = &y[i + 1]; + + const uint8x16_t m4b = vdupq_n_u8(0x0F); + + // extract the 5th bit via lookup table ((!b) << 4) + memcpy(&qh0, x0->qh, sizeof(qh0)); + memcpy(&qh1, x1->qh, sizeof(qh1)); + + tmp0[0] = table_b2b_1[(qh0 >> 0) & 0xFF]; + tmp0[1] = table_b2b_1[(qh0 >> 8) & 0xFF]; + tmp0[2] = table_b2b_1[(qh0 >> 16) & 0xFF]; + tmp0[3] = table_b2b_1[(qh0 >> 24) ]; + + tmp1[0] = table_b2b_1[(qh1 >> 0) & 0xFF]; + tmp1[1] = table_b2b_1[(qh1 >> 8) & 0xFF]; + tmp1[2] = table_b2b_1[(qh1 >> 16) & 0xFF]; + tmp1[3] = table_b2b_1[(qh1 >> 24) ]; + + const int8x16_t qhl0 = vld1q_s8((const int8_t *)(tmp0 + 0)); + const int8x16_t qhh0 = vld1q_s8((const int8_t *)(tmp0 + 2)); + const int8x16_t qhl1 = vld1q_s8((const int8_t *)(tmp1 + 0)); + const int8x16_t qhh1 = vld1q_s8((const int8_t *)(tmp1 + 2)); + + const uint8x16_t v0_0 = vld1q_u8(x0->qs); + const uint8x16_t v0_1 = vld1q_u8(x1->qs); + + // 4-bit -> 8-bit + int8x16_t v0_0l = vreinterpretq_s8_u8(vandq_u8 (v0_0, m4b)); + int8x16_t v0_0h = vreinterpretq_s8_u8(vshrq_n_u8(v0_0, 4)); + int8x16_t v0_1l = vreinterpretq_s8_u8(vandq_u8 (v0_1, m4b)); + int8x16_t v0_1h = vreinterpretq_s8_u8(vshrq_n_u8(v0_1, 4)); + + // add high bit and sub 16 (equivalent to sub 0x10 when bit is zero) + const int8x16_t v0_0lf = vsubq_s8(v0_0l, qhl0); + const int8x16_t v0_0hf = vsubq_s8(v0_0h, qhh0); + const int8x16_t v0_1lf = vsubq_s8(v0_1l, qhl1); + const int8x16_t v0_1hf = vsubq_s8(v0_1h, qhh1); + + // load y + const int8x16_t v1_0l = vld1q_s8(y0->qs); + const int8x16_t v1_0h = vld1q_s8(y0->qs + 16); + const int8x16_t v1_1l = vld1q_s8(y1->qs); + const int8x16_t v1_1h = vld1q_s8(y1->qs + 16); + +#if defined(__ARM_FEATURE_DOTPROD) + sumv0 = vmlaq_n_f32(sumv0, vcvtq_f32_s32(vaddq_s32( + vdotq_s32(vdupq_n_s32(0), v0_0lf, v1_0l), + vdotq_s32(vdupq_n_s32(0), v0_0hf, v1_0h))), GGML_FP16_TO_FP32(x0->d)*GGML_FP16_TO_FP32(y0->d)); + sumv1 = vmlaq_n_f32(sumv1, vcvtq_f32_s32(vaddq_s32( + vdotq_s32(vdupq_n_s32(0), v0_1lf, v1_1l), + vdotq_s32(vdupq_n_s32(0), v0_1hf, v1_1h))), GGML_FP16_TO_FP32(x1->d)*GGML_FP16_TO_FP32(y1->d)); +#else + const int16x8_t pl0l = vmull_s8(vget_low_s8 (v0_0lf), vget_low_s8 (v1_0l)); + const int16x8_t pl0h = vmull_s8(vget_high_s8(v0_0lf), vget_high_s8(v1_0l)); + const int16x8_t ph0l = vmull_s8(vget_low_s8 (v0_0hf), vget_low_s8 (v1_0h)); + const int16x8_t ph0h = vmull_s8(vget_high_s8(v0_0hf), vget_high_s8(v1_0h)); + + const int16x8_t pl1l = vmull_s8(vget_low_s8 (v0_1lf), vget_low_s8 (v1_1l)); + const int16x8_t pl1h = vmull_s8(vget_high_s8(v0_1lf), vget_high_s8(v1_1l)); + const int16x8_t ph1l = vmull_s8(vget_low_s8 (v0_1hf), vget_low_s8 (v1_1h)); + const int16x8_t ph1h = vmull_s8(vget_high_s8(v0_1hf), vget_high_s8(v1_1h)); + + const int32x4_t pl0 = vaddq_s32(vpaddlq_s16(pl0l), vpaddlq_s16(pl0h)); + const int32x4_t ph0 = vaddq_s32(vpaddlq_s16(ph0l), vpaddlq_s16(ph0h)); + const int32x4_t pl1 = vaddq_s32(vpaddlq_s16(pl1l), vpaddlq_s16(pl1h)); + const int32x4_t ph1 = vaddq_s32(vpaddlq_s16(ph1l), vpaddlq_s16(ph1h)); + + sumv0 = vmlaq_n_f32(sumv0, vcvtq_f32_s32(vaddq_s32(pl0, ph0)), GGML_FP16_TO_FP32(x0->d)*GGML_FP16_TO_FP32(y0->d)); + sumv1 = vmlaq_n_f32(sumv1, vcvtq_f32_s32(vaddq_s32(pl1, ph1)), GGML_FP16_TO_FP32(x1->d)*GGML_FP16_TO_FP32(y1->d)); +#endif + } + + *s = vaddvq_f32(sumv0) + vaddvq_f32(sumv1); +#elif defined(__wasm_simd128__) + v128_t sumv = wasm_f32x4_splat(0.0f); + + uint32_t qh; + uint64_t tmp[4]; + + // TODO: check if unrolling this is better + for (int i = 0; i < nb; ++i) { + const block_q5_0 * restrict x0 = &x[i]; + const block_q8_0 * restrict y0 = &y[i]; + + const v128_t m4b = wasm_i8x16_splat(0x0F); + + // extract the 5th bit + memcpy(&qh, x0->qh, sizeof(qh)); + + tmp[0] = table_b2b_1[(qh >> 0) & 0xFF]; + tmp[1] = table_b2b_1[(qh >> 8) & 0xFF]; + tmp[2] = table_b2b_1[(qh >> 16) & 0xFF]; + tmp[3] = table_b2b_1[(qh >> 24) ]; + + const v128_t qhl = wasm_v128_load(tmp + 0); + const v128_t qhh = wasm_v128_load(tmp + 2); + + const v128_t v0 = wasm_v128_load(x0->qs); + + // 4-bit -> 8-bit + const v128_t v0l = wasm_v128_and (v0, m4b); + const v128_t v0h = wasm_u8x16_shr(v0, 4); + + // add high bit and sub 16 (equivalent to sub 0x10 when bit is zero) + const v128_t v0lf = wasm_i8x16_sub(v0l, qhl); + const v128_t v0hf = wasm_i8x16_sub(v0h, qhh); + + // load y + const v128_t v1l = wasm_v128_load(y0->qs); + const v128_t v1h = wasm_v128_load(y0->qs + 16); + + // int8x16 -> int16x8 + const v128_t v0lfl = wasm_i16x8_extend_low_i8x16 (v0lf); + const v128_t v0lfh = wasm_i16x8_extend_high_i8x16(v0lf); + const v128_t v0hfl = wasm_i16x8_extend_low_i8x16 (v0hf); + const v128_t v0hfh = wasm_i16x8_extend_high_i8x16(v0hf); + + const v128_t v1ll = wasm_i16x8_extend_low_i8x16 (v1l); + const v128_t v1lh = wasm_i16x8_extend_high_i8x16(v1l); + const v128_t v1hl = wasm_i16x8_extend_low_i8x16 (v1h); + const v128_t v1hh = wasm_i16x8_extend_high_i8x16(v1h); + + // dot product + sumv = wasm_f32x4_add(sumv, wasm_f32x4_mul(wasm_f32x4_convert_i32x4( + wasm_i32x4_add( + wasm_i32x4_add(wasm_i32x4_dot_i16x8(v0lfl, v1ll), + wasm_i32x4_dot_i16x8(v0lfh, v1lh)), + wasm_i32x4_add(wasm_i32x4_dot_i16x8(v0hfl, v1hl), + wasm_i32x4_dot_i16x8(v0hfh, v1hh)))), + wasm_f32x4_splat(GGML_FP16_TO_FP32(x0->d) * GGML_FP16_TO_FP32(y0->d)))); + } + + *s = wasm_f32x4_extract_lane(sumv, 0) + wasm_f32x4_extract_lane(sumv, 1) + + wasm_f32x4_extract_lane(sumv, 2) + wasm_f32x4_extract_lane(sumv, 3); +#elif defined(__AVX2__) + // Initialize accumulator with zeros + __m256 acc = _mm256_setzero_ps(); + + // Main loop + for (int i = 0; i < nb; i++) { + /* Compute combined scale for the block */ + const __m256 d = _mm256_set1_ps(GGML_FP16_TO_FP32(x[i].d) * GGML_FP16_TO_FP32(y[i].d)); + + __m256i bx = bytes_from_nibbles_32(x[i].qs); + __m256i bxhi = bytes_from_bits_32(x[i].qh); + bxhi = _mm256_andnot_si256(bxhi, _mm256_set1_epi8((char)0xF0)); + bx = _mm256_or_si256(bx, bxhi); + + __m256i by = _mm256_loadu_si256((const __m256i *)y[i].qs); + + const __m256 q = mul_sum_i8_pairs_float(bx, by); + + /* Multiply q with scale and accumulate */ + acc = _mm256_fmadd_ps(d, q, acc); + } + + *s = hsum_float_8(acc); +#elif defined(__AVX__) + // Initialize accumulator with zeros + __m256 acc = _mm256_setzero_ps(); + __m128i mask = _mm_set1_epi8((char)0xF0); + + // Main loop + for (int i = 0; i < nb; i++) { + /* Compute combined scale for the block */ + const __m256 d = _mm256_set1_ps(GGML_FP16_TO_FP32(x[i].d) * GGML_FP16_TO_FP32(y[i].d)); + + __m256i bx = bytes_from_nibbles_32(x[i].qs); + const __m256i bxhi = bytes_from_bits_32(x[i].qh); + __m128i bxhil = _mm256_castsi256_si128(bxhi); + __m128i bxhih = _mm256_extractf128_si256(bxhi, 1); + bxhil = _mm_andnot_si128(bxhil, mask); + bxhih = _mm_andnot_si128(bxhih, mask); + __m128i bxl = _mm256_castsi256_si128(bx); + __m128i bxh = _mm256_extractf128_si256(bx, 1); + bxl = _mm_or_si128(bxl, bxhil); + bxh = _mm_or_si128(bxh, bxhih); + bx = MM256_SET_M128I(bxh, bxl); + + const __m256i by = _mm256_loadu_si256((const __m256i *)y[i].qs); + + const __m256 q = mul_sum_i8_pairs_float(bx, by); + + /* Multiply q with scale and accumulate */ + acc = _mm256_add_ps(_mm256_mul_ps(d, q), acc); + } + + *s = hsum_float_8(acc); +#elif defined(__riscv_v_intrinsic) + float sumf = 0.0; + + uint32_t qh; + + size_t vl = __riscv_vsetvl_e8m1(qk/2); + + // These tempory registers are for masking and shift operations + vuint32m2_t vt_1 = __riscv_vid_v_u32m2(vl); + vuint32m2_t vt_2 = __riscv_vsll_vv_u32m2(__riscv_vmv_v_x_u32m2(1, vl), vt_1, vl); + + vuint32m2_t vt_3 = __riscv_vsll_vx_u32m2(vt_2, 16, vl); + vuint32m2_t vt_4 = __riscv_vadd_vx_u32m2(vt_1, 12, vl); + + for (int i = 0; i < nb; i++) { + memcpy(&qh, x[i].qh, sizeof(uint32_t)); + + // ((qh & (1u << (j + 0 ))) >> (j + 0 )) << 4; + vuint32m2_t xha_0 = __riscv_vand_vx_u32m2(vt_2, qh, vl); + vuint32m2_t xhr_0 = __riscv_vsrl_vv_u32m2(xha_0, vt_1, vl); + vuint32m2_t xhl_0 = __riscv_vsll_vx_u32m2(xhr_0, 4, vl); + + // ((qh & (1u << (j + 16))) >> (j + 12)); + vuint32m2_t xha_1 = __riscv_vand_vx_u32m2(vt_3, qh, vl); + vuint32m2_t xhl_1 = __riscv_vsrl_vv_u32m2(xha_1, vt_4, vl); + + // narrowing + vuint16m1_t xhc_0 = __riscv_vncvt_x_x_w_u16m1(xhl_0, vl); + vuint8mf2_t xh_0 = __riscv_vncvt_x_x_w_u8mf2(xhc_0, vl); + + vuint16m1_t xhc_1 = __riscv_vncvt_x_x_w_u16m1(xhl_1, vl); + vuint8mf2_t xh_1 = __riscv_vncvt_x_x_w_u8mf2(xhc_1, vl); + + // load + vuint8mf2_t tx = __riscv_vle8_v_u8mf2(x[i].qs, vl); + + vint8mf2_t y0 = __riscv_vle8_v_i8mf2(y[i].qs, vl); + vint8mf2_t y1 = __riscv_vle8_v_i8mf2(y[i].qs+16, vl); + + vuint8mf2_t x_at = __riscv_vand_vx_u8mf2(tx, 0x0F, vl); + vuint8mf2_t x_lt = __riscv_vsrl_vx_u8mf2(tx, 0x04, vl); + + vuint8mf2_t x_a = __riscv_vor_vv_u8mf2(x_at, xh_0, vl); + vuint8mf2_t x_l = __riscv_vor_vv_u8mf2(x_lt, xh_1, vl); + + vint8mf2_t x_ai = __riscv_vreinterpret_v_u8mf2_i8mf2(x_a); + vint8mf2_t x_li = __riscv_vreinterpret_v_u8mf2_i8mf2(x_l); + + vint8mf2_t v0 = __riscv_vsub_vx_i8mf2(x_ai, 16, vl); + vint8mf2_t v1 = __riscv_vsub_vx_i8mf2(x_li, 16, vl); + + vint16m1_t vec_mul1 = __riscv_vwmul_vv_i16m1(v0, y0, vl); + vint16m1_t vec_mul2 = __riscv_vwmul_vv_i16m1(v1, y1, vl); + + vint32m1_t vec_zero = __riscv_vmv_v_x_i32m1(0, vl); + + vint32m1_t vs1 = __riscv_vwredsum_vs_i16m1_i32m1(vec_mul1, vec_zero, vl); + vint32m1_t vs2 = __riscv_vwredsum_vs_i16m1_i32m1(vec_mul2, vs1, vl); + + int sumi = __riscv_vmv_x_s_i32m1_i32(vs2); + + sumf += (GGML_FP16_TO_FP32(x[i].d)*GGML_FP16_TO_FP32(y[i].d)) * sumi; + } + + *s = sumf; +#else + // scalar + float sumf = 0.0; + + for (int i = 0; i < nb; i++) { + uint32_t qh; + memcpy(&qh, x[i].qh, sizeof(qh)); + + int sumi = 0; + + for (int j = 0; j < qk/2; ++j) { + const uint8_t xh_0 = ((qh & (1u << (j + 0 ))) >> (j + 0 )) << 4; + const uint8_t xh_1 = ((qh & (1u << (j + 16))) >> (j + 12)); + + const int32_t x0 = ((x[i].qs[j] & 0x0F) | xh_0) - 16; + const int32_t x1 = ((x[i].qs[j] >> 4) | xh_1) - 16; + + sumi += (x0 * y[i].qs[j]) + (x1 * y[i].qs[j + qk/2]); + } + + sumf += (GGML_FP16_TO_FP32(x[i].d)*GGML_FP16_TO_FP32(y[i].d)) * sumi; + } + + *s = sumf; +#endif +} + +void ggml_vec_dot_q5_1_q8_1(const int n, float * restrict s, const void * restrict vx, const void * restrict vy) { + const int qk = QK8_1; + const int nb = n / qk; + + assert(n % qk == 0); + assert(qk == QK5_1); + + const block_q5_1 * restrict x = vx; + const block_q8_1 * restrict y = vy; + +#if defined(__ARM_NEON) + float32x4_t sumv0 = vdupq_n_f32(0.0f); + float32x4_t sumv1 = vdupq_n_f32(0.0f); + + float summs0 = 0.0f; + float summs1 = 0.0f; + + uint32_t qh0; + uint32_t qh1; + + uint64_t tmp0[4]; + uint64_t tmp1[4]; + + assert(nb % 2 == 0); // TODO: handle odd nb + + for (int i = 0; i < nb; i += 2) { + const block_q5_1 * restrict x0 = &x[i]; + const block_q5_1 * restrict x1 = &x[i + 1]; + const block_q8_1 * restrict y0 = &y[i]; + const block_q8_1 * restrict y1 = &y[i + 1]; + + const uint8x16_t m4b = vdupq_n_u8(0x0F); + + summs0 += GGML_FP16_TO_FP32(x0->m) * y0->s; + summs1 += GGML_FP16_TO_FP32(x1->m) * y1->s; + + // extract the 5th bit via lookup table ((b) << 4) + memcpy(&qh0, x0->qh, sizeof(qh0)); + memcpy(&qh1, x1->qh, sizeof(qh1)); + + tmp0[0] = table_b2b_0[(qh0 >> 0) & 0xFF]; + tmp0[1] = table_b2b_0[(qh0 >> 8) & 0xFF]; + tmp0[2] = table_b2b_0[(qh0 >> 16) & 0xFF]; + tmp0[3] = table_b2b_0[(qh0 >> 24) ]; + + tmp1[0] = table_b2b_0[(qh1 >> 0) & 0xFF]; + tmp1[1] = table_b2b_0[(qh1 >> 8) & 0xFF]; + tmp1[2] = table_b2b_0[(qh1 >> 16) & 0xFF]; + tmp1[3] = table_b2b_0[(qh1 >> 24) ]; + + const int8x16_t qhl0 = vld1q_s8((const int8_t *)(tmp0 + 0)); + const int8x16_t qhh0 = vld1q_s8((const int8_t *)(tmp0 + 2)); + const int8x16_t qhl1 = vld1q_s8((const int8_t *)(tmp1 + 0)); + const int8x16_t qhh1 = vld1q_s8((const int8_t *)(tmp1 + 2)); + + const uint8x16_t v0_0 = vld1q_u8(x0->qs); + const uint8x16_t v0_1 = vld1q_u8(x1->qs); + + // 4-bit -> 8-bit + const int8x16_t v0_0l = vreinterpretq_s8_u8(vandq_u8 (v0_0, m4b)); + const int8x16_t v0_0h = vreinterpretq_s8_u8(vshrq_n_u8(v0_0, 4)); + const int8x16_t v0_1l = vreinterpretq_s8_u8(vandq_u8 (v0_1, m4b)); + const int8x16_t v0_1h = vreinterpretq_s8_u8(vshrq_n_u8(v0_1, 4)); + + // add high bit + const int8x16_t v0_0lf = vorrq_s8(v0_0l, qhl0); + const int8x16_t v0_0hf = vorrq_s8(v0_0h, qhh0); + const int8x16_t v0_1lf = vorrq_s8(v0_1l, qhl1); + const int8x16_t v0_1hf = vorrq_s8(v0_1h, qhh1); + + // load y + const int8x16_t v1_0l = vld1q_s8(y0->qs); + const int8x16_t v1_0h = vld1q_s8(y0->qs + 16); + const int8x16_t v1_1l = vld1q_s8(y1->qs); + const int8x16_t v1_1h = vld1q_s8(y1->qs + 16); + +#if defined(__ARM_FEATURE_DOTPROD) + sumv0 = vmlaq_n_f32(sumv0, vcvtq_f32_s32(vaddq_s32( + vdotq_s32(vdupq_n_s32(0), v0_0lf, v1_0l), + vdotq_s32(vdupq_n_s32(0), v0_0hf, v1_0h))), GGML_FP16_TO_FP32(x0->d)*y0->d); + sumv1 = vmlaq_n_f32(sumv1, vcvtq_f32_s32(vaddq_s32( + vdotq_s32(vdupq_n_s32(0), v0_1lf, v1_1l), + vdotq_s32(vdupq_n_s32(0), v0_1hf, v1_1h))), GGML_FP16_TO_FP32(x1->d)*y1->d); +#else + const int16x8_t pl0l = vmull_s8(vget_low_s8 (v0_0lf), vget_low_s8 (v1_0l)); + const int16x8_t pl0h = vmull_s8(vget_high_s8(v0_0lf), vget_high_s8(v1_0l)); + const int16x8_t ph0l = vmull_s8(vget_low_s8 (v0_0hf), vget_low_s8 (v1_0h)); + const int16x8_t ph0h = vmull_s8(vget_high_s8(v0_0hf), vget_high_s8(v1_0h)); + + const int16x8_t pl1l = vmull_s8(vget_low_s8 (v0_1lf), vget_low_s8 (v1_1l)); + const int16x8_t pl1h = vmull_s8(vget_high_s8(v0_1lf), vget_high_s8(v1_1l)); + const int16x8_t ph1l = vmull_s8(vget_low_s8 (v0_1hf), vget_low_s8 (v1_1h)); + const int16x8_t ph1h = vmull_s8(vget_high_s8(v0_1hf), vget_high_s8(v1_1h)); + + const int32x4_t pl0 = vaddq_s32(vpaddlq_s16(pl0l), vpaddlq_s16(pl0h)); + const int32x4_t ph0 = vaddq_s32(vpaddlq_s16(ph0l), vpaddlq_s16(ph0h)); + const int32x4_t pl1 = vaddq_s32(vpaddlq_s16(pl1l), vpaddlq_s16(pl1h)); + const int32x4_t ph1 = vaddq_s32(vpaddlq_s16(ph1l), vpaddlq_s16(ph1h)); + + sumv0 = vmlaq_n_f32(sumv0, vcvtq_f32_s32(vaddq_s32(pl0, ph0)), GGML_FP16_TO_FP32(x0->d)*y0->d); + sumv1 = vmlaq_n_f32(sumv1, vcvtq_f32_s32(vaddq_s32(pl1, ph1)), GGML_FP16_TO_FP32(x1->d)*y1->d); +#endif + } + + *s = vaddvq_f32(sumv0) + vaddvq_f32(sumv1) + summs0 + summs1; +#elif defined(__wasm_simd128__) + v128_t sumv = wasm_f32x4_splat(0.0f); + + float summs = 0.0f; + + uint32_t qh; + uint64_t tmp[4]; + + // TODO: check if unrolling this is better + for (int i = 0; i < nb; ++i) { + const block_q5_1 * restrict x0 = &x[i]; + const block_q8_1 * restrict y0 = &y[i]; + + summs += GGML_FP16_TO_FP32(x0->m) * y0->s; + + const v128_t m4b = wasm_i8x16_splat(0x0F); + + // extract the 5th bit + memcpy(&qh, x0->qh, sizeof(qh)); + + tmp[0] = table_b2b_0[(qh >> 0) & 0xFF]; + tmp[1] = table_b2b_0[(qh >> 8) & 0xFF]; + tmp[2] = table_b2b_0[(qh >> 16) & 0xFF]; + tmp[3] = table_b2b_0[(qh >> 24) ]; + + const v128_t qhl = wasm_v128_load(tmp + 0); + const v128_t qhh = wasm_v128_load(tmp + 2); + + const v128_t v0 = wasm_v128_load(x0->qs); + + // 4-bit -> 8-bit + const v128_t v0l = wasm_v128_and (v0, m4b); + const v128_t v0h = wasm_u8x16_shr(v0, 4); + + // add high bit + const v128_t v0lf = wasm_v128_or(v0l, qhl); + const v128_t v0hf = wasm_v128_or(v0h, qhh); + + // load y + const v128_t v1l = wasm_v128_load(y0->qs); + const v128_t v1h = wasm_v128_load(y0->qs + 16); + + // int8x16 -> int16x8 + const v128_t v0lfl = wasm_i16x8_extend_low_i8x16 (v0lf); + const v128_t v0lfh = wasm_i16x8_extend_high_i8x16(v0lf); + const v128_t v0hfl = wasm_i16x8_extend_low_i8x16 (v0hf); + const v128_t v0hfh = wasm_i16x8_extend_high_i8x16(v0hf); + + const v128_t v1ll = wasm_i16x8_extend_low_i8x16 (v1l); + const v128_t v1lh = wasm_i16x8_extend_high_i8x16(v1l); + const v128_t v1hl = wasm_i16x8_extend_low_i8x16 (v1h); + const v128_t v1hh = wasm_i16x8_extend_high_i8x16(v1h); + + // dot product + sumv = wasm_f32x4_add(sumv, + wasm_f32x4_mul(wasm_f32x4_convert_i32x4(wasm_i32x4_add( + wasm_i32x4_add(wasm_i32x4_dot_i16x8(v0lfl, v1ll), + wasm_i32x4_dot_i16x8(v0lfh, v1lh)), + wasm_i32x4_add(wasm_i32x4_dot_i16x8(v0hfl, v1hl), + wasm_i32x4_dot_i16x8(v0hfh, v1hh)))), + wasm_f32x4_splat(GGML_FP16_TO_FP32(x0->d) * y0->d))); + } + + *s = wasm_f32x4_extract_lane(sumv, 0) + wasm_f32x4_extract_lane(sumv, 1) + + wasm_f32x4_extract_lane(sumv, 2) + wasm_f32x4_extract_lane(sumv, 3) + summs; +#elif defined(__AVX2__) + // Initialize accumulator with zeros + __m256 acc = _mm256_setzero_ps(); + + float summs = 0.0f; + + // Main loop + for (int i = 0; i < nb; i++) { + const __m256 dx = _mm256_set1_ps(GGML_FP16_TO_FP32(x[i].d)); + + summs += GGML_FP16_TO_FP32(x[i].m) * y[i].s; + + __m256i bx = bytes_from_nibbles_32(x[i].qs); + __m256i bxhi = bytes_from_bits_32(x[i].qh); + bxhi = _mm256_and_si256(bxhi, _mm256_set1_epi8(0x10)); + bx = _mm256_or_si256(bx, bxhi); + + const __m256 dy = _mm256_set1_ps(y[i].d); + const __m256i by = _mm256_loadu_si256((const __m256i *)y[i].qs); + + const __m256 q = mul_sum_us8_pairs_float(bx, by); + + acc = _mm256_fmadd_ps(q, _mm256_mul_ps(dx, dy), acc); + } + + *s = hsum_float_8(acc) + summs; +#elif defined(__AVX__) + // Initialize accumulator with zeros + __m256 acc = _mm256_setzero_ps(); + __m128i mask = _mm_set1_epi8(0x10); + + float summs = 0.0f; + + // Main loop + for (int i = 0; i < nb; i++) { + const __m256 dx = _mm256_set1_ps(GGML_FP16_TO_FP32(x[i].d)); + + summs += GGML_FP16_TO_FP32(x[i].m) * y[i].s; + + __m256i bx = bytes_from_nibbles_32(x[i].qs); + const __m256i bxhi = bytes_from_bits_32(x[i].qh); + __m128i bxhil = _mm256_castsi256_si128(bxhi); + __m128i bxhih = _mm256_extractf128_si256(bxhi, 1); + bxhil = _mm_and_si128(bxhil, mask); + bxhih = _mm_and_si128(bxhih, mask); + __m128i bxl = _mm256_castsi256_si128(bx); + __m128i bxh = _mm256_extractf128_si256(bx, 1); + bxl = _mm_or_si128(bxl, bxhil); + bxh = _mm_or_si128(bxh, bxhih); + bx = MM256_SET_M128I(bxh, bxl); + + const __m256 dy = _mm256_set1_ps(y[i].d); + const __m256i by = _mm256_loadu_si256((const __m256i *)y[i].qs); + + const __m256 q = mul_sum_us8_pairs_float(bx, by); + + acc = _mm256_add_ps(_mm256_mul_ps(q, _mm256_mul_ps(dx, dy)), acc); + } + + *s = hsum_float_8(acc) + summs; +#elif defined(__riscv_v_intrinsic) + float sumf = 0.0; + + uint32_t qh; + + size_t vl = __riscv_vsetvl_e8m1(qk/2); + + // temporary registers for shift operations + vuint32m2_t vt_1 = __riscv_vid_v_u32m2(vl); + vuint32m2_t vt_2 = __riscv_vadd_vx_u32m2(vt_1, 12, vl); + + for (int i = 0; i < nb; i++) { + memcpy(&qh, x[i].qh, sizeof(uint32_t)); + + // load qh + vuint32m2_t vqh = __riscv_vmv_v_x_u32m2(qh, vl); + + // ((qh >> (j + 0)) << 4) & 0x10; + vuint32m2_t xhr_0 = __riscv_vsrl_vv_u32m2(vqh, vt_1, vl); + vuint32m2_t xhl_0 = __riscv_vsll_vx_u32m2(xhr_0, 4, vl); + vuint32m2_t xha_0 = __riscv_vand_vx_u32m2(xhl_0, 0x10, vl); + + // ((qh >> (j + 12)) ) & 0x10; + vuint32m2_t xhr_1 = __riscv_vsrl_vv_u32m2(vqh, vt_2, vl); + vuint32m2_t xha_1 = __riscv_vand_vx_u32m2(xhr_1, 0x10, vl); + + // narrowing + vuint16m1_t xhc_0 = __riscv_vncvt_x_x_w_u16m1(xha_0, vl); + vuint8mf2_t xh_0 = __riscv_vncvt_x_x_w_u8mf2(xhc_0, vl); + + vuint16m1_t xhc_1 = __riscv_vncvt_x_x_w_u16m1(xha_1, vl); + vuint8mf2_t xh_1 = __riscv_vncvt_x_x_w_u8mf2(xhc_1, vl); + + // load + vuint8mf2_t tx = __riscv_vle8_v_u8mf2(x[i].qs, vl); + + vint8mf2_t y0 = __riscv_vle8_v_i8mf2(y[i].qs, vl); + vint8mf2_t y1 = __riscv_vle8_v_i8mf2(y[i].qs+16, vl); + + vuint8mf2_t x_at = __riscv_vand_vx_u8mf2(tx, 0x0F, vl); + vuint8mf2_t x_lt = __riscv_vsrl_vx_u8mf2(tx, 0x04, vl); + + vuint8mf2_t x_a = __riscv_vor_vv_u8mf2(x_at, xh_0, vl); + vuint8mf2_t x_l = __riscv_vor_vv_u8mf2(x_lt, xh_1, vl); + + vint8mf2_t v0 = __riscv_vreinterpret_v_u8mf2_i8mf2(x_a); + vint8mf2_t v1 = __riscv_vreinterpret_v_u8mf2_i8mf2(x_l); + + vint16m1_t vec_mul1 = __riscv_vwmul_vv_i16m1(v0, y0, vl); + vint16m1_t vec_mul2 = __riscv_vwmul_vv_i16m1(v1, y1, vl); + + vint32m1_t vec_zero = __riscv_vmv_v_x_i32m1(0, vl); + + vint32m1_t vs1 = __riscv_vwredsum_vs_i16m1_i32m1(vec_mul1, vec_zero, vl); + vint32m1_t vs2 = __riscv_vwredsum_vs_i16m1_i32m1(vec_mul2, vs1, vl); + + int sumi = __riscv_vmv_x_s_i32m1_i32(vs2); + + sumf += (GGML_FP16_TO_FP32(x[i].d)*y[i].d)*sumi + GGML_FP16_TO_FP32(x[i].m)*y[i].s; + } + + *s = sumf; +#else + // scalar + float sumf = 0.0; + + for (int i = 0; i < nb; i++) { + uint32_t qh; + memcpy(&qh, x[i].qh, sizeof(qh)); + + int sumi = 0; + + for (int j = 0; j < qk/2; ++j) { + const uint8_t xh_0 = ((qh >> (j + 0)) << 4) & 0x10; + const uint8_t xh_1 = ((qh >> (j + 12)) ) & 0x10; + + const int32_t x0 = (x[i].qs[j] & 0xF) | xh_0; + const int32_t x1 = (x[i].qs[j] >> 4) | xh_1; + + sumi += (x0 * y[i].qs[j]) + (x1 * y[i].qs[j + qk/2]); + } + + sumf += (GGML_FP16_TO_FP32(x[i].d)*y[i].d)*sumi + GGML_FP16_TO_FP32(x[i].m)*y[i].s; + } + + *s = sumf; +#endif +} + +void ggml_vec_dot_q8_0_q8_0(const int n, float * restrict s, const void * restrict vx, const void * restrict vy) { + const int qk = QK8_0; + const int nb = n / qk; + + assert(n % qk == 0); + + const block_q8_0 * restrict x = vx; + const block_q8_0 * restrict y = vy; + +#if defined(__ARM_NEON) + float32x4_t sumv0 = vdupq_n_f32(0.0f); + float32x4_t sumv1 = vdupq_n_f32(0.0f); + + assert(nb % 2 == 0); // TODO: handle odd nb + + for (int i = 0; i < nb; i += 2) { + const block_q8_0 * restrict x0 = &x[i + 0]; + const block_q8_0 * restrict x1 = &x[i + 1]; + const block_q8_0 * restrict y0 = &y[i + 0]; + const block_q8_0 * restrict y1 = &y[i + 1]; + + const int8x16_t x0_0 = vld1q_s8(x0->qs); + const int8x16_t x0_1 = vld1q_s8(x0->qs + 16); + const int8x16_t x1_0 = vld1q_s8(x1->qs); + const int8x16_t x1_1 = vld1q_s8(x1->qs + 16); + + // load y + const int8x16_t y0_0 = vld1q_s8(y0->qs); + const int8x16_t y0_1 = vld1q_s8(y0->qs + 16); + const int8x16_t y1_0 = vld1q_s8(y1->qs); + const int8x16_t y1_1 = vld1q_s8(y1->qs + 16); + +#if defined(__ARM_FEATURE_DOTPROD) + sumv0 = vmlaq_n_f32(sumv0, vcvtq_f32_s32(vaddq_s32( + vdotq_s32(vdupq_n_s32(0), x0_0, y0_0), + vdotq_s32(vdupq_n_s32(0), x0_1, y0_1))), GGML_FP16_TO_FP32(x0->d)*GGML_FP16_TO_FP32(y0->d)); + + sumv1 = vmlaq_n_f32(sumv1, vcvtq_f32_s32(vaddq_s32( + vdotq_s32(vdupq_n_s32(0), x1_0, y1_0), + vdotq_s32(vdupq_n_s32(0), x1_1, y1_1))), GGML_FP16_TO_FP32(x1->d)*GGML_FP16_TO_FP32(y1->d)); + +#else + const int16x8_t p0_0 = vmull_s8(vget_low_s8 (x0_0), vget_low_s8 (y0_0)); + const int16x8_t p0_1 = vmull_s8(vget_high_s8(x0_0), vget_high_s8(y0_0)); + const int16x8_t p0_2 = vmull_s8(vget_low_s8 (x0_1), vget_low_s8 (y0_1)); + const int16x8_t p0_3 = vmull_s8(vget_high_s8(x0_1), vget_high_s8(y0_1)); + + const int16x8_t p1_0 = vmull_s8(vget_low_s8 (x1_0), vget_low_s8 (y1_0)); + const int16x8_t p1_1 = vmull_s8(vget_high_s8(x1_0), vget_high_s8(y1_0)); + const int16x8_t p1_2 = vmull_s8(vget_low_s8 (x1_1), vget_low_s8 (y1_1)); + const int16x8_t p1_3 = vmull_s8(vget_high_s8(x1_1), vget_high_s8(y1_1)); + + const int32x4_t p0 = vaddq_s32(vpaddlq_s16(p0_0), vpaddlq_s16(p0_1)); + const int32x4_t p1 = vaddq_s32(vpaddlq_s16(p0_2), vpaddlq_s16(p0_3)); + const int32x4_t p2 = vaddq_s32(vpaddlq_s16(p1_0), vpaddlq_s16(p1_1)); + const int32x4_t p3 = vaddq_s32(vpaddlq_s16(p1_2), vpaddlq_s16(p1_3)); + + sumv0 = vmlaq_n_f32(sumv0, vcvtq_f32_s32(vaddq_s32(p0, p1)), GGML_FP16_TO_FP32(x0->d)*GGML_FP16_TO_FP32(y0->d)); + sumv1 = vmlaq_n_f32(sumv1, vcvtq_f32_s32(vaddq_s32(p2, p3)), GGML_FP16_TO_FP32(x1->d)*GGML_FP16_TO_FP32(y1->d)); +#endif + } + + *s = vaddvq_f32(sumv0) + vaddvq_f32(sumv1); +#elif defined(__AVX2__) || defined(__AVX__) + // Initialize accumulator with zeros + __m256 acc = _mm256_setzero_ps(); + + // Main loop + for (int i = 0; i < nb; ++i) { + // Compute combined scale for the block + const __m256 d = _mm256_set1_ps(GGML_FP16_TO_FP32(x[i].d) * GGML_FP16_TO_FP32(y[i].d)); + __m256i bx = _mm256_loadu_si256((const __m256i *)x[i].qs); + __m256i by = _mm256_loadu_si256((const __m256i *)y[i].qs); + + const __m256 q = mul_sum_i8_pairs_float(bx, by); + + // Multiply q with scale and accumulate +#if defined(__AVX2__) + acc = _mm256_fmadd_ps( d, q, acc ); +#else + acc = _mm256_add_ps( _mm256_mul_ps( d, q ), acc ); +#endif + } + + *s = hsum_float_8(acc); +#elif defined(__riscv_v_intrinsic) + float sumf = 0.0; + size_t vl = __riscv_vsetvl_e8m1(qk); + + for (int i = 0; i < nb; i++) { + // load elements + vint8m1_t bx = __riscv_vle8_v_i8m1(x[i].qs, vl); + vint8m1_t by = __riscv_vle8_v_i8m1(y[i].qs, vl); + + vint16m2_t vw_mul = __riscv_vwmul_vv_i16m2(bx, by, vl); + + vint32m1_t v_zero = __riscv_vmv_v_x_i32m1(0, vl); + vint32m1_t v_sum = __riscv_vwredsum_vs_i16m2_i32m1(vw_mul, v_zero, vl); + + int sumi = __riscv_vmv_x_s_i32m1_i32(v_sum); + + sumf += sumi*(GGML_FP16_TO_FP32(x[i].d)*GGML_FP16_TO_FP32(y[i].d)); + } + + *s = sumf; +#else + // scalar + float sumf = 0.0; + + for (int i = 0; i < nb; i++) { + int sumi = 0; + + for (int j = 0; j < qk; j++) { + sumi += x[i].qs[j]*y[i].qs[j]; + } + + sumf += sumi*(GGML_FP16_TO_FP32(x[i].d)*GGML_FP16_TO_FP32(y[i].d)); + } + + *s = sumf; +#endif +} + +#if QK_K == 256 +void ggml_vec_dot_q2_K_q8_K(const int n, float * restrict s, const void * restrict vx, const void * restrict vy) { + + const block_q2_K * restrict x = vx; + const block_q8_K * restrict y = vy; + + const int nb = n / QK_K; + +#ifdef __ARM_NEON + + const uint8x16_t m3 = vdupq_n_u8(0x3); + const uint8x16_t m4 = vdupq_n_u8(0xF); +#if defined(__ARM_FEATURE_DOTPROD) + const int32x4_t vzero = vdupq_n_s32(0); +#endif + + int8x16x2_t q2bytes; + uint8_t aux[16]; + + float sum = 0; + + for (int i = 0; i < nb; ++i) { + + const float d = y[i].d * GGML_FP16_TO_FP32(x[i].d); + const float dmin = -y[i].d * GGML_FP16_TO_FP32(x[i].dmin); + + const uint8_t * restrict q2 = x[i].qs; + const int8_t * restrict q8 = y[i].qs; + const uint8_t * restrict sc = x[i].scales; + + const uint8x16_t mins_and_scales = vld1q_u8(sc); + const uint8x16_t scales = vandq_u8(mins_and_scales, m4); + vst1q_u8(aux, scales); + + const uint8x16_t mins = vshrq_n_u8(mins_and_scales, 4); + const int16x8x2_t q8sums = vld1q_s16_x2(y[i].bsums); + const int16x8x2_t mins16 = {vreinterpretq_s16_u16(vmovl_u8(vget_low_u8(mins))), vreinterpretq_s16_u16(vmovl_u8(vget_high_u8(mins)))}; + const int32x4_t s0 = vaddq_s32(vmull_s16(vget_low_s16 (mins16.val[0]), vget_low_s16 (q8sums.val[0])), + vmull_s16(vget_high_s16(mins16.val[0]), vget_high_s16(q8sums.val[0]))); + const int32x4_t s1 = vaddq_s32(vmull_s16(vget_low_s16 (mins16.val[1]), vget_low_s16 (q8sums.val[1])), + vmull_s16(vget_high_s16(mins16.val[1]), vget_high_s16(q8sums.val[1]))); + sum += dmin * vaddvq_s32(vaddq_s32(s0, s1)); + + int isum = 0; + int is = 0; + +// We use this macro instead of a function call because for some reason +// the code runs 2-3% slower, even if the function is declared inline +#if defined(__ARM_FEATURE_DOTPROD) +#define MULTIPLY_ACCUM_WITH_SCALE(index)\ + isum += vaddvq_s32(vdotq_s32(vzero, q2bytes.val[0], q8bytes.val[0])) * aux[is+(index)];\ + isum += vaddvq_s32(vdotq_s32(vzero, q2bytes.val[1], q8bytes.val[1])) * aux[is+1+(index)]; +#else +#define MULTIPLY_ACCUM_WITH_SCALE(index)\ + {\ + const int16x8_t p1 = vaddq_s16(vmull_s8(vget_low_s8 (q2bytes.val[0]), vget_low_s8 (q8bytes.val[0])),\ + vmull_s8(vget_high_s8(q2bytes.val[0]), vget_high_s8(q8bytes.val[0])));\ + const int16x8_t p2 = vaddq_s16(vmull_s8(vget_low_s8 (q2bytes.val[1]), vget_low_s8 (q8bytes.val[1])),\ + vmull_s8(vget_high_s8(q2bytes.val[1]), vget_high_s8(q8bytes.val[1])));\ + isum += vaddvq_s16(p1) * aux[is+(index)] + vaddvq_s16(p2) * aux[is+1+(index)];\ + } +#endif + +#define SHIFT_MULTIPLY_ACCUM_WITH_SCALE(shift, index)\ + q8bytes = vld1q_s8_x2(q8); q8 += 32;\ + q2bytes.val[0] = vreinterpretq_s8_u8(vandq_u8(vshrq_n_u8(q2bits.val[0], (shift)), m3));\ + q2bytes.val[1] = vreinterpretq_s8_u8(vandq_u8(vshrq_n_u8(q2bits.val[1], (shift)), m3));\ + MULTIPLY_ACCUM_WITH_SCALE((index)); + + + for (int j = 0; j < QK_K/128; ++j) { + + const uint8x16x2_t q2bits = vld1q_u8_x2(q2); q2 += 32; + + int8x16x2_t q8bytes = vld1q_s8_x2(q8); q8 += 32; + q2bytes.val[0] = vreinterpretq_s8_u8(vandq_u8(q2bits.val[0], m3)); + q2bytes.val[1] = vreinterpretq_s8_u8(vandq_u8(q2bits.val[1], m3)); + MULTIPLY_ACCUM_WITH_SCALE(0); + + SHIFT_MULTIPLY_ACCUM_WITH_SCALE(2, 2); + + SHIFT_MULTIPLY_ACCUM_WITH_SCALE(4, 4); + + SHIFT_MULTIPLY_ACCUM_WITH_SCALE(6, 6); + + is += 8; + } + sum += d * isum; + + } + + *s = sum; + +#elif defined __AVX2__ + + const __m256i m3 = _mm256_set1_epi8(3); + const __m128i m4 = _mm_set1_epi8(0xF); + + __m256 acc = _mm256_setzero_ps(); + + for (int i = 0; i < nb; ++i) { + + const float d = y[i].d * GGML_FP16_TO_FP32(x[i].d); + const float dmin = -y[i].d * GGML_FP16_TO_FP32(x[i].dmin); + + const uint8_t * restrict q2 = x[i].qs; + const int8_t * restrict q8 = y[i].qs; + + const __m128i mins_and_scales = _mm_loadu_si128((const __m128i*)x[i].scales); + const __m128i scales8 = _mm_and_si128(mins_and_scales, m4); + const __m128i mins8 = _mm_and_si128(_mm_srli_epi16(mins_and_scales, 4), m4); + const __m256i mins = _mm256_cvtepi8_epi16(mins8); + const __m256i prod = _mm256_madd_epi16(mins, _mm256_loadu_si256((const __m256i*)y[i].bsums)); + + acc = _mm256_fmadd_ps(_mm256_broadcast_ss(&dmin), _mm256_cvtepi32_ps(prod), acc); + + const __m256i all_scales = _mm256_cvtepi8_epi16(scales8); + const __m128i l_scales = _mm256_extracti128_si256(all_scales, 0); + const __m128i h_scales = _mm256_extracti128_si256(all_scales, 1); + const __m256i scales[2] = {MM256_SET_M128I(l_scales, l_scales), MM256_SET_M128I(h_scales, h_scales)}; + + __m256i sumi = _mm256_setzero_si256(); + + for (int j = 0; j < QK_K/128; ++j) { + + const __m256i q2bits = _mm256_loadu_si256((const __m256i*)q2); q2 += 32; + + const __m256i q8_0 = _mm256_loadu_si256((const __m256i*)q8); q8 += 32; + const __m256i q8_1 = _mm256_loadu_si256((const __m256i*)q8); q8 += 32; + const __m256i q8_2 = _mm256_loadu_si256((const __m256i*)q8); q8 += 32; + const __m256i q8_3 = _mm256_loadu_si256((const __m256i*)q8); q8 += 32; + + const __m256i q2_0 = _mm256_and_si256(q2bits, m3); + const __m256i q2_1 = _mm256_and_si256(_mm256_srli_epi16(q2bits, 2), m3); + const __m256i q2_2 = _mm256_and_si256(_mm256_srli_epi16(q2bits, 4), m3); + const __m256i q2_3 = _mm256_and_si256(_mm256_srli_epi16(q2bits, 6), m3); + + __m256i p0 = _mm256_maddubs_epi16(q2_0, q8_0); + __m256i p1 = _mm256_maddubs_epi16(q2_1, q8_1); + __m256i p2 = _mm256_maddubs_epi16(q2_2, q8_2); + __m256i p3 = _mm256_maddubs_epi16(q2_3, q8_3); + + p0 = _mm256_madd_epi16(_mm256_shuffle_epi8(scales[j], get_scale_shuffle_q3k(0)), p0); + p1 = _mm256_madd_epi16(_mm256_shuffle_epi8(scales[j], get_scale_shuffle_q3k(1)), p1); + p2 = _mm256_madd_epi16(_mm256_shuffle_epi8(scales[j], get_scale_shuffle_q3k(2)), p2); + p3 = _mm256_madd_epi16(_mm256_shuffle_epi8(scales[j], get_scale_shuffle_q3k(3)), p3); + + p0 = _mm256_add_epi32(p0, p1); + p2 = _mm256_add_epi32(p2, p3); + + sumi = _mm256_add_epi32(sumi, _mm256_add_epi32(p0, p2)); + } + + acc = _mm256_fmadd_ps(_mm256_broadcast_ss(&d), _mm256_cvtepi32_ps(sumi), acc); + + } + + *s = hsum_float_8(acc); + +#elif defined __AVX__ + + const __m128i m3 = _mm_set1_epi8(0x3); + const __m128i m4 = _mm_set1_epi8(0xF); + const __m128i m2 = _mm_set1_epi8(0x2); + + __m256 acc = _mm256_setzero_ps(); + + for (int i = 0; i < nb; ++i) { + + const float dall = y[i].d * GGML_FP16_TO_FP32(x[i].d); + const float dmin = -y[i].d * GGML_FP16_TO_FP32(x[i].dmin); + + const uint8_t * restrict q2 = x[i].qs; + const int8_t * restrict q8 = y[i].qs; + + // load mins and scales from block_q2_K.scales[QK_K/16] + const __m128i mins_and_scales = _mm_loadu_si128((const __m128i*)x[i].scales); + const __m128i scales16 = _mm_and_si128(mins_and_scales, m4); + const __m128i mins16 = _mm_and_si128(_mm_srli_epi16(mins_and_scales, 4), m4); + const __m128i mins_0 = _mm_cvtepi8_epi16(mins16); + const __m128i mins_1 = _mm_cvtepi8_epi16(_mm_unpackhi_epi64(mins16, mins16)); + + // summs = y[i].bsums * (x[i].scales >> 4) in 16bits*8*2 to 32bits*4*2 + const __m128i summs_0 = _mm_madd_epi16(mins_0, _mm_loadu_si128((const __m128i*)&y[i].bsums[0])); + const __m128i summs_1 = _mm_madd_epi16(mins_1, _mm_loadu_si128((const __m128i*)&y[i].bsums[8])); + + // sumf += -dmin * summs in 32bits*8 + acc = _mm256_add_ps(_mm256_mul_ps(_mm256_broadcast_ss(&dmin), _mm256_cvtepi32_ps(MM256_SET_M128I(summs_1, summs_0))), acc); + + const __m128i scales_0 = _mm_cvtepi8_epi16(scales16); + const __m128i scales_1 = _mm_cvtepi8_epi16(_mm_unpackhi_epi64(scales16, scales16)); + const __m128i scales[2] = { scales_0, scales_1 }; + + __m128i sumi_0 = _mm_setzero_si128(); + __m128i sumi_1 = _mm_setzero_si128(); + + for (int j = 0; j < QK_K/128; ++j) { + + // load Q8 quants int8*16*8 from block_q8_K.qs[QK_K] + const __m128i q8_0 = _mm_loadu_si128((const __m128i*)q8); q8 += 16; + const __m128i q8_1 = _mm_loadu_si128((const __m128i*)q8); q8 += 16; + const __m128i q8_2 = _mm_loadu_si128((const __m128i*)q8); q8 += 16; + const __m128i q8_3 = _mm_loadu_si128((const __m128i*)q8); q8 += 16; + const __m128i q8_4 = _mm_loadu_si128((const __m128i*)q8); q8 += 16; + const __m128i q8_5 = _mm_loadu_si128((const __m128i*)q8); q8 += 16; + const __m128i q8_6 = _mm_loadu_si128((const __m128i*)q8); q8 += 16; + const __m128i q8_7 = _mm_loadu_si128((const __m128i*)q8); q8 += 16; + + // load 2bits*16*8 from block_q2_K.qs[QK_K/4] + __m128i q2bits = _mm_loadu_si128((const __m128i*)q2); q2 += 16; + const __m128i q2_0 = _mm_and_si128(q2bits, m3); + const __m128i q2_2 = _mm_and_si128(_mm_srli_epi16(q2bits, 2), m3); + const __m128i q2_4 = _mm_and_si128(_mm_srli_epi16(q2bits, 4), m3); + const __m128i q2_6 = _mm_and_si128(_mm_srli_epi16(q2bits, 6), m3); + q2bits = _mm_loadu_si128((const __m128i*)q2); q2 += 16; + const __m128i q2_1 = _mm_and_si128(q2bits, m3); + const __m128i q2_3 = _mm_and_si128(_mm_srli_epi16(q2bits, 2), m3); + const __m128i q2_5 = _mm_and_si128(_mm_srli_epi16(q2bits, 4), m3); + const __m128i q2_7 = _mm_and_si128(_mm_srli_epi16(q2bits, 6), m3); + + // isuml = q8[l] * ((q2[l] >> shift) & 3) in 8bits*16*8 to 16bits*8*8 + __m128i p0 = _mm_maddubs_epi16(q2_0, q8_0); + __m128i p1 = _mm_maddubs_epi16(q2_1, q8_1); + __m128i p2 = _mm_maddubs_epi16(q2_2, q8_2); + __m128i p3 = _mm_maddubs_epi16(q2_3, q8_3); + __m128i p4 = _mm_maddubs_epi16(q2_4, q8_4); + __m128i p5 = _mm_maddubs_epi16(q2_5, q8_5); + __m128i p6 = _mm_maddubs_epi16(q2_6, q8_6); + __m128i p7 = _mm_maddubs_epi16(q2_7, q8_7); + + // isum += (x[i].scales[is++] & 0xF) * isuml in 16bits*8*8 to 32bits*4*8 + __m128i shuffle = _mm_set1_epi16(0x0100); + p0 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p0); + shuffle = _mm_add_epi16(shuffle, m2); + p1 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p1); + shuffle = _mm_add_epi16(shuffle, m2); + p2 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p2); + shuffle = _mm_add_epi16(shuffle, m2); + p3 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p3); + shuffle = _mm_add_epi16(shuffle, m2); + p4 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p4); + shuffle = _mm_add_epi16(shuffle, m2); + p5 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p5); + shuffle = _mm_add_epi16(shuffle, m2); + p6 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p6); + shuffle = _mm_add_epi16(shuffle, m2); + p7 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p7); + + p0 = _mm_add_epi32(p0, p1); + p2 = _mm_add_epi32(p2, p3); + p4 = _mm_add_epi32(p4, p5); + p6 = _mm_add_epi32(p6, p7); + + // isum in 32bits*4*2 + sumi_0 = _mm_add_epi32(sumi_0, _mm_add_epi32(p0, p2)); + sumi_1 = _mm_add_epi32(sumi_1, _mm_add_epi32(p4, p6)); + } + + // sumf += dall * isum - dmin * summs in 32bits + __m256i sumi = MM256_SET_M128I(sumi_1, sumi_0); + acc = _mm256_add_ps(_mm256_mul_ps(_mm256_broadcast_ss(&dall), _mm256_cvtepi32_ps(sumi)), acc); + } + + *s = hsum_float_8(acc); + +#elif defined __riscv_v_intrinsic + + float sumf = 0; + uint8_t temp_01[32] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; + + for (int i = 0; i < nb; ++i) { + + const uint8_t * q2 = x[i].qs; + const int8_t * q8 = y[i].qs; + const uint8_t * sc = x[i].scales; + + const float dall = y[i].d * GGML_FP16_TO_FP32(x[i].d); + const float dmin = -y[i].d * GGML_FP16_TO_FP32(x[i].dmin); + + size_t vl = 16; + + vuint8m1_t scales = __riscv_vle8_v_u8m1(sc, vl); + vuint8m1_t aux = __riscv_vand_vx_u8m1(scales, 0x0F, vl); + + vint16m1_t q8sums = __riscv_vle16_v_i16m1(y[i].bsums, vl); + + vuint8mf2_t scales_2 = __riscv_vle8_v_u8mf2(sc, vl); + vuint8mf2_t mins8 = __riscv_vsrl_vx_u8mf2(scales_2, 0x4, vl); + vint16m1_t mins = __riscv_vreinterpret_v_u16m1_i16m1(__riscv_vzext_vf2_u16m1(mins8, vl)); + vint32m2_t prod = __riscv_vwmul_vv_i32m2(q8sums, mins, vl); + vint32m1_t vsums = __riscv_vredsum_vs_i32m2_i32m1(prod, __riscv_vmv_v_x_i32m1(0, 1), vl); + + sumf += dmin * __riscv_vmv_x_s_i32m1_i32(vsums); + + vl = 32; + + vint32m1_t vzero = __riscv_vmv_v_x_i32m1(0, 1); + vuint8m1_t v_b = __riscv_vle8_v_u8m1(temp_01, vl); + + uint8_t is=0; + int isum=0; + + for (int j = 0; j < QK_K/128; ++j) { + // load Q2 + vuint8m1_t q2_x = __riscv_vle8_v_u8m1(q2, vl); + + vuint8m1_t q2_0 = __riscv_vand_vx_u8m1(q2_x, 0x03, vl); + vuint8m1_t q2_1 = __riscv_vand_vx_u8m1(__riscv_vsrl_vx_u8m1(q2_x, 0x2, vl), 0x03 , vl); + vuint8m1_t q2_2 = __riscv_vand_vx_u8m1(__riscv_vsrl_vx_u8m1(q2_x, 0x4, vl), 0x03 , vl); + vuint8m1_t q2_3 = __riscv_vand_vx_u8m1(__riscv_vsrl_vx_u8m1(q2_x, 0x6, vl), 0x03 , vl); + + // duplicate scale elements for product + vuint8m1_t sc0 = __riscv_vrgather_vv_u8m1(aux, __riscv_vadd_vx_u8m1(v_b, 0+is, vl), vl); + vuint8m1_t sc1 = __riscv_vrgather_vv_u8m1(aux, __riscv_vadd_vx_u8m1(v_b, 2+is, vl), vl); + vuint8m1_t sc2 = __riscv_vrgather_vv_u8m1(aux, __riscv_vadd_vx_u8m1(v_b, 4+is, vl), vl); + vuint8m1_t sc3 = __riscv_vrgather_vv_u8m1(aux, __riscv_vadd_vx_u8m1(v_b, 6+is, vl), vl); + + vint16m2_t p0 = __riscv_vreinterpret_v_u16m2_i16m2(__riscv_vwmulu_vv_u16m2(q2_0, sc0, vl)); + vint16m2_t p1 = __riscv_vreinterpret_v_u16m2_i16m2(__riscv_vwmulu_vv_u16m2(q2_1, sc1, vl)); + vint16m2_t p2 = __riscv_vreinterpret_v_u16m2_i16m2(__riscv_vwmulu_vv_u16m2(q2_2, sc2, vl)); + vint16m2_t p3 = __riscv_vreinterpret_v_u16m2_i16m2(__riscv_vwmulu_vv_u16m2(q2_3, sc3, vl)); + + // load Q8 + vint8m1_t q8_0 = __riscv_vle8_v_i8m1(q8, vl); + vint8m1_t q8_1 = __riscv_vle8_v_i8m1(q8+32, vl); + vint8m1_t q8_2 = __riscv_vle8_v_i8m1(q8+64, vl); + vint8m1_t q8_3 = __riscv_vle8_v_i8m1(q8+96, vl); + + vint32m4_t s0 = __riscv_vwmul_vv_i32m4(p0, __riscv_vwcvt_x_x_v_i16m2(q8_0, vl), vl); + vint32m4_t s1 = __riscv_vwmul_vv_i32m4(p1, __riscv_vwcvt_x_x_v_i16m2(q8_1, vl), vl); + vint32m4_t s2 = __riscv_vwmul_vv_i32m4(p2, __riscv_vwcvt_x_x_v_i16m2(q8_2, vl), vl); + vint32m4_t s3 = __riscv_vwmul_vv_i32m4(p3, __riscv_vwcvt_x_x_v_i16m2(q8_3, vl), vl); + + vint32m1_t isum0 = __riscv_vredsum_vs_i32m4_i32m1(__riscv_vadd_vv_i32m4(s0, s1, vl), vzero, vl); + vint32m1_t isum1 = __riscv_vredsum_vs_i32m4_i32m1(__riscv_vadd_vv_i32m4(s2, s3, vl), isum0, vl); + + isum += __riscv_vmv_x_s_i32m1_i32(isum1); + + q2+=32; q8+=128; is=8; + + } + + sumf += dall * isum; + + } + + *s = sumf; + +#else + + float sumf = 0; + + for (int i = 0; i < nb; ++i) { + + const uint8_t * q2 = x[i].qs; + const int8_t * q8 = y[i].qs; + const uint8_t * sc = x[i].scales; + + int summs = 0; + for (int j = 0; j < 16; ++j) { + summs += y[i].bsums[j] * (sc[j] >> 4); + } + + const float dall = y[i].d * GGML_FP16_TO_FP32(x[i].d); + const float dmin = y[i].d * GGML_FP16_TO_FP32(x[i].dmin); + + int isum = 0; + int is = 0; + int d; + for (int k = 0; k < QK_K/128; ++k) { + int shift = 0; + for (int j = 0; j < 4; ++j) { + d = sc[is++] & 0xF; + int isuml = 0; + for (int l = 0; l < 16; ++l) isuml += q8[l] * ((q2[l] >> shift) & 3); + isum += d * isuml; + d = sc[is++] & 0xF; + isuml = 0; + for (int l = 16; l < 32; ++l) isuml += q8[l] * ((q2[l] >> shift) & 3); + isum += d * isuml; + shift += 2; + q8 += 32; + } + q2 += 32; + } + sumf += dall * isum - dmin * summs; + } + *s = sumf; +#endif +} + +#else + +void ggml_vec_dot_q2_K_q8_K(const int n, float * restrict s, const void * restrict vx, const void * restrict vy) { + + const block_q2_K * restrict x = vx; + const block_q8_K * restrict y = vy; + + const int nb = n / QK_K; + +#ifdef __ARM_NEON + + const uint8x16_t m3 = vdupq_n_u8(0x3); +#if defined(__ARM_FEATURE_DOTPROD) + const int32x4_t vzero = vdupq_n_s32(0); +#endif + + int8x16x4_t q2bytes; + + uint32_t aux32[2]; + const uint8_t * scales = (const uint8_t *)aux32; + + float sum = 0; + + for (int i = 0; i < nb; ++i) { + + const float d = y[i].d * (float)x[i].d; + const float dmin = -y[i].d * (float)x[i].dmin; + + const uint8_t * restrict q2 = x[i].qs; + const int8_t * restrict q8 = y[i].qs; + const uint32_t * restrict sc = (const uint32_t *)x[i].scales; + + aux32[0] = sc[0] & 0x0f0f0f0f; + aux32[1] = (sc[0] >> 4) & 0x0f0f0f0f; + + sum += dmin * (scales[4] * y[i].bsums[0] + scales[5] * y[i].bsums[1] + scales[6] * y[i].bsums[2] + scales[7] * y[i].bsums[3]); + + int isum1 = 0, isum2 = 0; + + const uint8x16_t q2bits = vld1q_u8(q2); + + const int8x16x4_t q8bytes = vld1q_s8_x4(q8); + + q2bytes.val[0] = vreinterpretq_s8_u8(vandq_u8(q2bits, m3)); + q2bytes.val[1] = vreinterpretq_s8_u8(vandq_u8(vshrq_n_u8(q2bits, 2), m3)); + q2bytes.val[2] = vreinterpretq_s8_u8(vandq_u8(vshrq_n_u8(q2bits, 4), m3)); + q2bytes.val[3] = vreinterpretq_s8_u8(vandq_u8(vshrq_n_u8(q2bits, 6), m3)); + +#if defined(__ARM_FEATURE_DOTPROD) + isum1 += vaddvq_s32(vdotq_s32(vzero, q2bytes.val[0], q8bytes.val[0])) * scales[0]; + isum2 += vaddvq_s32(vdotq_s32(vzero, q2bytes.val[1], q8bytes.val[1])) * scales[1]; + isum1 += vaddvq_s32(vdotq_s32(vzero, q2bytes.val[2], q8bytes.val[2])) * scales[2]; + isum2 += vaddvq_s32(vdotq_s32(vzero, q2bytes.val[3], q8bytes.val[3])) * scales[3]; +#else + const int16x8_t p1 = vaddq_s16(vmull_s8(vget_low_s8 (q2bytes.val[0]), vget_low_s8 (q8bytes.val[0])), + vmull_s8(vget_high_s8(q2bytes.val[0]), vget_high_s8(q8bytes.val[0]))); + const int16x8_t p2 = vaddq_s16(vmull_s8(vget_low_s8 (q2bytes.val[1]), vget_low_s8 (q8bytes.val[1])), + vmull_s8(vget_high_s8(q2bytes.val[1]), vget_high_s8(q8bytes.val[1]))); + isum1 += vaddvq_s16(p1) * scales[0]; + isum2 += vaddvq_s16(p2) * scales[1]; + + const int16x8_t p3 = vaddq_s16(vmull_s8(vget_low_s8 (q2bytes.val[2]), vget_low_s8 (q8bytes.val[2])), + vmull_s8(vget_high_s8(q2bytes.val[2]), vget_high_s8(q8bytes.val[2]))); + const int16x8_t p4 = vaddq_s16(vmull_s8(vget_low_s8 (q2bytes.val[3]), vget_low_s8 (q8bytes.val[3])), + vmull_s8(vget_high_s8(q2bytes.val[3]), vget_high_s8(q8bytes.val[3]))); + isum1 += vaddvq_s16(p3) * scales[2]; + isum2 += vaddvq_s16(p4) * scales[3]; +#endif + sum += d * (isum1 + isum2); + + } + + *s = sum; + +#elif defined __AVX2__ + + const __m256i m3 = _mm256_set1_epi8(3); + + __m256 acc = _mm256_setzero_ps(); + + uint32_t ud, um; + const uint8_t * restrict db = (const uint8_t *)&ud; + const uint8_t * restrict mb = (const uint8_t *)&um; + + float summs = 0; + + // TODO: optimize this + + for (int i = 0; i < nb; ++i) { + + const float d = y[i].d * GGML_FP16_TO_FP32(x[i].d); + const float dmin = -y[i].d * GGML_FP16_TO_FP32(x[i].dmin); + + const uint8_t * restrict q2 = x[i].qs; + const int8_t * restrict q8 = y[i].qs; + + const uint32_t * restrict sc = (const uint32_t *)x[i].scales; + ud = (sc[0] >> 0) & 0x0f0f0f0f; + um = (sc[0] >> 4) & 0x0f0f0f0f; + + int32_t smin = mb[0] * y[i].bsums[0] + mb[1] * y[i].bsums[1] + mb[2] * y[i].bsums[2] + mb[3] * y[i].bsums[3]; + summs += dmin * smin; + + const __m128i q2bits = _mm_loadu_si128((const __m128i*)q2); + const __m256i q2_0 = _mm256_and_si256(MM256_SET_M128I(_mm_srli_epi16(q2bits, 2), q2bits), m3); + const __m256i q2_1 = _mm256_and_si256(MM256_SET_M128I(_mm_srli_epi16(q2bits, 6), _mm_srli_epi16(q2bits, 4)), m3); + + const __m256i q8_0 = _mm256_loadu_si256((const __m256i*)(q8+ 0)); + const __m256i q8_1 = _mm256_loadu_si256((const __m256i*)(q8+32)); + + const __m256i p0 = _mm256_maddubs_epi16(q2_0, q8_0); + const __m256i p1 = _mm256_maddubs_epi16(q2_1, q8_1); + + const __m256i p_0 = _mm256_cvtepi16_epi32(_mm256_extracti128_si256(p0, 0)); + const __m256i p_1 = _mm256_cvtepi16_epi32(_mm256_extracti128_si256(p0, 1)); + const __m256i p_2 = _mm256_cvtepi16_epi32(_mm256_extracti128_si256(p1, 0)); + const __m256i p_3 = _mm256_cvtepi16_epi32(_mm256_extracti128_si256(p1, 1)); + + acc = _mm256_fmadd_ps(_mm256_set1_ps(d * db[0]), _mm256_cvtepi32_ps(p_0), acc); + acc = _mm256_fmadd_ps(_mm256_set1_ps(d * db[1]), _mm256_cvtepi32_ps(p_1), acc); + acc = _mm256_fmadd_ps(_mm256_set1_ps(d * db[2]), _mm256_cvtepi32_ps(p_2), acc); + acc = _mm256_fmadd_ps(_mm256_set1_ps(d * db[3]), _mm256_cvtepi32_ps(p_3), acc); + } + + *s = hsum_float_8(acc) + summs; + +#elif defined __AVX__ + + const __m128i m3 = _mm_set1_epi8(3); + + __m256 acc = _mm256_setzero_ps(); + + uint32_t ud, um; + const uint8_t * restrict db = (const uint8_t *)&ud; + const uint8_t * restrict mb = (const uint8_t *)&um; + + float summs = 0; + + // TODO: optimize this + + for (int i = 0; i < nb; ++i) { + + const float d = y[i].d * GGML_FP16_TO_FP32(x[i].d); + const float dmin = -y[i].d * GGML_FP16_TO_FP32(x[i].dmin); + + const uint8_t * restrict q2 = x[i].qs; + const int8_t * restrict q8 = y[i].qs; + + const uint32_t * restrict sc = (const uint32_t *)x[i].scales; + ud = (sc[0] >> 0) & 0x0f0f0f0f; + um = (sc[0] >> 4) & 0x0f0f0f0f; + + int32_t smin = mb[0] * y[i].bsums[0] + mb[1] * y[i].bsums[1] + mb[2] * y[i].bsums[2] + mb[3] * y[i].bsums[3]; + summs += dmin * smin; + + const __m128i q2bits = _mm_loadu_si128((const __m128i*)q2); + const __m128i q2_0 = _mm_and_si128(q2bits, m3); + const __m128i q2_1 = _mm_and_si128(_mm_srli_epi16(q2bits, 2), m3); + const __m128i q2_2 = _mm_and_si128(_mm_srli_epi16(q2bits, 4), m3); + const __m128i q2_3 = _mm_and_si128(_mm_srli_epi16(q2bits, 6), m3); + + const __m256i q8_0 = _mm256_loadu_si256((const __m256i*)(q8+ 0)); + const __m256i q8_1 = _mm256_loadu_si256((const __m256i*)(q8+32)); + + const __m128i p0 = _mm_maddubs_epi16(q2_0, _mm256_extractf128_si256(q8_0, 0)); + const __m128i p1 = _mm_maddubs_epi16(q2_1, _mm256_extractf128_si256(q8_0, 1)); + const __m128i p2 = _mm_maddubs_epi16(q2_2, _mm256_extractf128_si256(q8_1, 0)); + const __m128i p3 = _mm_maddubs_epi16(q2_3, _mm256_extractf128_si256(q8_1, 1)); + + const __m256i p_0 = MM256_SET_M128I(_mm_cvtepi16_epi32(_mm_unpackhi_epi64(p0, p0)), _mm_cvtepi16_epi32(p0)); + const __m256i p_1 = MM256_SET_M128I(_mm_cvtepi16_epi32(_mm_unpackhi_epi64(p1, p1)), _mm_cvtepi16_epi32(p1)); + const __m256i p_2 = MM256_SET_M128I(_mm_cvtepi16_epi32(_mm_unpackhi_epi64(p2, p2)), _mm_cvtepi16_epi32(p2)); + const __m256i p_3 = MM256_SET_M128I(_mm_cvtepi16_epi32(_mm_unpackhi_epi64(p3, p3)), _mm_cvtepi16_epi32(p3)); + + acc = _mm256_add_ps(_mm256_mul_ps(_mm256_set1_ps(d * db[0]), _mm256_cvtepi32_ps(p_0)), acc); + acc = _mm256_add_ps(_mm256_mul_ps(_mm256_set1_ps(d * db[1]), _mm256_cvtepi32_ps(p_1)), acc); + acc = _mm256_add_ps(_mm256_mul_ps(_mm256_set1_ps(d * db[2]), _mm256_cvtepi32_ps(p_2)), acc); + acc = _mm256_add_ps(_mm256_mul_ps(_mm256_set1_ps(d * db[3]), _mm256_cvtepi32_ps(p_3)), acc); + } + + *s = hsum_float_8(acc) + summs; + +#elif defined __riscv_v_intrinsic + + uint32_t aux32[2]; + const uint8_t * scales = (const uint8_t *)aux32; + + float sumf = 0; + + for (int i = 0; i < nb; ++i) { + + const float d = y[i].d * (float)x[i].d; + const float dmin = -y[i].d * (float)x[i].dmin; + + const uint8_t * restrict q2 = x[i].qs; + const int8_t * restrict q8 = y[i].qs; + const uint32_t * restrict sc = (const uint32_t *)x[i].scales; + + aux32[0] = sc[0] & 0x0f0f0f0f; + aux32[1] = (sc[0] >> 4) & 0x0f0f0f0f; + + sumf += dmin * (scales[4] * y[i].bsums[0] + scales[5] * y[i].bsums[1] + scales[6] * y[i].bsums[2] + scales[7] * y[i].bsums[3]); + + int isum1 = 0; + int isum2 = 0; + + size_t vl = 16; + + vint16m1_t vzero = __riscv_vmv_v_x_i16m1(0, 1); + + // load Q2 + vuint8mf2_t q2_x = __riscv_vle8_v_u8mf2(q2, vl); + + vint8mf2_t q2_0 = __riscv_vreinterpret_v_u8mf2_i8mf2(__riscv_vand_vx_u8mf2(q2_x, 0x03, vl)); + vint8mf2_t q2_1 = __riscv_vreinterpret_v_u8mf2_i8mf2(__riscv_vand_vx_u8mf2(__riscv_vsrl_vx_u8mf2(q2_x, 0x2, vl), 0x03 , vl)); + vint8mf2_t q2_2 = __riscv_vreinterpret_v_u8mf2_i8mf2(__riscv_vand_vx_u8mf2(__riscv_vsrl_vx_u8mf2(q2_x, 0x4, vl), 0x03 , vl)); + vint8mf2_t q2_3 = __riscv_vreinterpret_v_u8mf2_i8mf2(__riscv_vand_vx_u8mf2(__riscv_vsrl_vx_u8mf2(q2_x, 0x6, vl), 0x03 , vl)); + + // load Q8, and take product with Q2 + vint16m1_t p0 = __riscv_vwmul_vv_i16m1(q2_0, __riscv_vle8_v_i8mf2(q8, vl), vl); + vint16m1_t p1 = __riscv_vwmul_vv_i16m1(q2_1, __riscv_vle8_v_i8mf2(q8+16, vl), vl); + vint16m1_t p2 = __riscv_vwmul_vv_i16m1(q2_2, __riscv_vle8_v_i8mf2(q8+32, vl), vl); + vint16m1_t p3 = __riscv_vwmul_vv_i16m1(q2_3, __riscv_vle8_v_i8mf2(q8+48, vl), vl); + + vint16m1_t vs_0 = __riscv_vredsum_vs_i16m1_i16m1(p0, vzero, vl); + vint16m1_t vs_1 = __riscv_vredsum_vs_i16m1_i16m1(p1, vzero, vl); + vint16m1_t vs_2 = __riscv_vredsum_vs_i16m1_i16m1(p2, vzero, vl); + vint16m1_t vs_3 = __riscv_vredsum_vs_i16m1_i16m1(p3, vzero, vl); + + isum1 += __riscv_vmv_x_s_i16m1_i16(vs_0) * scales[0]; + isum2 += __riscv_vmv_x_s_i16m1_i16(vs_1) * scales[1]; + isum1 += __riscv_vmv_x_s_i16m1_i16(vs_2) * scales[2]; + isum2 += __riscv_vmv_x_s_i16m1_i16(vs_3) * scales[3]; + + sumf += d * (isum1 + isum2); + + } + + *s = sumf; + +#else + + float sumf = 0; + + int isum[4]; + + for (int i = 0; i < nb; ++i) { + + const uint8_t * q2 = x[i].qs; + const int8_t * q8 = y[i].qs; + const uint8_t * sc = x[i].scales; + + int summs = 0; + for (int j = 0; j < QK_K/16; ++j) { + summs += y[i].bsums[j] * (sc[j] >> 4); + } + + const float dall = y[i].d * GGML_FP16_TO_FP32(x[i].d); + const float dmin = y[i].d * GGML_FP16_TO_FP32(x[i].dmin); + + isum[0] = isum[1] = isum[2] = isum[3] = 0; + for (int l = 0; l < 16; ++l) { + isum[0] += q8[l+ 0] * ((q2[l] >> 0) & 3); + isum[1] += q8[l+16] * ((q2[l] >> 2) & 3); + isum[2] += q8[l+32] * ((q2[l] >> 4) & 3); + isum[3] += q8[l+48] * ((q2[l] >> 6) & 3); + } + for (int l = 0; l < 4; ++l) { + isum[l] *= (sc[l] & 0xF); + } + sumf += dall * (isum[0] + isum[1] + isum[2] + isum[3]) - dmin * summs; + } + *s = sumf; +#endif +} +#endif + +#if QK_K == 256 +void ggml_vec_dot_q3_K_q8_K(const int n, float * restrict s, const void * restrict vx, const void * restrict vy) { + assert(n % QK_K == 0); + + const uint32_t kmask1 = 0x03030303; + const uint32_t kmask2 = 0x0f0f0f0f; + + const block_q3_K * restrict x = vx; + const block_q8_K * restrict y = vy; + + const int nb = n / QK_K; + +#ifdef __ARM_NEON + + uint32_t aux[3]; + uint32_t utmp[4]; + + const uint8x16_t m3b = vdupq_n_u8(0x3); +#ifdef __ARM_FEATURE_DOTPROD + const int32x4_t vzero = vdupq_n_s32(0); +#endif + + const uint8x16_t m0 = vdupq_n_u8(1); + const uint8x16_t m1 = vshlq_n_u8(m0, 1); + const uint8x16_t m2 = vshlq_n_u8(m0, 2); + const uint8x16_t m3 = vshlq_n_u8(m0, 3); + const int8_t m32 = 32; + + int8x16x4_t q3bytes; + + float sum = 0; + + for (int i = 0; i < nb; ++i) { + + const float d = y[i].d * GGML_FP16_TO_FP32(x[i].d); + + const uint8_t * restrict q3 = x[i].qs; + const uint8_t * restrict qh = x[i].hmask; + const int8_t * restrict q8 = y[i].qs; + + uint8x16x2_t qhbits = vld1q_u8_x2(qh); + + uint8x16x4_t q3h; + + int32_t isum = 0; + + // Set up scales + memcpy(aux, x[i].scales, 12); + utmp[3] = ((aux[1] >> 4) & kmask2) | (((aux[2] >> 6) & kmask1) << 4); + utmp[2] = ((aux[0] >> 4) & kmask2) | (((aux[2] >> 4) & kmask1) << 4); + utmp[1] = (aux[1] & kmask2) | (((aux[2] >> 2) & kmask1) << 4); + utmp[0] = (aux[0] & kmask2) | (((aux[2] >> 0) & kmask1) << 4); + + int8_t * scale = (int8_t *)utmp; + for (int j = 0; j < 16; ++j) scale[j] -= m32; + + for (int j = 0; j < QK_K/128; ++j) { + + const uint8x16x2_t q3bits = vld1q_u8_x2(q3); q3 += 32; + const int8x16x4_t q8bytes_1 = vld1q_s8_x4(q8); q8 += 64; + const int8x16x4_t q8bytes_2 = vld1q_s8_x4(q8); q8 += 64; + + q3h.val[0] = vshlq_n_u8(vbicq_u8(m0, qhbits.val[0]), 2); + q3h.val[1] = vshlq_n_u8(vbicq_u8(m0, qhbits.val[1]), 2); + q3h.val[2] = vshlq_n_u8(vbicq_u8(m1, qhbits.val[0]), 1); + q3h.val[3] = vshlq_n_u8(vbicq_u8(m1, qhbits.val[1]), 1); + + q3bytes.val[0] = vsubq_s8(vreinterpretq_s8_u8(vandq_u8(q3bits.val[0], m3b)), vreinterpretq_s8_u8(q3h.val[0])); + q3bytes.val[1] = vsubq_s8(vreinterpretq_s8_u8(vandq_u8(q3bits.val[1], m3b)), vreinterpretq_s8_u8(q3h.val[1])); + q3bytes.val[2] = vsubq_s8(vreinterpretq_s8_u8(vandq_u8(vshrq_n_u8(q3bits.val[0], 2), m3b)), vreinterpretq_s8_u8(q3h.val[2])); + q3bytes.val[3] = vsubq_s8(vreinterpretq_s8_u8(vandq_u8(vshrq_n_u8(q3bits.val[1], 2), m3b)), vreinterpretq_s8_u8(q3h.val[3])); + +#if defined(__ARM_FEATURE_DOTPROD) + isum += vaddvq_s32(vdotq_s32(vzero, q3bytes.val[0], q8bytes_1.val[0])) * scale[0]; + isum += vaddvq_s32(vdotq_s32(vzero, q3bytes.val[1], q8bytes_1.val[1])) * scale[1]; + isum += vaddvq_s32(vdotq_s32(vzero, q3bytes.val[2], q8bytes_1.val[2])) * scale[2]; + isum += vaddvq_s32(vdotq_s32(vzero, q3bytes.val[3], q8bytes_1.val[3])) * scale[3]; +#else + int16x8_t p0 = vaddq_s16(vmull_s8(vget_low_s8 (q3bytes.val[0]), vget_low_s8 (q8bytes_1.val[0])), + vmull_s8(vget_high_s8(q3bytes.val[0]), vget_high_s8(q8bytes_1.val[0]))); + int16x8_t p1 = vaddq_s16(vmull_s8(vget_low_s8 (q3bytes.val[1]), vget_low_s8 (q8bytes_1.val[1])), + vmull_s8(vget_high_s8(q3bytes.val[1]), vget_high_s8(q8bytes_1.val[1]))); + int16x8_t p2 = vaddq_s16(vmull_s8(vget_low_s8 (q3bytes.val[2]), vget_low_s8 (q8bytes_1.val[2])), + vmull_s8(vget_high_s8(q3bytes.val[2]), vget_high_s8(q8bytes_1.val[2]))); + int16x8_t p3 = vaddq_s16(vmull_s8(vget_low_s8 (q3bytes.val[3]), vget_low_s8 (q8bytes_1.val[3])), + vmull_s8(vget_high_s8(q3bytes.val[3]), vget_high_s8(q8bytes_1.val[3]))); + isum += vaddvq_s16(p0) * scale[0] + vaddvq_s16(p1) * scale[1] + vaddvq_s16(p2) * scale[2] + vaddvq_s16(p3) * scale[3]; +#endif + scale += 4; + + q3h.val[0] = vbicq_u8(m2, qhbits.val[0]); + q3h.val[1] = vbicq_u8(m2, qhbits.val[1]); + q3h.val[2] = vshrq_n_u8(vbicq_u8(m3, qhbits.val[0]), 1); + q3h.val[3] = vshrq_n_u8(vbicq_u8(m3, qhbits.val[1]), 1); + + q3bytes.val[0] = vsubq_s8(vreinterpretq_s8_u8(vandq_u8(vshrq_n_u8(q3bits.val[0], 4), m3b)), vreinterpretq_s8_u8(q3h.val[0])); + q3bytes.val[1] = vsubq_s8(vreinterpretq_s8_u8(vandq_u8(vshrq_n_u8(q3bits.val[1], 4), m3b)), vreinterpretq_s8_u8(q3h.val[1])); + q3bytes.val[2] = vsubq_s8(vreinterpretq_s8_u8(vandq_u8(vshrq_n_u8(q3bits.val[0], 6), m3b)), vreinterpretq_s8_u8(q3h.val[2])); + q3bytes.val[3] = vsubq_s8(vreinterpretq_s8_u8(vandq_u8(vshrq_n_u8(q3bits.val[1], 6), m3b)), vreinterpretq_s8_u8(q3h.val[3])); + +#if defined(__ARM_FEATURE_DOTPROD) + isum += vaddvq_s32(vdotq_s32(vzero, q3bytes.val[0], q8bytes_2.val[0])) * scale[0]; + isum += vaddvq_s32(vdotq_s32(vzero, q3bytes.val[1], q8bytes_2.val[1])) * scale[1]; + isum += vaddvq_s32(vdotq_s32(vzero, q3bytes.val[2], q8bytes_2.val[2])) * scale[2]; + isum += vaddvq_s32(vdotq_s32(vzero, q3bytes.val[3], q8bytes_2.val[3])) * scale[3]; +#else + p0 = vaddq_s16(vmull_s8(vget_low_s8 (q3bytes.val[0]), vget_low_s8 (q8bytes_2.val[0])), + vmull_s8(vget_high_s8(q3bytes.val[0]), vget_high_s8(q8bytes_2.val[0]))); + p1 = vaddq_s16(vmull_s8(vget_low_s8 (q3bytes.val[1]), vget_low_s8 (q8bytes_2.val[1])), + vmull_s8(vget_high_s8(q3bytes.val[1]), vget_high_s8(q8bytes_2.val[1]))); + p2 = vaddq_s16(vmull_s8(vget_low_s8 (q3bytes.val[2]), vget_low_s8 (q8bytes_2.val[2])), + vmull_s8(vget_high_s8(q3bytes.val[2]), vget_high_s8(q8bytes_2.val[2]))); + p3 = vaddq_s16(vmull_s8(vget_low_s8 (q3bytes.val[3]), vget_low_s8 (q8bytes_2.val[3])), + vmull_s8(vget_high_s8(q3bytes.val[3]), vget_high_s8(q8bytes_2.val[3]))); + isum += vaddvq_s16(p0) * scale[0] + vaddvq_s16(p1) * scale[1] + vaddvq_s16(p2) * scale[2] + vaddvq_s16(p3) * scale[3]; +#endif + scale += 4; + + if (j == 0) { + qhbits.val[0] = vshrq_n_u8(qhbits.val[0], 4); + qhbits.val[1] = vshrq_n_u8(qhbits.val[1], 4); + } + + } + sum += d * isum; + + } + + *s = sum; + +#elif defined __AVX2__ + + const __m256i m3 = _mm256_set1_epi8(3); + const __m256i mone = _mm256_set1_epi8(1); + const __m128i m32 = _mm_set1_epi8(32); + + __m256 acc = _mm256_setzero_ps(); + + uint32_t aux[3]; + + for (int i = 0; i < nb; ++i) { + + const float d = y[i].d * GGML_FP16_TO_FP32(x[i].d); + + const uint8_t * restrict q3 = x[i].qs; + const int8_t * restrict q8 = y[i].qs; + + // Set up scales + memcpy(aux, x[i].scales, 12); + __m128i scales128 = _mm_set_epi32( + ((aux[1] >> 4) & kmask2) | (((aux[2] >> 6) & kmask1) << 4), + ((aux[0] >> 4) & kmask2) | (((aux[2] >> 4) & kmask1) << 4), + (aux[1] & kmask2) | (((aux[2] >> 2) & kmask1) << 4), + (aux[0] & kmask2) | (((aux[2] >> 0) & kmask1) << 4)); + scales128 = _mm_sub_epi8(scales128, m32); + const __m256i all_scales = _mm256_cvtepi8_epi16(scales128); + const __m128i l_scales = _mm256_extracti128_si256(all_scales, 0); + const __m128i h_scales = _mm256_extracti128_si256(all_scales, 1); + const __m256i scales[2] = {MM256_SET_M128I(l_scales, l_scales), MM256_SET_M128I(h_scales, h_scales)}; + + // high bit + const __m256i hbits = _mm256_loadu_si256((const __m256i*)x[i].hmask); + + // integer accumulator + __m256i sumi = _mm256_setzero_si256(); + + int bit = 0; + int is = 0; + + for (int j = 0; j < QK_K/128; ++j) { + // load low 2 bits + const __m256i q3bits = _mm256_loadu_si256((const __m256i*)q3); q3 += 32; + + // prepare low and high bits + const __m256i q3l_0 = _mm256_and_si256(q3bits, m3); + const __m256i q3h_0 = _mm256_slli_epi16(_mm256_srli_epi16(_mm256_andnot_si256(hbits, _mm256_slli_epi16(mone, bit)), bit), 2); + ++bit; + + const __m256i q3l_1 = _mm256_and_si256(_mm256_srli_epi16(q3bits, 2), m3); + const __m256i q3h_1 = _mm256_slli_epi16(_mm256_srli_epi16(_mm256_andnot_si256(hbits, _mm256_slli_epi16(mone, bit)), bit), 2); + ++bit; + + const __m256i q3l_2 = _mm256_and_si256(_mm256_srli_epi16(q3bits, 4), m3); + const __m256i q3h_2 = _mm256_slli_epi16(_mm256_srli_epi16(_mm256_andnot_si256(hbits, _mm256_slli_epi16(mone, bit)), bit), 2); + ++bit; + + const __m256i q3l_3 = _mm256_and_si256(_mm256_srli_epi16(q3bits, 6), m3); + const __m256i q3h_3 = _mm256_slli_epi16(_mm256_srli_epi16(_mm256_andnot_si256(hbits, _mm256_slli_epi16(mone, bit)), bit), 2); + ++bit; + + // load Q8 quants + const __m256i q8_0 = _mm256_loadu_si256((const __m256i*)q8); q8 += 32; + const __m256i q8_1 = _mm256_loadu_si256((const __m256i*)q8); q8 += 32; + const __m256i q8_2 = _mm256_loadu_si256((const __m256i*)q8); q8 += 32; + const __m256i q8_3 = _mm256_loadu_si256((const __m256i*)q8); q8 += 32; + + // Dot product: we multiply the 2 low bits and 1 high bit part separately, so we can use _mm256_maddubs_epi16, + // and then subtract. The high bit part has the 2 already subtracted (and so, it is zero if the high bit was not set, + // and 2 if the high bit was set) + __m256i q8s_0 = _mm256_maddubs_epi16(q3h_0, q8_0); + __m256i q8s_1 = _mm256_maddubs_epi16(q3h_1, q8_1); + __m256i q8s_2 = _mm256_maddubs_epi16(q3h_2, q8_2); + __m256i q8s_3 = _mm256_maddubs_epi16(q3h_3, q8_3); + + __m256i p16_0 = _mm256_maddubs_epi16(q3l_0, q8_0); + __m256i p16_1 = _mm256_maddubs_epi16(q3l_1, q8_1); + __m256i p16_2 = _mm256_maddubs_epi16(q3l_2, q8_2); + __m256i p16_3 = _mm256_maddubs_epi16(q3l_3, q8_3); + + p16_0 = _mm256_sub_epi16(p16_0, q8s_0); + p16_1 = _mm256_sub_epi16(p16_1, q8s_1); + p16_2 = _mm256_sub_epi16(p16_2, q8s_2); + p16_3 = _mm256_sub_epi16(p16_3, q8s_3); + + // multiply with scales + p16_0 = _mm256_madd_epi16(_mm256_shuffle_epi8(scales[j], get_scale_shuffle_q3k(is + 0)), p16_0); + p16_1 = _mm256_madd_epi16(_mm256_shuffle_epi8(scales[j], get_scale_shuffle_q3k(is + 1)), p16_1); + p16_2 = _mm256_madd_epi16(_mm256_shuffle_epi8(scales[j], get_scale_shuffle_q3k(is + 2)), p16_2); + p16_3 = _mm256_madd_epi16(_mm256_shuffle_epi8(scales[j], get_scale_shuffle_q3k(is + 3)), p16_3); + + // accumulate + p16_0 = _mm256_add_epi32(p16_0, p16_1); + p16_2 = _mm256_add_epi32(p16_2, p16_3); + sumi = _mm256_add_epi32(sumi, _mm256_add_epi32(p16_0, p16_2)); + + } + + // multiply with block scale and accumulate + acc = _mm256_fmadd_ps(_mm256_broadcast_ss(&d), _mm256_cvtepi32_ps(sumi), acc); + + } + + *s = hsum_float_8(acc); + +#elif defined __AVX__ + + const __m128i m3 = _mm_set1_epi8(3); + const __m128i mone = _mm_set1_epi8(1); + const __m128i m32 = _mm_set1_epi8(32); + const __m128i m2 = _mm_set1_epi8(2); + + __m256 acc = _mm256_setzero_ps(); + + const uint32_t *aux; + + for (int i = 0; i < nb; ++i) { + + const float d = y[i].d * GGML_FP16_TO_FP32(x[i].d); + + const uint8_t * restrict q3 = x[i].qs; + const int8_t * restrict q8 = y[i].qs; + + // Set up scales + aux = (const uint32_t *)x[i].scales; + __m128i scales128 = _mm_set_epi32( + ((aux[1] >> 4) & kmask2) | (((aux[2] >> 6) & kmask1) << 4), + ((aux[0] >> 4) & kmask2) | (((aux[2] >> 4) & kmask1) << 4), + (aux[1] & kmask2) | (((aux[2] >> 2) & kmask1) << 4), + (aux[0] & kmask2) | (((aux[2] >> 0) & kmask1) << 4)); + scales128 = _mm_sub_epi8(scales128, m32); + const __m128i scales_0 = _mm_cvtepi8_epi16(scales128); + const __m128i scales_1 = _mm_cvtepi8_epi16(_mm_unpackhi_epi64(scales128, scales128)); + const __m128i scales[2] = { scales_0, scales_1 }; + + // high bit *128*2 from block_q3_K.hmask[QK_K/8] + const __m128i hbits_0 = _mm_loadu_si128((const __m128i*)&x[i].hmask[0]); + const __m128i hbits_1 = _mm_loadu_si128((const __m128i*)&x[i].hmask[16]); + + // integer accumulator + __m128i sumi_0 = _mm_setzero_si128(); + __m128i sumi_1 = _mm_setzero_si128(); + + for (int j = 0; j < QK_K/128; ++j) { + // load low 2 bits *64*2 from block_q3_K.qs[QK_K/4] + const __m128i q3bits_0 = _mm_loadu_si128((const __m128i*)q3); q3 += 16; + const __m128i q3bits_1 = _mm_loadu_si128((const __m128i*)q3); q3 += 16; + + // prepare low and high bits + const int bit = j << 2; + + const __m128i q3l_0 = _mm_and_si128(q3bits_0, m3); + const __m128i q3l_1 = _mm_and_si128(q3bits_1, m3); + const __m128i q3h_0 = _mm_slli_epi16(_mm_srli_epi16(_mm_andnot_si128(hbits_0, _mm_slli_epi16(mone, bit)), bit), 2); + const __m128i q3h_1 = _mm_slli_epi16(_mm_srli_epi16(_mm_andnot_si128(hbits_1, _mm_slli_epi16(mone, bit)), bit), 2); + + const __m128i q3l_2 = _mm_and_si128(_mm_srli_epi16(q3bits_0, 2), m3); + const __m128i q3l_3 = _mm_and_si128(_mm_srli_epi16(q3bits_1, 2), m3); + const __m128i q3h_2 = _mm_slli_epi16(_mm_srli_epi16(_mm_andnot_si128(hbits_0, _mm_slli_epi16(mone, bit+1)), bit+1), 2); + const __m128i q3h_3 = _mm_slli_epi16(_mm_srli_epi16(_mm_andnot_si128(hbits_1, _mm_slli_epi16(mone, bit+1)), bit+1), 2); + + const __m128i q3l_4 = _mm_and_si128(_mm_srli_epi16(q3bits_0, 4), m3); + const __m128i q3l_5 = _mm_and_si128(_mm_srli_epi16(q3bits_1, 4), m3); + const __m128i q3h_4 = _mm_slli_epi16(_mm_srli_epi16(_mm_andnot_si128(hbits_0, _mm_slli_epi16(mone, bit+2)), bit+2), 2); + const __m128i q3h_5 = _mm_slli_epi16(_mm_srli_epi16(_mm_andnot_si128(hbits_1, _mm_slli_epi16(mone, bit+2)), bit+2), 2); + + const __m128i q3l_6 = _mm_and_si128(_mm_srli_epi16(q3bits_0, 6), m3); + const __m128i q3l_7 = _mm_and_si128(_mm_srli_epi16(q3bits_1, 6), m3); + const __m128i q3h_6 = _mm_slli_epi16(_mm_srli_epi16(_mm_andnot_si128(hbits_0, _mm_slli_epi16(mone, bit+3)), bit+3), 2); + const __m128i q3h_7 = _mm_slli_epi16(_mm_srli_epi16(_mm_andnot_si128(hbits_1, _mm_slli_epi16(mone, bit+3)), bit+3), 2); + + // load Q8 quants from block_q8_K.qs[QK_K] + const __m128i q8_0 = _mm_loadu_si128((const __m128i*)q8); q8 += 16; + const __m128i q8_1 = _mm_loadu_si128((const __m128i*)q8); q8 += 16; + const __m128i q8_2 = _mm_loadu_si128((const __m128i*)q8); q8 += 16; + const __m128i q8_3 = _mm_loadu_si128((const __m128i*)q8); q8 += 16; + const __m128i q8_4 = _mm_loadu_si128((const __m128i*)q8); q8 += 16; + const __m128i q8_5 = _mm_loadu_si128((const __m128i*)q8); q8 += 16; + const __m128i q8_6 = _mm_loadu_si128((const __m128i*)q8); q8 += 16; + const __m128i q8_7 = _mm_loadu_si128((const __m128i*)q8); q8 += 16; + + // Dot product: we multiply the 2 low bits and 1 high bit part separately, so we can use _mm256_maddubs_epi16, + // and then subtract. The high bit part has the 2 already subtracted (and so, it is zero if the high bit was not set, + // and 2 if the high bit was set) + __m128i q8s_0 = _mm_maddubs_epi16(q3h_0, q8_0); + __m128i q8s_1 = _mm_maddubs_epi16(q3h_1, q8_1); + __m128i q8s_2 = _mm_maddubs_epi16(q3h_2, q8_2); + __m128i q8s_3 = _mm_maddubs_epi16(q3h_3, q8_3); + __m128i q8s_4 = _mm_maddubs_epi16(q3h_4, q8_4); + __m128i q8s_5 = _mm_maddubs_epi16(q3h_5, q8_5); + __m128i q8s_6 = _mm_maddubs_epi16(q3h_6, q8_6); + __m128i q8s_7 = _mm_maddubs_epi16(q3h_7, q8_7); + + __m128i p16_0 = _mm_maddubs_epi16(q3l_0, q8_0); + __m128i p16_1 = _mm_maddubs_epi16(q3l_1, q8_1); + __m128i p16_2 = _mm_maddubs_epi16(q3l_2, q8_2); + __m128i p16_3 = _mm_maddubs_epi16(q3l_3, q8_3); + __m128i p16_4 = _mm_maddubs_epi16(q3l_4, q8_4); + __m128i p16_5 = _mm_maddubs_epi16(q3l_5, q8_5); + __m128i p16_6 = _mm_maddubs_epi16(q3l_6, q8_6); + __m128i p16_7 = _mm_maddubs_epi16(q3l_7, q8_7); + + p16_0 = _mm_sub_epi16(p16_0, q8s_0); + p16_1 = _mm_sub_epi16(p16_1, q8s_1); + p16_2 = _mm_sub_epi16(p16_2, q8s_2); + p16_3 = _mm_sub_epi16(p16_3, q8s_3); + p16_4 = _mm_sub_epi16(p16_4, q8s_4); + p16_5 = _mm_sub_epi16(p16_5, q8s_5); + p16_6 = _mm_sub_epi16(p16_6, q8s_6); + p16_7 = _mm_sub_epi16(p16_7, q8s_7); + + // multiply with scales + __m128i shuffle = _mm_set1_epi16(0x0100); + p16_0 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p16_0); + shuffle = _mm_add_epi16(shuffle, m2); + p16_1 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p16_1); + shuffle = _mm_add_epi16(shuffle, m2); + p16_2 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p16_2); + shuffle = _mm_add_epi16(shuffle, m2); + p16_3 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p16_3); + shuffle = _mm_add_epi16(shuffle, m2); + p16_4 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p16_4); + shuffle = _mm_add_epi16(shuffle, m2); + p16_5 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p16_5); + shuffle = _mm_add_epi16(shuffle, m2); + p16_6 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p16_6); + shuffle = _mm_add_epi16(shuffle, m2); + p16_7 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p16_7); + + // accumulate + p16_0 = _mm_add_epi32(p16_0, p16_1); + p16_2 = _mm_add_epi32(p16_2, p16_3); + p16_4 = _mm_add_epi32(p16_4, p16_5); + p16_6 = _mm_add_epi32(p16_6, p16_7); + sumi_0 = _mm_add_epi32(sumi_0, _mm_add_epi32(p16_0, p16_2)); + sumi_1 = _mm_add_epi32(sumi_1, _mm_add_epi32(p16_4, p16_6)); + + } + + // multiply with block scale and accumulate + __m256i sumi = MM256_SET_M128I(sumi_1, sumi_0); + acc = _mm256_add_ps(_mm256_mul_ps(_mm256_broadcast_ss(&d), _mm256_cvtepi32_ps(sumi)), acc); + + } + + *s = hsum_float_8(acc); + +#elif defined __riscv_v_intrinsic + + uint32_t aux[3]; + uint32_t utmp[4]; + + float sumf = 0; + for (int i = 0; i < nb; ++i) { + + const uint8_t * restrict q3 = x[i].qs; + const uint8_t * restrict qh = x[i].hmask; + const int8_t * restrict q8 = y[i].qs; + + memcpy(aux, x[i].scales, 12); + utmp[3] = ((aux[1] >> 4) & kmask2) | (((aux[2] >> 6) & kmask1) << 4); + utmp[2] = ((aux[0] >> 4) & kmask2) | (((aux[2] >> 4) & kmask1) << 4); + utmp[1] = (aux[1] & kmask2) | (((aux[2] >> 2) & kmask1) << 4); + utmp[0] = (aux[0] & kmask2) | (((aux[2] >> 0) & kmask1) << 4); + + int8_t * scale = (int8_t *)utmp; + for (int j = 0; j < 16; ++j) scale[j] -= 32; + + + size_t vl = 32; + uint8_t m = 1; + + vint32m1_t vzero = __riscv_vmv_v_x_i32m1(0, 1); + vuint8m1_t vqh = __riscv_vle8_v_u8m1(qh, vl); + + int sum_t = 0; + + for (int j = 0; j < QK_K; j += 128) { + + vl = 32; + + // load Q3 + vuint8m1_t q3_x = __riscv_vle8_v_u8m1(q3, vl); + + vint8m1_t q3_0 = __riscv_vreinterpret_v_u8m1_i8m1(__riscv_vand_vx_u8m1(q3_x, 0x03, vl)); + vint8m1_t q3_1 = __riscv_vreinterpret_v_u8m1_i8m1(__riscv_vand_vx_u8m1(__riscv_vsrl_vx_u8m1(q3_x, 0x2, vl), 0x03 , vl)); + vint8m1_t q3_2 = __riscv_vreinterpret_v_u8m1_i8m1(__riscv_vand_vx_u8m1(__riscv_vsrl_vx_u8m1(q3_x, 0x4, vl), 0x03 , vl)); + vint8m1_t q3_3 = __riscv_vreinterpret_v_u8m1_i8m1(__riscv_vand_vx_u8m1(__riscv_vsrl_vx_u8m1(q3_x, 0x6, vl), 0x03 , vl)); + + // compute mask for subtraction + vuint8m1_t qh_m0 = __riscv_vand_vx_u8m1(vqh, m, vl); + vbool8_t vmask_0 = __riscv_vmseq_vx_u8m1_b8(qh_m0, 0, vl); + vint8m1_t q3_m0 = __riscv_vsub_vx_i8m1_m(vmask_0, q3_0, 0x4, vl); + m <<= 1; + + vuint8m1_t qh_m1 = __riscv_vand_vx_u8m1(vqh, m, vl); + vbool8_t vmask_1 = __riscv_vmseq_vx_u8m1_b8(qh_m1, 0, vl); + vint8m1_t q3_m1 = __riscv_vsub_vx_i8m1_m(vmask_1, q3_1, 0x4, vl); + m <<= 1; + + vuint8m1_t qh_m2 = __riscv_vand_vx_u8m1(vqh, m, vl); + vbool8_t vmask_2 = __riscv_vmseq_vx_u8m1_b8(qh_m2, 0, vl); + vint8m1_t q3_m2 = __riscv_vsub_vx_i8m1_m(vmask_2, q3_2, 0x4, vl); + m <<= 1; + + vuint8m1_t qh_m3 = __riscv_vand_vx_u8m1(vqh, m, vl); + vbool8_t vmask_3 = __riscv_vmseq_vx_u8m1_b8(qh_m3, 0, vl); + vint8m1_t q3_m3 = __riscv_vsub_vx_i8m1_m(vmask_3, q3_3, 0x4, vl); + m <<= 1; + + // load Q8 and take product with Q3 + vint16m2_t a0 = __riscv_vwmul_vv_i16m2(q3_m0, __riscv_vle8_v_i8m1(q8, vl), vl); + vint16m2_t a1 = __riscv_vwmul_vv_i16m2(q3_m1, __riscv_vle8_v_i8m1(q8+32, vl), vl); + vint16m2_t a2 = __riscv_vwmul_vv_i16m2(q3_m2, __riscv_vle8_v_i8m1(q8+64, vl), vl); + vint16m2_t a3 = __riscv_vwmul_vv_i16m2(q3_m3, __riscv_vle8_v_i8m1(q8+96, vl), vl); + + vl = 16; + + // retreive lane to multiply with scale + vint32m2_t aux0_0 = __riscv_vwmul_vx_i32m2(__riscv_vget_v_i16m2_i16m1(a0, 0), (scale[0]), vl); + vint32m2_t aux0_1 = __riscv_vwmul_vx_i32m2(__riscv_vget_v_i16m2_i16m1(a0, 1), (scale[1]), vl); + vint32m2_t aux1_0 = __riscv_vwmul_vx_i32m2(__riscv_vget_v_i16m2_i16m1(a1, 0), (scale[2]), vl); + vint32m2_t aux1_1 = __riscv_vwmul_vx_i32m2(__riscv_vget_v_i16m2_i16m1(a1, 1), (scale[3]), vl); + vint32m2_t aux2_0 = __riscv_vwmul_vx_i32m2(__riscv_vget_v_i16m2_i16m1(a2, 0), (scale[4]), vl); + vint32m2_t aux2_1 = __riscv_vwmul_vx_i32m2(__riscv_vget_v_i16m2_i16m1(a2, 1), (scale[5]), vl); + vint32m2_t aux3_0 = __riscv_vwmul_vx_i32m2(__riscv_vget_v_i16m2_i16m1(a3, 0), (scale[6]), vl); + vint32m2_t aux3_1 = __riscv_vwmul_vx_i32m2(__riscv_vget_v_i16m2_i16m1(a3, 1), (scale[7]), vl); + + vint32m1_t isum0 = __riscv_vredsum_vs_i32m2_i32m1(__riscv_vadd_vv_i32m2(aux0_0, aux0_1, vl), vzero, vl); + vint32m1_t isum1 = __riscv_vredsum_vs_i32m2_i32m1(__riscv_vadd_vv_i32m2(aux1_0, aux1_1, vl), isum0, vl); + vint32m1_t isum2 = __riscv_vredsum_vs_i32m2_i32m1(__riscv_vadd_vv_i32m2(aux2_0, aux2_1, vl), isum1, vl); + vint32m1_t isum3 = __riscv_vredsum_vs_i32m2_i32m1(__riscv_vadd_vv_i32m2(aux3_0, aux3_1, vl), isum2, vl); + + sum_t += __riscv_vmv_x_s_i32m1_i32(isum3); + + q3 += 32; q8 += 128; scale += 8; + + } + + const float d = GGML_FP16_TO_FP32(x[i].d) * y[i].d; + + sumf += d*sum_t; + + } + + *s = sumf; + +#else + // scalar version + // This function is written like this so the compiler can manage to vectorize most of it + // Using -Ofast, GCC and clang manage to produce code that is within a factor of 2 or so from the + // manually vectorized version above. Every other version I tried would run at least 4 times slower. + // The ideal situation would be if we could just write the code once, and the compiler would + // automatically produce the best possible set of machine instructions, instead of us having to manually + // write vectorized versions for AVX, ARM_NEON, etc. + + int8_t aux8[QK_K]; + int16_t aux16[8]; + float sums [8]; + int32_t aux32[8]; + memset(sums, 0, 8*sizeof(float)); + + uint32_t auxs[4]; + const int8_t * scales = (const int8_t*)auxs; + + float sumf = 0; + for (int i = 0; i < nb; ++i) { + const uint8_t * restrict q3 = x[i].qs; + const uint8_t * restrict hm = x[i].hmask; + const int8_t * restrict q8 = y[i].qs; + memset(aux32, 0, 8*sizeof(int32_t)); + int8_t * restrict a = aux8; + uint8_t m = 1; + for (int j = 0; j < QK_K; j += 128) { + for (int l = 0; l < 32; ++l) a[l] = q3[l] & 3; + for (int l = 0; l < 32; ++l) a[l] -= (hm[l] & m ? 0 : 4); + a += 32; m <<= 1; + for (int l = 0; l < 32; ++l) a[l] = (q3[l] >> 2) & 3; + for (int l = 0; l < 32; ++l) a[l] -= (hm[l] & m ? 0 : 4); + a += 32; m <<= 1; + for (int l = 0; l < 32; ++l) a[l] = (q3[l] >> 4) & 3; + for (int l = 0; l < 32; ++l) a[l] -= (hm[l] & m ? 0 : 4); + a += 32; m <<= 1; + for (int l = 0; l < 32; ++l) a[l] = (q3[l] >> 6) & 3; + for (int l = 0; l < 32; ++l) a[l] -= (hm[l] & m ? 0 : 4); + a += 32; m <<= 1; + q3 += 32; + } + a = aux8; + + memcpy(auxs, x[i].scales, 12); + uint32_t tmp = auxs[2]; + auxs[2] = ((auxs[0] >> 4) & kmask2) | (((tmp >> 4) & kmask1) << 4); + auxs[3] = ((auxs[1] >> 4) & kmask2) | (((tmp >> 6) & kmask1) << 4); + auxs[0] = (auxs[0] & kmask2) | (((tmp >> 0) & kmask1) << 4); + auxs[1] = (auxs[1] & kmask2) | (((tmp >> 2) & kmask1) << 4); + for (int j = 0; j < QK_K/16; ++j) { + for (int l = 0; l < 8; ++l) aux16[l] = q8[l] * a[l]; + for (int l = 0; l < 8; ++l) aux32[l] += (scales[j] - 32) * aux16[l]; + q8 += 8; a += 8; + for (int l = 0; l < 8; ++l) aux16[l] = q8[l] * a[l]; + for (int l = 0; l < 8; ++l) aux32[l] += (scales[j] - 32) * aux16[l]; + q8 += 8; a += 8; + } + const float d = GGML_FP16_TO_FP32(x[i].d) * y[i].d; + for (int l = 0; l < 8; ++l) sums[l] += d * aux32[l]; + } + for (int l = 0; l < 8; ++l) sumf += sums[l]; + *s = sumf; + +#endif + +} + +#else + +void ggml_vec_dot_q3_K_q8_K(const int n, float * restrict s, const void * restrict vx, const void * restrict vy) { + assert(n % QK_K == 0); + + const block_q3_K * restrict x = vx; + const block_q8_K * restrict y = vy; + + const int nb = n / QK_K; + +#ifdef __ARM_NEON + +#ifdef __ARM_FEATURE_DOTPROD + const int32x4_t vzero = vdupq_n_s32(0); +#endif + + const uint8x16_t m3b = vdupq_n_u8(0x3); + const uint8x16_t mh = vdupq_n_u8(4); + + int8x16x4_t q3bytes; + + uint16_t aux16[2]; + int8_t * scales = (int8_t *)aux16; + + float sum = 0; + + for (int i = 0; i < nb; ++i) { + + uint8x16x4_t q3h; + + const uint8x8_t hbits = vld1_u8(x[i].hmask); + const uint8x16_t q3bits = vld1q_u8(x[i].qs); + const int8x16x4_t q8bytes = vld1q_s8_x4(y[i].qs); + + const uint16_t a = *(const uint16_t *)x[i].scales; + aux16[0] = a & 0x0f0f; + aux16[1] = (a >> 4) & 0x0f0f; + + for (int j = 0; j < 4; ++j) scales[j] -= 8; + + int32_t isum = -4*(scales[0] * y[i].bsums[0] + scales[2] * y[i].bsums[1] + scales[1] * y[i].bsums[2] + scales[3] * y[i].bsums[3]); + + const float d = y[i].d * (float)x[i].d; + + const uint8x16_t htmp = vcombine_u8(hbits, vshr_n_u8(hbits, 1)); + q3h.val[0] = vandq_u8(mh, vshlq_n_u8(htmp, 2)); + q3h.val[1] = vandq_u8(mh, htmp); + q3h.val[2] = vandq_u8(mh, vshrq_n_u8(htmp, 2)); + q3h.val[3] = vandq_u8(mh, vshrq_n_u8(htmp, 4)); + + q3bytes.val[0] = vreinterpretq_s8_u8(vorrq_u8(vandq_u8(q3bits, m3b), q3h.val[0])); + q3bytes.val[1] = vreinterpretq_s8_u8(vorrq_u8(vandq_u8(vshrq_n_u8(q3bits, 2), m3b), q3h.val[1])); + q3bytes.val[2] = vreinterpretq_s8_u8(vorrq_u8(vandq_u8(vshrq_n_u8(q3bits, 4), m3b), q3h.val[2])); + q3bytes.val[3] = vreinterpretq_s8_u8(vorrq_u8(vshrq_n_u8(q3bits, 6), q3h.val[3])); + +#if defined(__ARM_FEATURE_DOTPROD) + isum += vaddvq_s32(vdotq_s32(vzero, q3bytes.val[0], q8bytes.val[0])) * scales[0]; + isum += vaddvq_s32(vdotq_s32(vzero, q3bytes.val[1], q8bytes.val[1])) * scales[2]; + isum += vaddvq_s32(vdotq_s32(vzero, q3bytes.val[2], q8bytes.val[2])) * scales[1]; + isum += vaddvq_s32(vdotq_s32(vzero, q3bytes.val[3], q8bytes.val[3])) * scales[3]; +#else + const int16x8_t p0 = vaddq_s16(vmull_s8(vget_low_s8 (q3bytes.val[0]), vget_low_s8 (q8bytes.val[0])), + vmull_s8(vget_high_s8(q3bytes.val[0]), vget_high_s8(q8bytes.val[0]))); + const int16x8_t p1 = vaddq_s16(vmull_s8(vget_low_s8 (q3bytes.val[1]), vget_low_s8 (q8bytes.val[1])), + vmull_s8(vget_high_s8(q3bytes.val[1]), vget_high_s8(q8bytes.val[1]))); + const int16x8_t p2 = vaddq_s16(vmull_s8(vget_low_s8 (q3bytes.val[2]), vget_low_s8 (q8bytes.val[2])), + vmull_s8(vget_high_s8(q3bytes.val[2]), vget_high_s8(q8bytes.val[2]))); + const int16x8_t p3 = vaddq_s16(vmull_s8(vget_low_s8 (q3bytes.val[3]), vget_low_s8 (q8bytes.val[3])), + vmull_s8(vget_high_s8(q3bytes.val[3]), vget_high_s8(q8bytes.val[3]))); + isum += vaddvq_s16(p0) * scales[0] + vaddvq_s16(p1) * scales[2] + vaddvq_s16(p2) * scales[1] + vaddvq_s16(p3) * scales[3]; +#endif + + sum += d * isum; + + } + + *s = sum; + +#elif defined __AVX2__ + + const __m256i m3 = _mm256_set1_epi8(3); + const __m256i m1 = _mm256_set1_epi8(1); + + __m256 acc = _mm256_setzero_ps(); + + uint64_t aux64; + + uint16_t aux16[2]; + const int8_t * aux8 = (const int8_t *)aux16; + + for (int i = 0; i < nb; ++i) { + + const float d = y[i].d * GGML_FP16_TO_FP32(x[i].d); + + const uint8_t * restrict q3 = x[i].qs; + const int8_t * restrict q8 = y[i].qs; + + const uint16_t a = *(const uint16_t *)x[i].scales; + aux16[0] = a & 0x0f0f; + aux16[1] = (a >> 4) & 0x0f0f; + + const __m256i scale_0 = MM256_SET_M128I(_mm_set1_epi16(aux8[2] - 8), _mm_set1_epi16(aux8[0] - 8)); + const __m256i scale_1 = MM256_SET_M128I(_mm_set1_epi16(aux8[3] - 8), _mm_set1_epi16(aux8[1] - 8)); + + memcpy(&aux64, x[i].hmask, 8); + + const __m128i haux = _mm_set_epi64x(aux64 >> 1, aux64 >> 0); + __m256i q3h_0 = MM256_SET_M128I(_mm_srli_epi16(haux, 2), haux); + __m256i q3h_1 = _mm256_srli_epi16(q3h_0, 4); + q3h_0 = _mm256_slli_epi16(_mm256_andnot_si256(q3h_0, m1), 2); + q3h_1 = _mm256_slli_epi16(_mm256_andnot_si256(q3h_1, m1), 2); + + // load low 2 bits + const __m128i q3bits = _mm_loadu_si128((const __m128i*)q3); + + // prepare low and high bits + const __m256i q3aux = MM256_SET_M128I(_mm_srli_epi16(q3bits, 2), q3bits); + const __m256i q3l_0 = _mm256_and_si256(q3aux, m3); + const __m256i q3l_1 = _mm256_and_si256(_mm256_srli_epi16(q3aux, 4), m3); + + // load Q8 quants + const __m256i q8_0 = _mm256_loadu_si256((const __m256i*)(q8+ 0)); + const __m256i q8_1 = _mm256_loadu_si256((const __m256i*)(q8+32)); + + // Dot product: we multiply the 2 low bits and 1 high bit part separately, so we can use _mm256_maddubs_epi16, + // and then subtract. The high bit part has the 2 already subtracted (and so, it is zero if the high bit was not set, + // and 2 if the high bit was set) + const __m256i q8s_0 = _mm256_maddubs_epi16(q3h_0, q8_0); + const __m256i q8s_1 = _mm256_maddubs_epi16(q3h_1, q8_1); + + __m256i p16_0 = _mm256_maddubs_epi16(q3l_0, q8_0); + __m256i p16_1 = _mm256_maddubs_epi16(q3l_1, q8_1); + + p16_0 = _mm256_sub_epi16(p16_0, q8s_0); + p16_1 = _mm256_sub_epi16(p16_1, q8s_1); + + // multiply with scales + p16_0 = _mm256_madd_epi16(scale_0, p16_0); + p16_1 = _mm256_madd_epi16(scale_1, p16_1); + + p16_0 = _mm256_add_epi32(p16_0, p16_1); + + // multiply with block scale and accumulate + acc = _mm256_fmadd_ps(_mm256_broadcast_ss(&d), _mm256_cvtepi32_ps(p16_0), acc); + + } + + *s = hsum_float_8(acc); + +#elif defined __AVX__ + + const __m128i m3 = _mm_set1_epi8(3); + const __m128i m1 = _mm_set1_epi8(1); + + __m256 acc = _mm256_setzero_ps(); + + uint64_t aux64; + + uint16_t aux16[2]; + const int8_t * aux8 = (const int8_t *)aux16; + + for (int i = 0; i < nb; ++i) { + + const float d = y[i].d * GGML_FP16_TO_FP32(x[i].d); + + const uint8_t * restrict q3 = x[i].qs; + const int8_t * restrict q8 = y[i].qs; + + const uint16_t a = *(const uint16_t *)x[i].scales; + aux16[0] = a & 0x0f0f; + aux16[1] = (a >> 4) & 0x0f0f; + + const __m128i scale_0 = _mm_set1_epi16(aux8[0] - 8); + const __m128i scale_1 = _mm_set1_epi16(aux8[2] - 8); + const __m128i scale_2 = _mm_set1_epi16(aux8[1] - 8); + const __m128i scale_3 = _mm_set1_epi16(aux8[3] - 8); + + memcpy(&aux64, x[i].hmask, 8); + + __m128i q3h_0 = _mm_set_epi64x(aux64 >> 1, aux64 >> 0); + __m128i q3h_1 = _mm_srli_epi16(q3h_0, 2); + __m128i q3h_2 = _mm_srli_epi16(q3h_0, 4); + __m128i q3h_3 = _mm_srli_epi16(q3h_0, 6); + q3h_0 = _mm_slli_epi16(_mm_andnot_si128(q3h_0, m1), 2); + q3h_1 = _mm_slli_epi16(_mm_andnot_si128(q3h_1, m1), 2); + q3h_2 = _mm_slli_epi16(_mm_andnot_si128(q3h_2, m1), 2); + q3h_3 = _mm_slli_epi16(_mm_andnot_si128(q3h_3, m1), 2); + + // load low 2 bits + const __m128i q3bits = _mm_loadu_si128((const __m128i*)q3); + + // prepare low and high bits + const __m128i q3l_0 = _mm_and_si128(q3bits, m3); + const __m128i q3l_1 = _mm_and_si128(_mm_srli_epi16(q3bits, 2), m3); + const __m128i q3l_2 = _mm_and_si128(_mm_srli_epi16(q3bits, 4), m3); + const __m128i q3l_3 = _mm_and_si128(_mm_srli_epi16(q3bits, 6), m3); + + // load Q8 quants + const __m256i q8_0 = _mm256_loadu_si256((const __m256i*)(q8+ 0)); + const __m256i q8_1 = _mm256_loadu_si256((const __m256i*)(q8+32)); + + // Dot product: we multiply the 2 low bits and 1 high bit part separately, so we can use _mm_maddubs_epi16, + // and then subtract. The high bit part has the 2 already subtracted (and so, it is zero if the high bit was not set, + // and 2 if the high bit was set) + const __m128i q8s_0 = _mm_maddubs_epi16(q3h_0, _mm256_extractf128_si256(q8_0, 0)); + const __m128i q8s_1 = _mm_maddubs_epi16(q3h_1, _mm256_extractf128_si256(q8_0, 1)); + const __m128i q8s_2 = _mm_maddubs_epi16(q3h_2, _mm256_extractf128_si256(q8_1, 0)); + const __m128i q8s_3 = _mm_maddubs_epi16(q3h_3, _mm256_extractf128_si256(q8_1, 1)); + + __m128i p16_0 = _mm_maddubs_epi16(q3l_0, _mm256_extractf128_si256(q8_0, 0)); + __m128i p16_1 = _mm_maddubs_epi16(q3l_1, _mm256_extractf128_si256(q8_0, 1)); + __m128i p16_2 = _mm_maddubs_epi16(q3l_2, _mm256_extractf128_si256(q8_1, 0)); + __m128i p16_3 = _mm_maddubs_epi16(q3l_3, _mm256_extractf128_si256(q8_1, 1)); + + p16_0 = _mm_sub_epi16(p16_0, q8s_0); + p16_1 = _mm_sub_epi16(p16_1, q8s_1); + p16_2 = _mm_sub_epi16(p16_2, q8s_2); + p16_3 = _mm_sub_epi16(p16_3, q8s_3); + + // multiply with scales + p16_0 = _mm_madd_epi16(scale_0, p16_0); + p16_1 = _mm_madd_epi16(scale_1, p16_1); + p16_2 = _mm_madd_epi16(scale_2, p16_2); + p16_3 = _mm_madd_epi16(scale_3, p16_3); + + p16_0 = _mm_add_epi32(p16_0, p16_2); + p16_1 = _mm_add_epi32(p16_1, p16_3); + __m256i p16 = MM256_SET_M128I(p16_1, p16_0); + + // multiply with block scale and accumulate + acc = _mm256_add_ps(_mm256_mul_ps(_mm256_broadcast_ss(&d), _mm256_cvtepi32_ps(p16)), acc); + + } + + *s = hsum_float_8(acc); + +#elif defined __riscv_v_intrinsic + + uint16_t aux16[2]; + int8_t * scales = (int8_t *)aux16; + + float sumf = 0; + + for (int i = 0; i < nb; ++i) { + + const uint8_t * restrict q3 = x[i].qs; + const int8_t * restrict q8 = y[i].qs; + + const uint16_t a = *(const uint16_t *)x[i].scales; + aux16[0] = a & 0x0f0f; + aux16[1] = (a >> 4) & 0x0f0f; + + for (int j = 0; j < 4; ++j) scales[j] -= 8; + + int32_t isum = -4*(scales[0] * y[i].bsums[0] + scales[2] * y[i].bsums[1] + scales[1] * y[i].bsums[2] + scales[3] * y[i].bsums[3]); + + const float d = y[i].d * (float)x[i].d; + + vint32m1_t vzero = __riscv_vmv_v_x_i32m1(0, 1); + + // load qh + vuint8mf4_t qh_x1 = __riscv_vle8_v_u8mf4(x[i].hmask, 8); + vuint8mf2_t qh_x2 = __riscv_vlmul_ext_v_u8mf4_u8mf2(__riscv_vsrl_vx_u8mf4(qh_x1, 1, 8)); + + size_t vl = 16; + + // extend and combine both qh_x1 and qh_x2 + vuint8mf2_t qh_x = __riscv_vslideup_vx_u8mf2(__riscv_vlmul_ext_v_u8mf4_u8mf2(qh_x1), qh_x2, vl/2, vl); + + vuint8mf2_t qh_0 = __riscv_vand_vx_u8mf2(__riscv_vsll_vx_u8mf2(qh_x, 0x2, vl), 0x4, vl); + vuint8mf2_t qh_1 = __riscv_vand_vx_u8mf2(qh_x, 0x4, vl); + vuint8mf2_t qh_2 = __riscv_vand_vx_u8mf2(__riscv_vsrl_vx_u8mf2(qh_x, 0x2, vl), 0x4, vl); + vuint8mf2_t qh_3 = __riscv_vand_vx_u8mf2(__riscv_vsrl_vx_u8mf2(qh_x, 0x4, vl), 0x4, vl); + + // load Q3 + vuint8mf2_t q3_x = __riscv_vle8_v_u8mf2(q3, vl); + + vuint8mf2_t q3h_0 = __riscv_vor_vv_u8mf2(__riscv_vand_vx_u8mf2(q3_x, 0x3, vl), qh_0, vl); + vuint8mf2_t q3h_1 = __riscv_vor_vv_u8mf2(__riscv_vand_vx_u8mf2(__riscv_vsrl_vx_u8mf2(q3_x, 2, vl), 0x3, vl), qh_1, vl); + vuint8mf2_t q3h_2 = __riscv_vor_vv_u8mf2(__riscv_vand_vx_u8mf2(__riscv_vsrl_vx_u8mf2(q3_x, 4, vl), 0x3, vl), qh_2, vl); + vuint8mf2_t q3h_3 = __riscv_vor_vv_u8mf2(__riscv_vsrl_vx_u8mf2(q3_x, 0x6, vl), qh_3, vl); + + vint8mf2_t q3_0 = __riscv_vreinterpret_v_u8mf2_i8mf2(q3h_0); + vint8mf2_t q3_1 = __riscv_vreinterpret_v_u8mf2_i8mf2(q3h_1); + vint8mf2_t q3_2 = __riscv_vreinterpret_v_u8mf2_i8mf2(q3h_2); + vint8mf2_t q3_3 = __riscv_vreinterpret_v_u8mf2_i8mf2(q3h_3); + + // load Q8 and take product with Q3 + vint16m1_t p0 = __riscv_vwmul_vv_i16m1(q3_0, __riscv_vle8_v_i8mf2(q8, vl), vl); + vint16m1_t p1 = __riscv_vwmul_vv_i16m1(q3_1, __riscv_vle8_v_i8mf2(q8+16, vl), vl); + vint16m1_t p2 = __riscv_vwmul_vv_i16m1(q3_2, __riscv_vle8_v_i8mf2(q8+32, vl), vl); + vint16m1_t p3 = __riscv_vwmul_vv_i16m1(q3_3, __riscv_vle8_v_i8mf2(q8+48, vl), vl); + + vint32m1_t vs_0 = __riscv_vwredsum_vs_i16m1_i32m1(p0, vzero, vl); + vint32m1_t vs_1 = __riscv_vwredsum_vs_i16m1_i32m1(p1, vzero, vl); + vint32m1_t vs_2 = __riscv_vwredsum_vs_i16m1_i32m1(p2, vzero, vl); + vint32m1_t vs_3 = __riscv_vwredsum_vs_i16m1_i32m1(p3, vzero, vl); + + isum += __riscv_vmv_x_s_i32m1_i32(vs_0) * scales[0]; + isum += __riscv_vmv_x_s_i32m1_i32(vs_1) * scales[2]; + isum += __riscv_vmv_x_s_i32m1_i32(vs_2) * scales[1]; + isum += __riscv_vmv_x_s_i32m1_i32(vs_3) * scales[3]; + + sumf += d * isum; + + } + + *s = sumf; + +#else + + int8_t aux8[QK_K]; + int16_t aux16[8]; + float sums [8]; + int32_t aux32[8]; + int32_t scales[4]; + memset(sums, 0, 8*sizeof(float)); + + float sumf = 0; + for (int i = 0; i < nb; ++i) { + const uint8_t * restrict q3 = x[i].qs; + const uint8_t * restrict hm = x[i].hmask; + const int8_t * restrict q8 = y[i].qs; + int8_t * restrict a = aux8; + for (int l = 0; l < 8; ++l) { + a[l+ 0] = (int8_t)((q3[l+0] >> 0) & 3) - (hm[l] & 0x01 ? 0 : 4); + a[l+ 8] = (int8_t)((q3[l+8] >> 0) & 3) - (hm[l] & 0x02 ? 0 : 4); + a[l+16] = (int8_t)((q3[l+0] >> 2) & 3) - (hm[l] & 0x04 ? 0 : 4); + a[l+24] = (int8_t)((q3[l+8] >> 2) & 3) - (hm[l] & 0x08 ? 0 : 4); + a[l+32] = (int8_t)((q3[l+0] >> 4) & 3) - (hm[l] & 0x10 ? 0 : 4); + a[l+40] = (int8_t)((q3[l+8] >> 4) & 3) - (hm[l] & 0x20 ? 0 : 4); + a[l+48] = (int8_t)((q3[l+0] >> 6) & 3) - (hm[l] & 0x40 ? 0 : 4); + a[l+56] = (int8_t)((q3[l+8] >> 6) & 3) - (hm[l] & 0x80 ? 0 : 4); + } + + scales[0] = (x[i].scales[0] & 0xF) - 8; + scales[1] = (x[i].scales[0] >> 4) - 8; + scales[2] = (x[i].scales[1] & 0xF) - 8; + scales[3] = (x[i].scales[1] >> 4) - 8; + + memset(aux32, 0, 8*sizeof(int32_t)); + for (int j = 0; j < QK_K/16; ++j) { + for (int l = 0; l < 8; ++l) aux16[l] = q8[l] * a[l]; + q8 += 8; a += 8; + for (int l = 0; l < 8; ++l) aux16[l] += q8[l] * a[l]; + q8 += 8; a += 8; + for (int l = 0; l < 8; ++l) aux32[l] += scales[j] * aux16[l]; + } + const float d = GGML_FP16_TO_FP32(x[i].d) * y[i].d; + for (int l = 0; l < 8; ++l) sums[l] += d * aux32[l]; + } + for (int l = 0; l < 8; ++l) sumf += sums[l]; + *s = sumf; + +#endif + +} +#endif + +#if QK_K == 256 +void ggml_vec_dot_q4_K_q8_K(const int n, float * restrict s, const void * restrict vx, const void * restrict vy) { + assert(n % QK_K == 0); + + const block_q4_K * restrict x = vx; + const block_q8_K * restrict y = vy; + + const int nb = n / QK_K; + + static const uint32_t kmask1 = 0x3f3f3f3f; + static const uint32_t kmask2 = 0x0f0f0f0f; + static const uint32_t kmask3 = 0x03030303; + + uint32_t utmp[4]; + +#ifdef __ARM_NEON + + const uint8x16_t m4b = vdupq_n_u8(0xf); +#ifdef __ARM_FEATURE_DOTPROD + const int32x4_t mzero = vdupq_n_s32(0); +#endif + + int8x16x2_t q4bytes; + int8x16x2_t q8bytes; + + float sumf = 0; + + for (int i = 0; i < nb; ++i) { + + const float d = y[i].d * GGML_FP16_TO_FP32(x[i].d); + const float dmin = y[i].d * GGML_FP16_TO_FP32(x[i].dmin); + + const int16x8_t q8sums = vpaddq_s16(vld1q_s16(y[i].bsums), vld1q_s16(y[i].bsums + 8)); + + memcpy(utmp, x[i].scales, 12); + + uint32x2_t mins8 = { 0 }; + mins8 = vset_lane_u32(utmp[1] & kmask1, mins8, 0); + mins8 = vset_lane_u32(((utmp[2] >> 4) & kmask2) | (((utmp[1] >> 6) & kmask3) << 4), mins8, 1); + + utmp[1] = (utmp[2] & kmask2) | (((utmp[0] >> 6) & kmask3) << 4); + utmp[0] &= kmask1; + + const int16x8_t mins = vreinterpretq_s16_u16(vmovl_u8(vreinterpret_u8_u32(mins8))); + const int32x4_t prod = vaddq_s32(vmull_s16(vget_low_s16 (q8sums), vget_low_s16 (mins)), + vmull_s16(vget_high_s16(q8sums), vget_high_s16(mins))); + sumf -= dmin * vaddvq_s32(prod); + + const uint8_t * scales = (const uint8_t *)utmp; + + const uint8_t * restrict q4 = x[i].qs; + const int8_t * restrict q8 = y[i].qs; + + int32_t sumi1 = 0; + int32_t sumi2 = 0; + + for (int j = 0; j < QK_K/64; ++j) { + + const uint8x16x2_t q4bits = vld1q_u8_x2(q4); q4 += 32; + +#ifdef __ARM_FEATURE_DOTPROD + q8bytes = vld1q_s8_x2(q8); q8 += 32; + q4bytes.val[0] = vreinterpretq_s8_u8(vandq_u8 (q4bits.val[0], m4b)); + q4bytes.val[1] = vreinterpretq_s8_u8(vandq_u8 (q4bits.val[1], m4b)); + + const int32x4_t p1 = vdotq_s32(vdotq_s32(mzero, q4bytes.val[0], q8bytes.val[0]), q4bytes.val[1], q8bytes.val[1]); + sumi1 += vaddvq_s32(p1) * scales[2*j+0]; + + q8bytes = vld1q_s8_x2(q8); q8 += 32; + q4bytes.val[0] = vreinterpretq_s8_u8(vshrq_n_u8(q4bits.val[0], 4)); + q4bytes.val[1] = vreinterpretq_s8_u8(vshrq_n_u8(q4bits.val[1], 4)); + + const int32x4_t p2 = vdotq_s32(vdotq_s32(mzero, q4bytes.val[0], q8bytes.val[0]), q4bytes.val[1], q8bytes.val[1]); + + sumi2 += vaddvq_s32(p2) * scales[2*j+1]; +#else + q8bytes = vld1q_s8_x2(q8); q8 += 32; + q4bytes.val[0] = vreinterpretq_s8_u8(vandq_u8 (q4bits.val[0], m4b)); + q4bytes.val[1] = vreinterpretq_s8_u8(vandq_u8 (q4bits.val[1], m4b)); + const int16x8_t p0 = vaddq_s16(vmull_s8(vget_low_s8 (q4bytes.val[0]), vget_low_s8 (q8bytes.val[0])), + vmull_s8(vget_high_s8(q4bytes.val[0]), vget_high_s8(q8bytes.val[0]))); + const int16x8_t p1 = vaddq_s16(vmull_s8(vget_low_s8 (q4bytes.val[1]), vget_low_s8 (q8bytes.val[1])), + vmull_s8(vget_high_s8(q4bytes.val[1]), vget_high_s8(q8bytes.val[1]))); + sumi1 += vaddvq_s16(vaddq_s16(p0, p1)) * scales[2*j+0]; + + q8bytes = vld1q_s8_x2(q8); q8 += 32; + q4bytes.val[0] = vreinterpretq_s8_u8(vshrq_n_u8(q4bits.val[0], 4)); + q4bytes.val[1] = vreinterpretq_s8_u8(vshrq_n_u8(q4bits.val[1], 4)); + const int16x8_t p2 = vaddq_s16(vmull_s8(vget_low_s8 (q4bytes.val[0]), vget_low_s8 (q8bytes.val[0])), + vmull_s8(vget_high_s8(q4bytes.val[0]), vget_high_s8(q8bytes.val[0]))); + const int16x8_t p3 = vaddq_s16(vmull_s8(vget_low_s8 (q4bytes.val[1]), vget_low_s8 (q8bytes.val[1])), + vmull_s8(vget_high_s8(q4bytes.val[1]), vget_high_s8(q8bytes.val[1]))); + sumi2 += vaddvq_s16(vaddq_s16(p2, p3)) * scales[2*j+1]; + +#endif + } + + sumf += d * (sumi1 + sumi2); + + } + + *s = sumf; + +#elif defined __AVX2__ + + const __m256i m4 = _mm256_set1_epi8(0xF); + + __m256 acc = _mm256_setzero_ps(); + __m128 acc_m = _mm_setzero_ps(); + + for (int i = 0; i < nb; ++i) { + + const float d = y[i].d * GGML_FP16_TO_FP32(x[i].d); + const float dmin = -y[i].d * GGML_FP16_TO_FP32(x[i].dmin); + + memcpy(utmp, x[i].scales, 12); + utmp[3] = ((utmp[2] >> 4) & kmask2) | (((utmp[1] >> 6) & kmask3) << 4); + const uint32_t uaux = utmp[1] & kmask1; + utmp[1] = (utmp[2] & kmask2) | (((utmp[0] >> 6) & kmask3) << 4); + utmp[2] = uaux; + utmp[0] &= kmask1; + + const uint8_t * restrict q4 = x[i].qs; + const int8_t * restrict q8 = y[i].qs; + + const __m256i mins_and_scales = _mm256_cvtepu8_epi16(_mm_set_epi32(utmp[3], utmp[2], utmp[1], utmp[0])); + + const __m256i q8sums = _mm256_loadu_si256((const __m256i*)y[i].bsums); + const __m128i q8s = _mm_hadd_epi16(_mm256_extracti128_si256(q8sums, 0), _mm256_extracti128_si256(q8sums, 1)); + const __m128i prod = _mm_madd_epi16(_mm256_extracti128_si256(mins_and_scales, 1), q8s); + acc_m = _mm_fmadd_ps(_mm_set1_ps(dmin), _mm_cvtepi32_ps(prod), acc_m); + + const __m128i sc128 = _mm256_extracti128_si256(mins_and_scales, 0); + const __m256i scales = MM256_SET_M128I(sc128, sc128); + + __m256i sumi = _mm256_setzero_si256(); + + for (int j = 0; j < QK_K/64; ++j) { + + const __m256i scale_l = _mm256_shuffle_epi8(scales, get_scale_shuffle_k4(2*j+0)); + const __m256i scale_h = _mm256_shuffle_epi8(scales, get_scale_shuffle_k4(2*j+1)); + + const __m256i q4bits = _mm256_loadu_si256((const __m256i*)q4); q4 += 32; + const __m256i q4l = _mm256_and_si256(q4bits, m4); + const __m256i q4h = _mm256_and_si256(_mm256_srli_epi16(q4bits, 4), m4); + + const __m256i q8l = _mm256_loadu_si256((const __m256i*)q8); q8 += 32; + __m256i p16l = _mm256_maddubs_epi16(q4l, q8l); + p16l = _mm256_madd_epi16(scale_l, p16l); + + const __m256i q8h = _mm256_loadu_si256((const __m256i*)q8); q8 += 32; + __m256i p16h = _mm256_maddubs_epi16(q4h, q8h); + p16h = _mm256_madd_epi16(scale_h, p16h); + const __m256i sumj = _mm256_add_epi32(p16l, p16h); + + sumi = _mm256_add_epi32(sumi, sumj); + } + + __m256 vd = _mm256_set1_ps(d); + acc = _mm256_fmadd_ps(vd, _mm256_cvtepi32_ps(sumi), acc); + + } + + acc_m = _mm_add_ps(acc_m, _mm_movehl_ps(acc_m, acc_m)); + acc_m = _mm_add_ss(acc_m, _mm_movehdup_ps(acc_m)); + + *s = hsum_float_8(acc) + _mm_cvtss_f32(acc_m); + +#elif defined __AVX__ + + const __m128i m4 = _mm_set1_epi8(0xF); + const __m128i m2 = _mm_set1_epi8(0x2); + + __m256 acc = _mm256_setzero_ps(); + __m128 acc_m = _mm_setzero_ps(); + + for (int i = 0; i < nb; ++i) { + + const float d = y[i].d * GGML_FP16_TO_FP32(x[i].d); + const float dmin = -y[i].d * GGML_FP16_TO_FP32(x[i].dmin); + + const uint8_t * restrict q4 = x[i].qs; + const int8_t * restrict q8 = y[i].qs; + + memcpy(utmp, x[i].scales, 12); + utmp[3] = ((utmp[2] >> 4) & kmask2) | (((utmp[1] >> 6) & kmask3) << 4); + const uint32_t uaux = utmp[1] & kmask1; + utmp[1] = (utmp[2] & kmask2) | (((utmp[0] >> 6) & kmask3) << 4); + utmp[2] = uaux; + utmp[0] &= kmask1; + + const __m128i utmps = _mm_set_epi32(utmp[3], utmp[2], utmp[1], utmp[0]); + const __m128i scales = _mm_cvtepu8_epi16(utmps); + const __m128i mins = _mm_cvtepu8_epi16(_mm_unpackhi_epi64(utmps, utmps)); + + const __m128i q8sums_0 = _mm_loadu_si128((const __m128i*)&y[i].bsums[0]); + const __m128i q8sums_1 = _mm_loadu_si128((const __m128i*)&y[i].bsums[8]); + const __m128i q8s = _mm_hadd_epi16(q8sums_0, q8sums_1); + const __m128i prod = _mm_madd_epi16(mins, q8s); + acc_m = _mm_add_ps(_mm_mul_ps(_mm_set1_ps(dmin), _mm_cvtepi32_ps(prod)), acc_m); + + __m128i sumi_0 = _mm_setzero_si128(); + __m128i sumi_1 = _mm_setzero_si128(); + + __m128i shuffle = _mm_set1_epi16(0x0100); + for (int j = 0; j < QK_K/64; ++j) { + + const __m128i scale_l = _mm_shuffle_epi8(scales, shuffle); + shuffle = _mm_add_epi16(shuffle, m2); + const __m128i scale_h = _mm_shuffle_epi8(scales, shuffle); + shuffle = _mm_add_epi16(shuffle, m2); + + __m128i q4bits = _mm_loadu_si128((const __m128i*)q4); q4 += 16; + const __m128i q4l_0 = _mm_and_si128(q4bits, m4); + const __m128i q4h_0 = _mm_and_si128(_mm_srli_epi16(q4bits, 4), m4); + q4bits = _mm_loadu_si128((const __m128i*)q4); q4 += 16; + const __m128i q4l_1 = _mm_and_si128(q4bits, m4); + const __m128i q4h_1 = _mm_and_si128(_mm_srli_epi16(q4bits, 4), m4); + + const __m128i q8l_0 = _mm_loadu_si128((const __m128i*)q8); q8 += 16; + __m128i p16l = _mm_maddubs_epi16(q4l_0, q8l_0); + p16l = _mm_madd_epi16(scale_l, p16l); + sumi_0 = _mm_add_epi32(sumi_0, p16l); + const __m128i q8l_1 = _mm_loadu_si128((const __m128i*)q8); q8 += 16; + p16l = _mm_maddubs_epi16(q4l_1, q8l_1); + p16l = _mm_madd_epi16(scale_l, p16l); + sumi_1 = _mm_add_epi32(sumi_1, p16l); + + const __m128i q8h_0 = _mm_loadu_si128((const __m128i*)q8); q8 += 16; + __m128i p16h = _mm_maddubs_epi16(q4h_0, q8h_0); + p16h = _mm_madd_epi16(scale_h, p16h); + sumi_0 = _mm_add_epi32(sumi_0, p16h); + const __m128i q8h_1 = _mm_loadu_si128((const __m128i*)q8); q8 += 16; + p16h = _mm_maddubs_epi16(q4h_1, q8h_1); + p16h = _mm_madd_epi16(scale_h, p16h); + sumi_1 = _mm_add_epi32(sumi_1, p16h); + + } + + __m256 vd = _mm256_set1_ps(d); + __m256i sumi = MM256_SET_M128I(sumi_1, sumi_0); + acc = _mm256_add_ps(_mm256_mul_ps(vd, _mm256_cvtepi32_ps(sumi)), acc); + + } + + acc_m = _mm_add_ps(acc_m, _mm_movehl_ps(acc_m, acc_m)); + acc_m = _mm_add_ss(acc_m, _mm_movehdup_ps(acc_m)); + + *s = hsum_float_8(acc) + _mm_cvtss_f32(acc_m); + +#elif defined __riscv_v_intrinsic + + const uint8_t * scales = (const uint8_t*)&utmp[0]; + const uint8_t * mins = (const uint8_t*)&utmp[2]; + + float sumf = 0; + + for (int i = 0; i < nb; ++i) { + + size_t vl = 8; + + const float d = y[i].d * GGML_FP16_TO_FP32(x[i].d); + const float dmin = y[i].d * GGML_FP16_TO_FP32(x[i].dmin); + + vint16mf2_t q8sums_0 = __riscv_vlse16_v_i16mf2(y[i].bsums, 4, vl); + vint16mf2_t q8sums_1 = __riscv_vlse16_v_i16mf2(y[i].bsums+1, 4, vl); + vint16mf2_t q8sums = __riscv_vadd_vv_i16mf2(q8sums_0, q8sums_1, vl); + + memcpy(utmp, x[i].scales, 12); + utmp[3] = ((utmp[2] >> 4) & kmask2) | (((utmp[1] >> 6) & kmask3) << 4); + const uint32_t uaux = utmp[1] & kmask1; + utmp[1] = (utmp[2] & kmask2) | (((utmp[0] >> 6) & kmask3) << 4); + utmp[2] = uaux; + utmp[0] &= kmask1; + + vuint8mf4_t mins8 = __riscv_vle8_v_u8mf4(mins, vl); + vint16mf2_t v_mins = __riscv_vreinterpret_v_u16mf2_i16mf2(__riscv_vzext_vf2_u16mf2(mins8, vl)); + vint32m1_t prod = __riscv_vwmul_vv_i32m1(q8sums, v_mins, vl); + + vint32m1_t sumi = __riscv_vredsum_vs_i32m1_i32m1(prod, __riscv_vmv_v_x_i32m1(0, 1), vl); + sumf -= dmin * __riscv_vmv_x_s_i32m1_i32(sumi); + + const uint8_t * restrict q4 = x[i].qs; + const int8_t * restrict q8 = y[i].qs; + + vl = 32; + + int32_t sum_1 = 0; + int32_t sum_2 = 0; + + vint16m1_t vzero = __riscv_vmv_v_x_i16m1(0, 1); + + for (int j = 0; j < QK_K/64; ++j) { + // load Q4 + vuint8m1_t q4_x = __riscv_vle8_v_u8m1(q4, vl); + + // load Q8 and multiply it with lower Q4 nibble + vint8m1_t q8_0 = __riscv_vle8_v_i8m1(q8, vl); + vint8m1_t q4_0 = __riscv_vreinterpret_v_u8m1_i8m1(__riscv_vand_vx_u8m1(q4_x, 0x0F, vl)); + vint16m2_t qv_0 = __riscv_vwmul_vv_i16m2(q4_0, q8_0, vl); + vint16m1_t vs_0 = __riscv_vredsum_vs_i16m2_i16m1(qv_0, vzero, vl); + + sum_1 += __riscv_vmv_x_s_i16m1_i16(vs_0) * scales[2*j+0]; + + // load Q8 and multiply it with upper Q4 nibble + vint8m1_t q8_1 = __riscv_vle8_v_i8m1(q8+32, vl); + vint8m1_t q4_1 = __riscv_vreinterpret_v_u8m1_i8m1(__riscv_vsrl_vx_u8m1(q4_x, 0x04, vl)); + vint16m2_t qv_1 = __riscv_vwmul_vv_i16m2(q4_1, q8_1, vl); + vint16m1_t vs_1 = __riscv_vredsum_vs_i16m2_i16m1(qv_1, vzero, vl); + + sum_2 += __riscv_vmv_x_s_i16m1_i16(vs_1) * scales[2*j+1]; + + q4 += 32; q8 += 64; + + } + + sumf += d*(sum_1 + sum_2); + + } + + *s = sumf; + +#else + + + const uint8_t * scales = (const uint8_t*)&utmp[0]; + const uint8_t * mins = (const uint8_t*)&utmp[2]; + + int8_t aux8[QK_K]; + int16_t aux16[8]; + float sums [8]; + int32_t aux32[8]; + memset(sums, 0, 8*sizeof(float)); + + float sumf = 0; + for (int i = 0; i < nb; ++i) { + const uint8_t * restrict q4 = x[i].qs; + const int8_t * restrict q8 = y[i].qs; + memset(aux32, 0, 8*sizeof(int32_t)); + int8_t * restrict a = aux8; + for (int j = 0; j < QK_K/64; ++j) { + for (int l = 0; l < 32; ++l) a[l] = (int8_t)(q4[l] & 0xF); + a += 32; + for (int l = 0; l < 32; ++l) a[l] = (int8_t)(q4[l] >> 4); + a += 32; q4 += 32; + } + memcpy(utmp, x[i].scales, 12); + utmp[3] = ((utmp[2] >> 4) & kmask2) | (((utmp[1] >> 6) & kmask3) << 4); + const uint32_t uaux = utmp[1] & kmask1; + utmp[1] = (utmp[2] & kmask2) | (((utmp[0] >> 6) & kmask3) << 4); + utmp[2] = uaux; + utmp[0] &= kmask1; + + int sumi = 0; + for (int j = 0; j < QK_K/16; ++j) sumi += y[i].bsums[j] * mins[j/2]; + a = aux8; + int is = 0; + for (int j = 0; j < QK_K/32; ++j) { + int32_t scale = scales[is++]; + for (int l = 0; l < 8; ++l) aux16[l] = q8[l] * a[l]; + for (int l = 0; l < 8; ++l) aux32[l] += scale * aux16[l]; + q8 += 8; a += 8; + for (int l = 0; l < 8; ++l) aux16[l] = q8[l] * a[l]; + for (int l = 0; l < 8; ++l) aux32[l] += scale * aux16[l]; + q8 += 8; a += 8; + for (int l = 0; l < 8; ++l) aux16[l] = q8[l] * a[l]; + for (int l = 0; l < 8; ++l) aux32[l] += scale * aux16[l]; + q8 += 8; a += 8; + for (int l = 0; l < 8; ++l) aux16[l] = q8[l] * a[l]; + for (int l = 0; l < 8; ++l) aux32[l] += scale * aux16[l]; + q8 += 8; a += 8; + } + const float d = GGML_FP16_TO_FP32(x[i].d) * y[i].d; + for (int l = 0; l < 8; ++l) sums[l] += d * aux32[l]; + const float dmin = GGML_FP16_TO_FP32(x[i].dmin) * y[i].d; + sumf -= dmin * sumi; + } + for (int l = 0; l < 8; ++l) sumf += sums[l]; + *s = sumf; +#endif +} +#else +void ggml_vec_dot_q4_K_q8_K(const int n, float * restrict s, const void * restrict vx, const void * restrict vy) { + assert(n % QK_K == 0); + + const block_q4_K * restrict x = vx; + const block_q8_K * restrict y = vy; + + const int nb = n / QK_K; + +#ifdef __ARM_NEON + + const uint8x16_t m4b = vdupq_n_u8(0xf); + +#ifdef __ARM_FEATURE_DOTPROD + const int32x4_t mzero = vdupq_n_s32(0); +#endif + + float sumf = 0; + + int8x16x2_t q4bytes; + int8x16x4_t q8bytes; + + float sum_mins = 0.f; + + uint16_t aux16[2]; + const uint8_t * restrict scales = (const uint8_t *)aux16; + + for (int i = 0; i < nb; ++i) { + + const uint8_t * restrict q4 = x[i].qs; + const int8_t * restrict q8 = y[i].qs; + + const uint16_t * restrict a = (const uint16_t *)x[i].scales; + aux16[0] = a[0] & 0x0f0f; + aux16[1] = (a[0] >> 4) & 0x0f0f; + + const int32_t summi = scales[2] * (y[i].bsums[0] + y[i].bsums[1]) + scales[3] * (y[i].bsums[2] + y[i].bsums[3]); + sum_mins += y[i].d * (float)x[i].d[1] * summi; + + const float d = y[i].d * (float)x[i].d[0]; + + const uint8x16x2_t q4bits = vld1q_u8_x2(q4); + +#ifdef __ARM_FEATURE_DOTPROD + q8bytes = vld1q_s8_x4(q8); + q4bytes.val[0] = vreinterpretq_s8_u8(vandq_u8 (q4bits.val[0], m4b)); + q4bytes.val[1] = vreinterpretq_s8_u8(vandq_u8 (q4bits.val[1], m4b)); + + const int32x4_t p1 = vdotq_s32(vdotq_s32(mzero, q4bytes.val[0], q8bytes.val[0]), q4bytes.val[1], q8bytes.val[1]); + const int32_t sumi1 = vaddvq_s32(p1) * scales[0]; + + q4bytes.val[0] = vreinterpretq_s8_u8(vshrq_n_u8(q4bits.val[0], 4)); + q4bytes.val[1] = vreinterpretq_s8_u8(vshrq_n_u8(q4bits.val[1], 4)); + + const int32x4_t p2 = vdotq_s32(vdotq_s32(mzero, q4bytes.val[0], q8bytes.val[2]), q4bytes.val[1], q8bytes.val[3]); + const int32_t sumi2 = vaddvq_s32(p2) * scales[1]; + +#else + q8bytes = vld1q_s8_x4(q8); + q4bytes.val[0] = vreinterpretq_s8_u8(vandq_u8 (q4bits.val[0], m4b)); + q4bytes.val[1] = vreinterpretq_s8_u8(vandq_u8 (q4bits.val[1], m4b)); + const int16x8_t p0 = vaddq_s16(vmull_s8(vget_low_s8 (q4bytes.val[0]), vget_low_s8 (q8bytes.val[0])), + vmull_s8(vget_high_s8(q4bytes.val[0]), vget_high_s8(q8bytes.val[0]))); + const int16x8_t p1 = vaddq_s16(vmull_s8(vget_low_s8 (q4bytes.val[1]), vget_low_s8 (q8bytes.val[1])), + vmull_s8(vget_high_s8(q4bytes.val[1]), vget_high_s8(q8bytes.val[1]))); + int32_t sumi1 = vaddvq_s16(vaddq_s16(p0, p1)) * scales[0]; + + q4bytes.val[0] = vreinterpretq_s8_u8(vshrq_n_u8(q4bits.val[0], 4)); + q4bytes.val[1] = vreinterpretq_s8_u8(vshrq_n_u8(q4bits.val[1], 4)); + const int16x8_t p2 = vaddq_s16(vmull_s8(vget_low_s8 (q4bytes.val[0]), vget_low_s8 (q8bytes.val[2])), + vmull_s8(vget_high_s8(q4bytes.val[0]), vget_high_s8(q8bytes.val[2]))); + const int16x8_t p3 = vaddq_s16(vmull_s8(vget_low_s8 (q4bytes.val[1]), vget_low_s8 (q8bytes.val[3])), + vmull_s8(vget_high_s8(q4bytes.val[1]), vget_high_s8(q8bytes.val[3]))); + int32_t sumi2 = vaddvq_s16(vaddq_s16(p2, p3)) * scales[1]; + +#endif + sumf += d * (sumi1 + sumi2); + + } + + *s = sumf - sum_mins; + +#elif defined __AVX2__ + + const __m256i m4 = _mm256_set1_epi8(0xF); + + __m256 acc = _mm256_setzero_ps(); + + float summs = 0; + + uint16_t aux16[2]; + const uint8_t * scales = (const uint8_t *)aux16; + + for (int i = 0; i < nb; ++i) { + + const float d = GGML_FP16_TO_FP32(x[i].d[0]) * y[i].d; + const float m = GGML_FP16_TO_FP32(x[i].d[1]) * y[i].d; + const __m256 vd = _mm256_set1_ps(d); + + const uint16_t * a = (const uint16_t *)x[i].scales; + aux16[0] = a[0] & 0x0f0f; + aux16[1] = (a[0] >> 4) & 0x0f0f; + + summs += m * (scales[2] * (y[i].bsums[0] + y[i].bsums[1]) + scales[3] * (y[i].bsums[2] + y[i].bsums[3])); + + const uint8_t * restrict q4 = x[i].qs; + const int8_t * restrict q8 = y[i].qs; + + const __m256i q4bits = _mm256_loadu_si256((const __m256i*)q4); + const __m256i q4l = _mm256_and_si256(q4bits, m4); + const __m256i q4h = _mm256_and_si256(_mm256_srli_epi16(q4bits, 4), m4); + + const __m256i q8l = _mm256_loadu_si256((const __m256i*)(q8+ 0)); + const __m256i q8h = _mm256_loadu_si256((const __m256i*)(q8+32)); + + const __m256i p16l = _mm256_maddubs_epi16(q4l, q8l); + const __m256i p16h = _mm256_maddubs_epi16(q4h, q8h); + + const __m256i p32l = _mm256_madd_epi16(_mm256_set1_epi16(scales[0]), p16l); + acc = _mm256_fmadd_ps(vd, _mm256_cvtepi32_ps(p32l), acc); + + const __m256i p32h = _mm256_madd_epi16(_mm256_set1_epi16(scales[1]), p16h); + acc = _mm256_fmadd_ps(vd, _mm256_cvtepi32_ps(p32h), acc); + + } + + *s = hsum_float_8(acc) - summs; + +#elif defined __AVX__ + + const __m128i m4 = _mm_set1_epi8(0xF); + + __m256 acc = _mm256_setzero_ps(); + + float summs = 0; + + uint16_t aux16[2]; + const uint8_t * scales = (const uint8_t *)aux16; + + for (int i = 0; i < nb; ++i) { + + const float d = GGML_FP16_TO_FP32(x[i].d[0]) * y[i].d; + const float m = GGML_FP16_TO_FP32(x[i].d[1]) * y[i].d; + const __m256 vd = _mm256_set1_ps(d); + + const uint16_t * a = (const uint16_t *)x[i].scales; + aux16[0] = a[0] & 0x0f0f; + aux16[1] = (a[0] >> 4) & 0x0f0f; + + summs += m * (scales[2] * (y[i].bsums[0] + y[i].bsums[1]) + scales[3] * (y[i].bsums[2] + y[i].bsums[3])); + + const uint8_t * restrict q4 = x[i].qs; + const int8_t * restrict q8 = y[i].qs; + + const __m256i q4bits = _mm256_loadu_si256((const __m256i*)q4); + const __m128i q4bits_0 = _mm256_extractf128_si256(q4bits, 0); + const __m128i q4bits_1 = _mm256_extractf128_si256(q4bits, 1); + const __m128i q4_0 = _mm_and_si128(q4bits_0, m4); + const __m128i q4_1 = _mm_and_si128(q4bits_1, m4); + const __m128i q4_2 = _mm_and_si128(_mm_srli_epi16(q4bits_0, 4), m4); + const __m128i q4_3 = _mm_and_si128(_mm_srli_epi16(q4bits_1, 4), m4); + + const __m256i q8_0 = _mm256_loadu_si256((const __m256i*)(q8+ 0)); + const __m256i q8_1 = _mm256_loadu_si256((const __m256i*)(q8+32)); + + const __m128i p16_0 = _mm_maddubs_epi16(q4_0, _mm256_extractf128_si256(q8_0, 0)); + const __m128i p16_1 = _mm_maddubs_epi16(q4_1, _mm256_extractf128_si256(q8_0, 1)); + const __m128i p16_2 = _mm_maddubs_epi16(q4_2, _mm256_extractf128_si256(q8_1, 0)); + const __m128i p16_3 = _mm_maddubs_epi16(q4_3, _mm256_extractf128_si256(q8_1, 1)); + + const __m128i p32_0 = _mm_madd_epi16(_mm_set1_epi16(scales[0]), p16_0); + const __m128i p32_1 = _mm_madd_epi16(_mm_set1_epi16(scales[0]), p16_1); + acc = _mm256_add_ps(_mm256_mul_ps(vd, _mm256_cvtepi32_ps(MM256_SET_M128I(p32_1, p32_0))), acc); + + const __m128i p32_2 = _mm_madd_epi16(_mm_set1_epi16(scales[1]), p16_2); + const __m128i p32_3 = _mm_madd_epi16(_mm_set1_epi16(scales[1]), p16_3); + acc = _mm256_add_ps(_mm256_mul_ps(vd, _mm256_cvtepi32_ps(MM256_SET_M128I(p32_3, p32_2))), acc); + + } + + *s = hsum_float_8(acc) - summs; + +#elif defined __riscv_v_intrinsic + + uint16_t s16[2]; + const uint8_t * restrict scales = (const uint8_t *)s16; + + float sumf = 0; + + for (int i = 0; i < nb; ++i) { + + const uint8_t * restrict q4 = x[i].qs; + const int8_t * restrict q8 = y[i].qs; + + const uint16_t * restrict b = (const uint16_t *)x[i].scales; + s16[0] = b[0] & 0x0f0f; + s16[1] = (b[0] >> 4) & 0x0f0f; + + sumf -= y[i].d * GGML_FP16_TO_FP32(x[i].d[1]) * (scales[2] * (y[i].bsums[0] + y[i].bsums[1]) + scales[3] * (y[i].bsums[2] + y[i].bsums[3])); + const float d = y[i].d * GGML_FP16_TO_FP32(x[i].d[0]); + + size_t vl = 32; + + vint16m1_t vzero = __riscv_vmv_v_x_i16m1(0, 1); + + // load Q4 + vuint8m1_t q4_x = __riscv_vle8_v_u8m1(q4, vl); + + // load Q8 and multiply it with lower Q4 nibble + vint8m1_t q4_a = __riscv_vreinterpret_v_u8m1_i8m1(__riscv_vand_vx_u8m1(q4_x, 0x0F, vl)); + vint16m2_t va_0 = __riscv_vwmul_vv_i16m2(q4_a, __riscv_vle8_v_i8m1(q8, vl), vl); + vint16m1_t aux1 = __riscv_vredsum_vs_i16m2_i16m1(va_0, vzero, vl); + + sumf += d*scales[0]*__riscv_vmv_x_s_i16m1_i16(aux1); + + // load Q8 and multiply it with upper Q4 nibble + vint8m1_t q4_s = __riscv_vreinterpret_v_u8m1_i8m1(__riscv_vsrl_vx_u8m1(q4_x, 0x04, vl)); + vint16m2_t va_1 = __riscv_vwmul_vv_i16m2(q4_s, __riscv_vle8_v_i8m1(q8+32, vl), vl); + vint16m1_t aux2 = __riscv_vredsum_vs_i16m2_i16m1(va_1, vzero, vl); + + sumf += d*scales[1]*__riscv_vmv_x_s_i16m1_i16(aux2); + + } + + *s = sumf; + +#else + + uint8_t aux8[QK_K]; + int16_t aux16[16]; + float sums [8]; + memset(sums, 0, 8*sizeof(float)); + + uint16_t s16[2]; + const uint8_t * restrict scales = (const uint8_t *)s16; + + float sumf = 0; + for (int i = 0; i < nb; ++i) { + const uint8_t * restrict q4 = x[i].qs; + const int8_t * restrict q8 = y[i].qs; + uint8_t * restrict a = aux8; + for (int l = 0; l < 32; ++l) a[l+ 0] = q4[l] & 0xF; + for (int l = 0; l < 32; ++l) a[l+32] = q4[l] >> 4; + + const uint16_t * restrict b = (const uint16_t *)x[i].scales; + s16[0] = b[0] & 0x0f0f; + s16[1] = (b[0] >> 4) & 0x0f0f; + + sumf -= y[i].d * GGML_FP16_TO_FP32(x[i].d[1]) * (scales[2] * (y[i].bsums[0] + y[i].bsums[1]) + scales[3] * (y[i].bsums[2] + y[i].bsums[3])); + + const float d = y[i].d * GGML_FP16_TO_FP32(x[i].d[0]); + + for (int j = 0; j < QK_K/32; ++j) { + for (int l = 0; l < 16; ++l) aux16[l] = q8[l] * a[l]; + q8 += 16; a += 16; + for (int l = 0; l < 16; ++l) aux16[l] += q8[l] * a[l]; + q8 += 16; a += 16; + const float dl = d * scales[j]; + for (int l = 0; l < 8; ++l) sums[l] += dl * (aux16[l] + aux16[l+8]); + } + } + for (int l = 0; l < 8; ++l) sumf += sums[l]; + *s = sumf; +#endif +} +#endif + +#if QK_K == 256 +void ggml_vec_dot_q5_K_q8_K(const int n, float * restrict s, const void * restrict vx, const void * restrict vy) { + assert(n % QK_K == 0); + + const block_q5_K * restrict x = vx; + const block_q8_K * restrict y = vy; + + const int nb = n / QK_K; + + static const uint32_t kmask1 = 0x3f3f3f3f; + static const uint32_t kmask2 = 0x0f0f0f0f; + static const uint32_t kmask3 = 0x03030303; + + uint32_t utmp[4]; + + +#ifdef __ARM_NEON + + const uint8x16_t m4b = vdupq_n_u8(0xf); + const uint8x16_t mone = vdupq_n_u8(1); + const uint8x16_t mtwo = vdupq_n_u8(2); +#if defined(__ARM_FEATURE_DOTPROD) + const int32x4_t mzero = vdupq_n_s32(0); +#endif + + int8x16x4_t q5bytes; + + float sumf = 0; + + for (int i = 0; i < nb; ++i) { + + const float d = y[i].d * GGML_FP16_TO_FP32(x[i].d); + const float dmin = y[i].d * GGML_FP16_TO_FP32(x[i].dmin); + + const int16x8_t q8sums = vpaddq_s16(vld1q_s16(y[i].bsums), vld1q_s16(y[i].bsums + 8)); + + memcpy(utmp, x[i].scales, 12); + utmp[3] = ((utmp[2] >> 4) & kmask2) | (((utmp[1] >> 6) & kmask3) << 4); + const uint32_t uaux = utmp[1] & kmask1; + utmp[1] = (utmp[2] & kmask2) | (((utmp[0] >> 6) & kmask3) << 4); + utmp[2] = uaux; + utmp[0] &= kmask1; + + const uint8x8_t mins8 = vld1_u8((const uint8_t*)utmp + 8); + const int16x8_t mins = vreinterpretq_s16_u16(vmovl_u8(mins8)); + const int32x4_t prod = vaddq_s32(vmull_s16(vget_low_s16 (q8sums), vget_low_s16 (mins)), + vmull_s16(vget_high_s16(q8sums), vget_high_s16(mins))); + int32_t sumi_mins = vaddvq_s32(prod); + + const uint8_t * scales = (const uint8_t *)utmp; + + const uint8_t * restrict q5 = x[i].qs; + const uint8_t * restrict qh = x[i].qh; + const int8_t * restrict q8 = y[i].qs; + + uint8x16x2_t qhbits = vld1q_u8_x2(qh); + + uint8x16x4_t q5h; + + int32_t sumi = 0; + + for (int j = 0; j < QK_K/64; ++j) { + + const uint8x16x2_t q5bits = vld1q_u8_x2(q5); q5 += 32; + const int8x16x4_t q8bytes = vld1q_s8_x4(q8); q8 += 64; + + q5h.val[0] = vshlq_n_u8(vandq_u8(mone, qhbits.val[0]), 4); + q5h.val[1] = vshlq_n_u8(vandq_u8(mone, qhbits.val[1]), 4); + q5h.val[2] = vshlq_n_u8(vandq_u8(mtwo, qhbits.val[0]), 3); + q5h.val[3] = vshlq_n_u8(vandq_u8(mtwo, qhbits.val[1]), 3); + qhbits.val[0] = vshrq_n_u8(qhbits.val[0], 2); + qhbits.val[1] = vshrq_n_u8(qhbits.val[1], 2); + + q5bytes.val[0] = vreinterpretq_s8_u8(vorrq_u8(vandq_u8(q5bits.val[0], m4b), q5h.val[0])); + q5bytes.val[1] = vreinterpretq_s8_u8(vorrq_u8(vandq_u8(q5bits.val[1], m4b), q5h.val[1])); + q5bytes.val[2] = vreinterpretq_s8_u8(vorrq_u8(vshrq_n_u8(q5bits.val[0], 4), q5h.val[2])); + q5bytes.val[3] = vreinterpretq_s8_u8(vorrq_u8(vshrq_n_u8(q5bits.val[1], 4), q5h.val[3])); + +#if defined(__ARM_FEATURE_DOTPROD) + + sumi += vaddvq_s32(vdotq_s32(vdotq_s32(mzero, q5bytes.val[0], q8bytes.val[0]), q5bytes.val[1], q8bytes.val[1])) * *scales++; + sumi += vaddvq_s32(vdotq_s32(vdotq_s32(mzero, q5bytes.val[2], q8bytes.val[2]), q5bytes.val[3], q8bytes.val[3])) * *scales++; +#else + + const int16x8_t p0 = vaddq_s16(vmull_s8(vget_low_s8 (q5bytes.val[0]), vget_low_s8 (q8bytes.val[0])), + vmull_s8(vget_high_s8(q5bytes.val[0]), vget_high_s8(q8bytes.val[0]))); + const int16x8_t p1 = vaddq_s16(vmull_s8(vget_low_s8 (q5bytes.val[1]), vget_low_s8 (q8bytes.val[1])), + vmull_s8(vget_high_s8(q5bytes.val[1]), vget_high_s8(q8bytes.val[1]))); + sumi += vaddvq_s16(vaddq_s16(p0, p1)) * *scales++; + + const int16x8_t p2 = vaddq_s16(vmull_s8(vget_low_s8 (q5bytes.val[2]), vget_low_s8 (q8bytes.val[2])), + vmull_s8(vget_high_s8(q5bytes.val[2]), vget_high_s8(q8bytes.val[2]))); + const int16x8_t p3 = vaddq_s16(vmull_s8(vget_low_s8 (q5bytes.val[3]), vget_low_s8 (q8bytes.val[3])), + vmull_s8(vget_high_s8(q5bytes.val[3]), vget_high_s8(q8bytes.val[3]))); + sumi += vaddvq_s16(vaddq_s16(p2, p3)) * *scales++; +#endif + } + + sumf += d * sumi - dmin * sumi_mins; + + } + + *s = sumf; + +#elif defined __AVX2__ + + const __m256i m4 = _mm256_set1_epi8(0xF); + const __m128i mzero = _mm_setzero_si128(); + const __m256i mone = _mm256_set1_epi8(1); + + __m256 acc = _mm256_setzero_ps(); + + float summs = 0.f; + + for (int i = 0; i < nb; ++i) { + + const uint8_t * restrict q5 = x[i].qs; + const int8_t * restrict q8 = y[i].qs; + +#if QK_K == 256 + const float d = y[i].d * GGML_FP16_TO_FP32(x[i].d); + const float dmin = -y[i].d * GGML_FP16_TO_FP32(x[i].dmin); + + memcpy(utmp, x[i].scales, 12); + utmp[3] = ((utmp[2] >> 4) & kmask2) | (((utmp[1] >> 6) & kmask3) << 4); + const uint32_t uaux = utmp[1] & kmask1; + utmp[1] = (utmp[2] & kmask2) | (((utmp[0] >> 6) & kmask3) << 4); + utmp[2] = uaux; + utmp[0] &= kmask1; +#else + // TODO + const float d = 0, dmin = 0; +#endif + + const __m256i mins_and_scales = _mm256_cvtepu8_epi16(_mm_set_epi32(utmp[3], utmp[2], utmp[1], utmp[0])); + + const __m256i q8sums = _mm256_loadu_si256((const __m256i*)y[i].bsums); + const __m128i q8s = _mm_hadd_epi16(_mm256_extracti128_si256(q8sums, 0), _mm256_extracti128_si256(q8sums, 1)); + const __m128i prod = _mm_madd_epi16(_mm256_extracti128_si256(mins_and_scales, 1), q8s); + const __m128i hsum = _mm_hadd_epi32(_mm_hadd_epi32(prod, mzero), mzero); + summs += dmin * _mm_extract_epi32(hsum, 0); + + const __m128i sc128 = _mm256_extracti128_si256(mins_and_scales, 0); + const __m256i scales = MM256_SET_M128I(sc128, sc128); + + const __m256i hbits = _mm256_loadu_si256((const __m256i*)x[i].qh); + __m256i hmask = mone; + + __m256i sumi = _mm256_setzero_si256(); + + int bit = 0; + + for (int j = 0; j < QK_K/64; ++j) { + + const __m256i scale_0 = _mm256_shuffle_epi8(scales, get_scale_shuffle_k4(2*j+0)); + const __m256i scale_1 = _mm256_shuffle_epi8(scales, get_scale_shuffle_k4(2*j+1)); + + const __m256i q5bits = _mm256_loadu_si256((const __m256i*)q5); q5 += 32; + + const __m256i q5l_0 = _mm256_and_si256(q5bits, m4); + const __m256i q5h_0 = _mm256_slli_epi16(_mm256_srli_epi16(_mm256_and_si256(hbits, hmask), bit++), 4); + const __m256i q5_0 = _mm256_add_epi8(q5l_0, q5h_0); + hmask = _mm256_slli_epi16(hmask, 1); + + const __m256i q5l_1 = _mm256_and_si256(_mm256_srli_epi16(q5bits, 4), m4); + const __m256i q5h_1 = _mm256_slli_epi16(_mm256_srli_epi16(_mm256_and_si256(hbits, hmask), bit++), 4); + const __m256i q5_1 = _mm256_add_epi8(q5l_1, q5h_1); + hmask = _mm256_slli_epi16(hmask, 1); + + const __m256i q8_0 = _mm256_loadu_si256((const __m256i*)q8); q8 += 32; + const __m256i q8_1 = _mm256_loadu_si256((const __m256i*)q8); q8 += 32; + + __m256i p16_0 = _mm256_maddubs_epi16(q5_0, q8_0); + __m256i p16_1 = _mm256_maddubs_epi16(q5_1, q8_1); + + p16_0 = _mm256_madd_epi16(scale_0, p16_0); + p16_1 = _mm256_madd_epi16(scale_1, p16_1); + + sumi = _mm256_add_epi32(sumi, _mm256_add_epi32(p16_0, p16_1)); + + } + + __m256 vd = _mm256_set1_ps(d); + acc = _mm256_fmadd_ps(vd, _mm256_cvtepi32_ps(sumi), acc); + + } + + *s = hsum_float_8(acc) + summs; + +#elif defined __AVX__ + + const __m128i m4 = _mm_set1_epi8(0xF); + const __m128i mzero = _mm_setzero_si128(); + const __m128i mone = _mm_set1_epi8(1); + const __m128i m2 = _mm_set1_epi8(2); + + __m256 acc = _mm256_setzero_ps(); + + float summs = 0.f; + + for (int i = 0; i < nb; ++i) { + + const float d = y[i].d * GGML_FP16_TO_FP32(x[i].d); + const float dmin = -y[i].d * GGML_FP16_TO_FP32(x[i].dmin); + + const uint8_t * restrict q5 = x[i].qs; + const int8_t * restrict q8 = y[i].qs; + + memcpy(utmp, x[i].scales, 12); + utmp[3] = ((utmp[2] >> 4) & kmask2) | (((utmp[1] >> 6) & kmask3) << 4); + const uint32_t uaux = utmp[1] & kmask1; + utmp[1] = (utmp[2] & kmask2) | (((utmp[0] >> 6) & kmask3) << 4); + utmp[2] = uaux; + utmp[0] &= kmask1; + + const __m128i utmps = _mm_set_epi32(utmp[3], utmp[2], utmp[1], utmp[0]); + const __m128i scales = _mm_cvtepu8_epi16(utmps); + const __m128i mins = _mm_cvtepu8_epi16(_mm_unpackhi_epi64(utmps, utmps)); + + const __m128i q8sums_0 = _mm_loadu_si128((const __m128i*)&y[i].bsums[0]); + const __m128i q8sums_1 = _mm_loadu_si128((const __m128i*)&y[i].bsums[8]); + const __m128i q8s = _mm_hadd_epi16(q8sums_0, q8sums_1); + const __m128i prod = _mm_madd_epi16(mins, q8s); + const __m128i hsum = _mm_hadd_epi32(_mm_hadd_epi32(prod, mzero), mzero); + summs += dmin * _mm_extract_epi32(hsum, 0); + + const __m128i hbits_0 = _mm_loadu_si128((const __m128i*)&x[i].qh[0]); + const __m128i hbits_1 = _mm_loadu_si128((const __m128i*)&x[i].qh[16]); + __m128i hmask = mone; + + __m128i sumi_0 = _mm_setzero_si128(); + __m128i sumi_1 = _mm_setzero_si128(); + + int bit = 0; + + __m128i shuffle = _mm_set1_epi16(0x0100); + for (int j = 0; j < QK_K/64; ++j) { + + const __m128i scale_0 = _mm_shuffle_epi8(scales, shuffle); + shuffle = _mm_add_epi16(shuffle, m2); + const __m128i scale_1 = _mm_shuffle_epi8(scales, shuffle); + shuffle = _mm_add_epi16(shuffle, m2); + + const __m128i q5bits_0 = _mm_loadu_si128((const __m128i*)q5); q5 += 16; + const __m128i q5bits_1 = _mm_loadu_si128((const __m128i*)q5); q5 += 16; + + __m128i q5l_0 = _mm_and_si128(q5bits_0, m4); + __m128i q5l_1 = _mm_and_si128(q5bits_1, m4); + __m128i q5h_0 = _mm_slli_epi16(_mm_srli_epi16(_mm_and_si128(hbits_0, hmask), bit), 4); + __m128i q5h_1 = _mm_slli_epi16(_mm_srli_epi16(_mm_and_si128(hbits_1, hmask), bit++), 4); + __m128i q5_0 = _mm_add_epi8(q5l_0, q5h_0); + __m128i q5_1 = _mm_add_epi8(q5l_1, q5h_1); + hmask = _mm_slli_epi16(hmask, 1); + + __m128i q8_0 = _mm_loadu_si128((const __m128i*)q8); q8 += 16; + __m128i q8_1 = _mm_loadu_si128((const __m128i*)q8); q8 += 16; + __m128i p16_0 = _mm_maddubs_epi16(q5_0, q8_0); + __m128i p16_1 = _mm_maddubs_epi16(q5_1, q8_1); + p16_0 = _mm_madd_epi16(scale_0, p16_0); + p16_1 = _mm_madd_epi16(scale_0, p16_1); + + q5l_0 = _mm_and_si128(_mm_srli_epi16(q5bits_0, 4), m4); + q5l_1 = _mm_and_si128(_mm_srli_epi16(q5bits_1, 4), m4); + q5h_0 = _mm_slli_epi16(_mm_srli_epi16(_mm_and_si128(hbits_0, hmask), bit), 4); + q5h_1 = _mm_slli_epi16(_mm_srli_epi16(_mm_and_si128(hbits_1, hmask), bit++), 4); + q5_0 = _mm_add_epi8(q5l_0, q5h_0); + q5_1 = _mm_add_epi8(q5l_1, q5h_1); + hmask = _mm_slli_epi16(hmask, 1); + + q8_0 = _mm_loadu_si128((const __m128i*)q8); q8 += 16; + q8_1 = _mm_loadu_si128((const __m128i*)q8); q8 += 16; + __m128i p16_2 = _mm_maddubs_epi16(q5_0, q8_0); + __m128i p16_3 = _mm_maddubs_epi16(q5_1, q8_1); + p16_2 = _mm_madd_epi16(scale_1, p16_2); + p16_3 = _mm_madd_epi16(scale_1, p16_3); + + sumi_0 = _mm_add_epi32(sumi_0, _mm_add_epi32(p16_0, p16_2)); + sumi_1 = _mm_add_epi32(sumi_1, _mm_add_epi32(p16_1, p16_3)); + + } + + __m256 vd = _mm256_set1_ps(d); + __m256i sumi = MM256_SET_M128I(sumi_1, sumi_0); + acc = _mm256_add_ps(_mm256_mul_ps(vd, _mm256_cvtepi32_ps(sumi)), acc); + + } + + *s = hsum_float_8(acc) + summs; + +#elif defined __riscv_v_intrinsic + + const uint8_t * scales = (const uint8_t*)&utmp[0]; + const uint8_t * mins = (const uint8_t*)&utmp[2]; + + float sumf = 0; + float sums = 0.0; + + size_t vl; + + for (int i = 0; i < nb; ++i) { + + vl = 8; + + const uint8_t * restrict q5 = x[i].qs; + const uint8_t * restrict hm = x[i].qh; + const int8_t * restrict q8 = y[i].qs; + + const float d = GGML_FP16_TO_FP32(x[i].d) * y[i].d; + const float dmin = GGML_FP16_TO_FP32(x[i].dmin) * y[i].d; + + vint16mf2_t q8sums_0 = __riscv_vlse16_v_i16mf2(y[i].bsums, 4, vl); + vint16mf2_t q8sums_1 = __riscv_vlse16_v_i16mf2(y[i].bsums+1, 4, vl); + vint16mf2_t q8sums = __riscv_vadd_vv_i16mf2(q8sums_0, q8sums_1, vl); + + memcpy(utmp, x[i].scales, 12); + utmp[3] = ((utmp[2] >> 4) & kmask2) | (((utmp[1] >> 6) & kmask3) << 4); + const uint32_t uaux = utmp[1] & kmask1; + utmp[1] = (utmp[2] & kmask2) | (((utmp[0] >> 6) & kmask3) << 4); + utmp[2] = uaux; + utmp[0] &= kmask1; + + vuint8mf4_t mins8 = __riscv_vle8_v_u8mf4(mins, vl); + vint16mf2_t v_mins = __riscv_vreinterpret_v_u16mf2_i16mf2(__riscv_vzext_vf2_u16mf2(mins8, vl)); + vint32m1_t prod = __riscv_vwmul_vv_i32m1(q8sums, v_mins, vl); + + vint32m1_t sumi = __riscv_vredsum_vs_i32m1_i32m1(prod, __riscv_vmv_v_x_i32m1(0, 1), vl); + sumf -= dmin * __riscv_vmv_x_s_i32m1_i32(sumi); + + vl = 32; + int32_t aux32 = 0; + int is = 0; + + uint8_t m = 1; + vint32m1_t vzero = __riscv_vmv_v_x_i32m1(0, 1); + vuint8m1_t vqh = __riscv_vle8_v_u8m1(hm, vl); + + for (int j = 0; j < QK_K/64; ++j) { + // load Q5 and Q8 + vuint8m1_t q5_x = __riscv_vle8_v_u8m1(q5, vl); + vint8m1_t q8_y1 = __riscv_vle8_v_i8m1(q8, vl); + vint8m1_t q8_y2 = __riscv_vle8_v_i8m1(q8+32, vl); + + // compute mask for addition + vint8m1_t q5_a = __riscv_vreinterpret_v_u8m1_i8m1(__riscv_vand_vx_u8m1(q5_x, 0x0F, vl)); + vuint8m1_t qh_m1 = __riscv_vand_vx_u8m1(vqh, m, vl); + vbool8_t vmask_1 = __riscv_vmsne_vx_u8m1_b8(qh_m1, 0, vl); + vint8m1_t q5_m1 = __riscv_vadd_vx_i8m1_m(vmask_1, q5_a, 16, vl); + m <<= 1; + + vint8m1_t q5_l = __riscv_vreinterpret_v_u8m1_i8m1(__riscv_vsrl_vx_u8m1(q5_x, 0x04, vl)); + vuint8m1_t qh_m2 = __riscv_vand_vx_u8m1(vqh, m, vl); + vbool8_t vmask_2 = __riscv_vmsne_vx_u8m1_b8(qh_m2, 0, vl); + vint8m1_t q5_m2 = __riscv_vadd_vx_i8m1_m(vmask_2, q5_l, 16, vl); + m <<= 1; + + vint16m2_t v0 = __riscv_vwmul_vv_i16m2(q5_m1, q8_y1, vl); + vint16m2_t v1 = __riscv_vwmul_vv_i16m2(q5_m2, q8_y2, vl); + + vint32m4_t vs1 = __riscv_vwmul_vx_i32m4(v0, scales[is++], vl); + vint32m4_t vs2 = __riscv_vwmul_vx_i32m4(v1, scales[is++], vl); + + vint32m1_t vacc1 = __riscv_vredsum_vs_i32m4_i32m1(vs1, vzero, vl); + vint32m1_t vacc2 = __riscv_vredsum_vs_i32m4_i32m1(vs2, vzero, vl); + + aux32 += __riscv_vmv_x_s_i32m1_i32(vacc1) + __riscv_vmv_x_s_i32m1_i32(vacc2); + q5 += 32; q8 += 64; + + } + + vfloat32m1_t vaux = __riscv_vfmul_vf_f32m1(__riscv_vfmv_v_f_f32m1(aux32, 1), d, 1); + sums += __riscv_vfmv_f_s_f32m1_f32(vaux); + + } + + *s = sumf+sums; + +#else + + const uint8_t * scales = (const uint8_t*)&utmp[0]; + const uint8_t * mins = (const uint8_t*)&utmp[2]; + + int8_t aux8[QK_K]; + int16_t aux16[8]; + float sums [8]; + int32_t aux32[8]; + memset(sums, 0, 8*sizeof(float)); + + float sumf = 0; + for (int i = 0; i < nb; ++i) { + const uint8_t * restrict q4 = x[i].qs; + const uint8_t * restrict hm = x[i].qh; + const int8_t * restrict q8 = y[i].qs; + memset(aux32, 0, 8*sizeof(int32_t)); + int8_t * restrict a = aux8; + uint8_t m = 1; + for (int j = 0; j < QK_K/64; ++j) { + for (int l = 0; l < 32; ++l) a[l] = (int8_t)(q4[l] & 0xF); + for (int l = 0; l < 32; ++l) a[l] += (hm[l] & m ? 16 : 0); + a += 32; m <<= 1; + for (int l = 0; l < 32; ++l) a[l] = (int8_t)(q4[l] >> 4); + for (int l = 0; l < 32; ++l) a[l] += (hm[l] & m ? 16 : 0); + a += 32; m <<= 1; + q4 += 32; + } + memcpy(utmp, x[i].scales, 12); + utmp[3] = ((utmp[2] >> 4) & kmask2) | (((utmp[1] >> 6) & kmask3) << 4); + const uint32_t uaux = utmp[1] & kmask1; + utmp[1] = (utmp[2] & kmask2) | (((utmp[0] >> 6) & kmask3) << 4); + utmp[2] = uaux; + utmp[0] &= kmask1; + + int sumi = 0; + for (int j = 0; j < QK_K/16; ++j) sumi += y[i].bsums[j] * mins[j/2]; + a = aux8; + int is = 0; + for (int j = 0; j < QK_K/32; ++j) { + int32_t scale = scales[is++]; + for (int l = 0; l < 8; ++l) aux16[l] = q8[l] * a[l]; + for (int l = 0; l < 8; ++l) aux32[l] += scale * aux16[l]; + q8 += 8; a += 8; + for (int l = 0; l < 8; ++l) aux16[l] = q8[l] * a[l]; + for (int l = 0; l < 8; ++l) aux32[l] += scale * aux16[l]; + q8 += 8; a += 8; + for (int l = 0; l < 8; ++l) aux16[l] = q8[l] * a[l]; + for (int l = 0; l < 8; ++l) aux32[l] += scale * aux16[l]; + q8 += 8; a += 8; + for (int l = 0; l < 8; ++l) aux16[l] = q8[l] * a[l]; + for (int l = 0; l < 8; ++l) aux32[l] += scale * aux16[l]; + q8 += 8; a += 8; + } + const float d = GGML_FP16_TO_FP32(x[i].d) * y[i].d; + for (int l = 0; l < 8; ++l) sums[l] += d * aux32[l]; + const float dmin = GGML_FP16_TO_FP32(x[i].dmin) * y[i].d; + sumf -= dmin * sumi; + } + for (int l = 0; l < 8; ++l) sumf += sums[l]; + *s = sumf; +#endif +} + +#else + +void ggml_vec_dot_q5_K_q8_K(const int n, float * restrict s, const void * restrict vx, const void * restrict vy) { + assert(n % QK_K == 0); + + const block_q5_K * restrict x = vx; + const block_q8_K * restrict y = vy; + + const int nb = n / QK_K; + +#ifdef __ARM_NEON + + const uint8x16_t m4b = vdupq_n_u8(0xf); + const uint8x16_t mh = vdupq_n_u8(16); +#if defined(__ARM_FEATURE_DOTPROD) + const int32x4_t mzero = vdupq_n_s32(0); +#endif + + int8x16x4_t q5bytes; + uint8x16x4_t q5h; + + float sumf = 0; + + for (int i = 0; i < nb; ++i) { + + const float d = y[i].d * (float)x[i].d; + const int8_t * sc = x[i].scales; + + const uint8_t * restrict q5 = x[i].qs; + const uint8_t * restrict qh = x[i].qh; + const int8_t * restrict q8 = y[i].qs; + + const uint8x8_t qhbits = vld1_u8(qh); + + const uint8x16x2_t q5bits = vld1q_u8_x2(q5); + const int8x16x4_t q8bytes = vld1q_s8_x4(q8); + + const uint8x16_t htmp = vcombine_u8(qhbits, vshr_n_u8(qhbits, 1)); + q5h.val[0] = vbicq_u8(mh, vshlq_n_u8(htmp, 4)); + q5h.val[1] = vbicq_u8(mh, vshlq_n_u8(htmp, 2)); + q5h.val[2] = vbicq_u8(mh, htmp); + q5h.val[3] = vbicq_u8(mh, vshrq_n_u8(htmp, 2)); + + q5bytes.val[0] = vsubq_s8(vreinterpretq_s8_u8(vandq_u8(q5bits.val[0], m4b)), vreinterpretq_s8_u8(q5h.val[0])); + q5bytes.val[1] = vsubq_s8(vreinterpretq_s8_u8(vandq_u8(q5bits.val[1], m4b)), vreinterpretq_s8_u8(q5h.val[1])); + q5bytes.val[2] = vsubq_s8(vreinterpretq_s8_u8(vshrq_n_u8(q5bits.val[0], 4)), vreinterpretq_s8_u8(q5h.val[2])); + q5bytes.val[3] = vsubq_s8(vreinterpretq_s8_u8(vshrq_n_u8(q5bits.val[1], 4)), vreinterpretq_s8_u8(q5h.val[3])); + +#if defined(__ARM_FEATURE_DOTPROD) + + int32_t sumi1 = sc[0] * vaddvq_s32(vdotq_s32(mzero, q5bytes.val[0], q8bytes.val[0])); + int32_t sumi2 = sc[1] * vaddvq_s32(vdotq_s32(mzero, q5bytes.val[1], q8bytes.val[1])); + int32_t sumi3 = sc[2] * vaddvq_s32(vdotq_s32(mzero, q5bytes.val[2], q8bytes.val[2])); + int32_t sumi4 = sc[3] * vaddvq_s32(vdotq_s32(mzero, q5bytes.val[3], q8bytes.val[3])); + + sumf += d * (sumi1 + sumi2 + sumi3 + sumi4); + +#else + + const int16x8_t p0 = vaddq_s16(vmull_s8(vget_low_s8 (q5bytes.val[0]), vget_low_s8 (q8bytes.val[0])), + vmull_s8(vget_high_s8(q5bytes.val[0]), vget_high_s8(q8bytes.val[0]))); + const int16x8_t p1 = vaddq_s16(vmull_s8(vget_low_s8 (q5bytes.val[1]), vget_low_s8 (q8bytes.val[1])), + vmull_s8(vget_high_s8(q5bytes.val[1]), vget_high_s8(q8bytes.val[1]))); + int32_t sumi = sc[0] * vaddvq_s16(p0) + sc[1] * vaddvq_s16(p1); + + const int16x8_t p2 = vaddq_s16(vmull_s8(vget_low_s8 (q5bytes.val[2]), vget_low_s8 (q8bytes.val[2])), + vmull_s8(vget_high_s8(q5bytes.val[2]), vget_high_s8(q8bytes.val[2]))); + const int16x8_t p3 = vaddq_s16(vmull_s8(vget_low_s8 (q5bytes.val[3]), vget_low_s8 (q8bytes.val[3])), + vmull_s8(vget_high_s8(q5bytes.val[3]), vget_high_s8(q8bytes.val[3]))); + sumi += sc[2] * vaddvq_s16(p2) + sc[3] * vaddvq_s16(p3); + + sumf += d*sumi; +#endif + + } + + *s = sumf; + +#elif defined __AVX2__ + + const __m256i m4 = _mm256_set1_epi8(0xF); + const __m256i mone = _mm256_set1_epi8(1); + + __m256 acc = _mm256_setzero_ps(); + + for (int i = 0; i < nb; ++i) { + + const uint8_t * restrict q5 = x[i].qs; + const int8_t * restrict q8 = y[i].qs; + + const float d = y[i].d * GGML_FP16_TO_FP32(x[i].d); + + const __m256i q5bits = _mm256_loadu_si256((const __m256i*)q5); + + const __m256i scale_l = MM256_SET_M128I(_mm_set1_epi16(x[i].scales[1]), _mm_set1_epi16(x[i].scales[0])); + const __m256i scale_h = MM256_SET_M128I(_mm_set1_epi16(x[i].scales[3]), _mm_set1_epi16(x[i].scales[2])); + + int64_t aux64; + memcpy(&aux64, x[i].qh, 8); + const __m128i haux128 = _mm_set_epi64x(aux64 >> 1, aux64); + const __m256i haux256 = MM256_SET_M128I(_mm_srli_epi16(haux128, 2), haux128); + + const __m256i q5h_0 = _mm256_slli_epi16(_mm256_andnot_si256(haux256, mone), 4); + const __m256i q5h_1 = _mm256_slli_epi16(_mm256_andnot_si256(_mm256_srli_epi16(haux256, 4), mone), 4); + + const __m256i q5l_0 = _mm256_and_si256(q5bits, m4); + const __m256i q5l_1 = _mm256_and_si256(_mm256_srli_epi16(q5bits, 4), m4); + + const __m256i q8_0 = _mm256_loadu_si256((const __m256i*)(q8+ 0)); + const __m256i q8_1 = _mm256_loadu_si256((const __m256i*)(q8+32)); + + const __m256i p16_0 = _mm256_madd_epi16(scale_l, _mm256_maddubs_epi16(q5l_0, q8_0)); + const __m256i p16_1 = _mm256_madd_epi16(scale_h, _mm256_maddubs_epi16(q5l_1, q8_1)); + const __m256i s16_0 = _mm256_madd_epi16(scale_l, _mm256_maddubs_epi16(q5h_0, q8_0)); + const __m256i s16_1 = _mm256_madd_epi16(scale_h, _mm256_maddubs_epi16(q5h_1, q8_1)); + + const __m256i dot = _mm256_sub_epi32(_mm256_add_epi32(p16_0, p16_1), _mm256_add_epi32(s16_0, s16_1)); + + acc = _mm256_fmadd_ps(_mm256_set1_ps(d), _mm256_cvtepi32_ps(dot), acc); + + } + + *s = hsum_float_8(acc); + +#elif defined __AVX__ + + const __m128i m4 = _mm_set1_epi8(0xF); + const __m128i mone = _mm_set1_epi8(1); + + __m256 acc = _mm256_setzero_ps(); + + for (int i = 0; i < nb; ++i) { + + const uint8_t * restrict q5 = x[i].qs; + const int8_t * restrict q8 = y[i].qs; + + const float d = y[i].d * GGML_FP16_TO_FP32(x[i].d); + + const __m256i q5bits = _mm256_loadu_si256((const __m256i*)q5); + + const __m128i scale_0 = _mm_set1_epi16(x[i].scales[0]); + const __m128i scale_1 = _mm_set1_epi16(x[i].scales[1]); + const __m128i scale_2 = _mm_set1_epi16(x[i].scales[2]); + const __m128i scale_3 = _mm_set1_epi16(x[i].scales[3]); + + int64_t aux64; + memcpy(&aux64, x[i].qh, 8); + const __m128i haux128_0 = _mm_set_epi64x(aux64 >> 1, aux64); + const __m128i haux128_1 = _mm_srli_epi16(haux128_0, 2); + + const __m128i q5h_0 = _mm_slli_epi16(_mm_andnot_si128(haux128_0, mone), 4); + const __m128i q5h_1 = _mm_slli_epi16(_mm_andnot_si128(haux128_1, mone), 4); + const __m128i q5h_2 = _mm_slli_epi16(_mm_andnot_si128(_mm_srli_epi16(haux128_0, 4), mone), 4); + const __m128i q5h_3 = _mm_slli_epi16(_mm_andnot_si128(_mm_srli_epi16(haux128_1, 4), mone), 4); + + const __m128i q5l_0 = _mm_and_si128(_mm256_extractf128_si256(q5bits, 0), m4); + const __m128i q5l_1 = _mm_and_si128(_mm256_extractf128_si256(q5bits, 1), m4); + const __m128i q5l_2 = _mm_and_si128(_mm_srli_epi16(_mm256_extractf128_si256(q5bits, 0), 4), m4); + const __m128i q5l_3 = _mm_and_si128(_mm_srli_epi16(_mm256_extractf128_si256(q5bits, 1), 4), m4); + + const __m256i q8_0 = _mm256_loadu_si256((const __m256i*)(q8+ 0)); + const __m256i q8_1 = _mm256_loadu_si256((const __m256i*)(q8+32)); + + const __m128i p16_0 = _mm_madd_epi16(scale_0, _mm_maddubs_epi16(q5l_0, _mm256_extractf128_si256(q8_0, 0))); + const __m128i p16_1 = _mm_madd_epi16(scale_1, _mm_maddubs_epi16(q5l_1, _mm256_extractf128_si256(q8_0, 1))); + const __m128i p16_2 = _mm_madd_epi16(scale_2, _mm_maddubs_epi16(q5l_2, _mm256_extractf128_si256(q8_1, 0))); + const __m128i p16_3 = _mm_madd_epi16(scale_3, _mm_maddubs_epi16(q5l_3, _mm256_extractf128_si256(q8_1, 1))); + const __m128i s16_0 = _mm_madd_epi16(scale_0, _mm_maddubs_epi16(q5h_0, _mm256_extractf128_si256(q8_0, 0))); + const __m128i s16_1 = _mm_madd_epi16(scale_1, _mm_maddubs_epi16(q5h_1, _mm256_extractf128_si256(q8_0, 1))); + const __m128i s16_2 = _mm_madd_epi16(scale_2, _mm_maddubs_epi16(q5h_2, _mm256_extractf128_si256(q8_1, 0))); + const __m128i s16_3 = _mm_madd_epi16(scale_3, _mm_maddubs_epi16(q5h_3, _mm256_extractf128_si256(q8_1, 1))); + + const __m128i dot_0 = _mm_sub_epi32(_mm_add_epi32(p16_0, p16_2), _mm_add_epi32(s16_0, s16_2)); + const __m128i dot_1 = _mm_sub_epi32(_mm_add_epi32(p16_1, p16_3), _mm_add_epi32(s16_1, s16_3)); + + acc = _mm256_add_ps(_mm256_mul_ps(_mm256_set1_ps(d), _mm256_cvtepi32_ps(MM256_SET_M128I(dot_1, dot_0))), acc); + + } + + *s = hsum_float_8(acc); + +#elif defined __riscv_v_intrinsic + + float sumf = 0; + + for (int i = 0; i < nb; ++i) { + + const float d = y[i].d * (float)x[i].d; + const int8_t * sc = x[i].scales; + + const uint8_t * restrict q5 = x[i].qs; + const uint8_t * restrict qh = x[i].qh; + const int8_t * restrict q8 = y[i].qs; + + vint32m1_t vzero = __riscv_vmv_v_x_i32m1(0, 1); + + // load qh + vuint8mf4_t qh_x1 = __riscv_vle8_v_u8mf4(qh, 8); + vuint8mf2_t qh_x2 = __riscv_vlmul_ext_v_u8mf4_u8mf2(__riscv_vsrl_vx_u8mf4(qh_x1, 1, 8)); + + size_t vl = 16; + + // combine both qh_1 and qh_2 + vuint8mf2_t qh_x = __riscv_vslideup_vx_u8mf2(__riscv_vlmul_ext_v_u8mf4_u8mf2(qh_x1), qh_x2, vl/2, vl); + + vuint8mf2_t qh_h0 = __riscv_vand_vx_u8mf2(__riscv_vnot_v_u8mf2(__riscv_vsll_vx_u8mf2(qh_x, 0x4, vl), vl), 16, vl); + vuint8mf2_t qh_h1 = __riscv_vand_vx_u8mf2(__riscv_vnot_v_u8mf2(__riscv_vsll_vx_u8mf2(qh_x, 0x2, vl), vl), 16, vl); + vuint8mf2_t qh_h2 = __riscv_vand_vx_u8mf2(__riscv_vnot_v_u8mf2(qh_x, vl), 16, vl); + vuint8mf2_t qh_h3 = __riscv_vand_vx_u8mf2(__riscv_vnot_v_u8mf2(__riscv_vsrl_vx_u8mf2(qh_x, 0x4, vl), vl), 16, vl); + + vint8mf2_t qh_0 = __riscv_vreinterpret_v_u8mf2_i8mf2(qh_h0); + vint8mf2_t qh_1 = __riscv_vreinterpret_v_u8mf2_i8mf2(qh_h1); + vint8mf2_t qh_2 = __riscv_vreinterpret_v_u8mf2_i8mf2(qh_h2); + vint8mf2_t qh_3 = __riscv_vreinterpret_v_u8mf2_i8mf2(qh_h3); + + // load q5 + vuint8mf2_t q5_x1 = __riscv_vle8_v_u8mf2(q5, vl); + vuint8mf2_t q5_x2 = __riscv_vle8_v_u8mf2(q5+16, vl); + + vint8mf2_t q5s_0 = __riscv_vreinterpret_v_u8mf2_i8mf2(__riscv_vand_vx_u8mf2(q5_x1, 0xF, vl)); + vint8mf2_t q5s_1 = __riscv_vreinterpret_v_u8mf2_i8mf2(__riscv_vand_vx_u8mf2(q5_x2, 0xF, vl)); + vint8mf2_t q5s_2 = __riscv_vreinterpret_v_u8mf2_i8mf2(__riscv_vsrl_vx_u8mf2(q5_x1, 0x4, vl)); + vint8mf2_t q5s_3 = __riscv_vreinterpret_v_u8mf2_i8mf2(__riscv_vsrl_vx_u8mf2(q5_x2, 0x4, vl)); + + vint8mf2_t q5_0 = __riscv_vsub_vv_i8mf2(q5s_0, qh_0, vl); + vint8mf2_t q5_1 = __riscv_vsub_vv_i8mf2(q5s_1, qh_1, vl); + vint8mf2_t q5_2 = __riscv_vsub_vv_i8mf2(q5s_2, qh_2, vl); + vint8mf2_t q5_3 = __riscv_vsub_vv_i8mf2(q5s_3, qh_3, vl); + + // load Q8 and multiply it with Q5 + vint16m1_t p0 = __riscv_vwmul_vv_i16m1(q5_0, __riscv_vle8_v_i8mf2(q8, vl), vl); + vint16m1_t p1 = __riscv_vwmul_vv_i16m1(q5_1, __riscv_vle8_v_i8mf2(q8+16, vl), vl); + vint16m1_t p2 = __riscv_vwmul_vv_i16m1(q5_2, __riscv_vle8_v_i8mf2(q8+32, vl), vl); + vint16m1_t p3 = __riscv_vwmul_vv_i16m1(q5_3, __riscv_vle8_v_i8mf2(q8+48, vl), vl); + + vint32m1_t vs_0 = __riscv_vwredsum_vs_i16m1_i32m1(p0, vzero, vl); + vint32m1_t vs_1 = __riscv_vwredsum_vs_i16m1_i32m1(p1, vzero, vl); + vint32m1_t vs_2 = __riscv_vwredsum_vs_i16m1_i32m1(p2, vzero, vl); + vint32m1_t vs_3 = __riscv_vwredsum_vs_i16m1_i32m1(p3, vzero, vl); + + int32_t sumi1 = sc[0] * __riscv_vmv_x_s_i32m1_i32(vs_0); + int32_t sumi2 = sc[1] * __riscv_vmv_x_s_i32m1_i32(vs_1); + int32_t sumi3 = sc[2] * __riscv_vmv_x_s_i32m1_i32(vs_2); + int32_t sumi4 = sc[3] * __riscv_vmv_x_s_i32m1_i32(vs_3); + + sumf += d * (sumi1 + sumi2 + sumi3 + sumi4); + + } + + *s = sumf; + +#else + + int8_t aux8[QK_K]; + int16_t aux16[16]; + float sums [8]; + memset(sums, 0, 8*sizeof(float)); + + float sumf = 0; + for (int i = 0; i < nb; ++i) { + const uint8_t * restrict q4 = x[i].qs; + const uint8_t * restrict hm = x[i].qh; + const int8_t * restrict q8 = y[i].qs; + int8_t * restrict a = aux8; + for (int l = 0; l < 32; ++l) { + a[l+ 0] = q4[l] & 0xF; + a[l+32] = q4[l] >> 4; + } + for (int is = 0; is < 8; ++is) { + uint8_t m = 1 << is; + for (int l = 0; l < 8; ++l) a[8*is + l] -= (hm[l] & m ? 0 : 16); + } + + const float d = y[i].d * GGML_FP16_TO_FP32(x[i].d); + const int8_t * restrict sc = x[i].scales; + + for (int j = 0; j < QK_K/16; ++j) { + const float dl = d * sc[j]; + for (int l = 0; l < 16; ++l) aux16[l] = q8[l] * a[l]; + for (int l = 0; l < 8; ++l) sums[l] += dl * (aux16[l] + aux16[8+l]); + q8 += 16; a += 16; + } + } + for (int l = 0; l < 8; ++l) sumf += sums[l]; + *s = sumf; +#endif +} +#endif + + +#if QK_K == 256 +void ggml_vec_dot_q6_K_q8_K(const int n, float * restrict s, const void * restrict vx, const void * restrict vy) { + assert(n % QK_K == 0); + + const block_q6_K * restrict x = vx; + const block_q8_K * restrict y = vy; + + const int nb = n / QK_K; + +#ifdef __ARM_NEON + + float sum = 0; + + const uint8x16_t m4b = vdupq_n_u8(0xF); +#if defined(__ARM_FEATURE_DOTPROD) + const int32x4_t vzero = vdupq_n_s32(0); +#endif + //const int8x16_t m32s = vdupq_n_s8(32); + + const uint8x16_t mone = vdupq_n_u8(3); + + int8x16x4_t q6bytes; + uint8x16x4_t q6h; + + for (int i = 0; i < nb; ++i) { + + const float d_all = GGML_FP16_TO_FP32(x[i].d); + + const uint8_t * restrict q6 = x[i].ql; + const uint8_t * restrict qh = x[i].qh; + const int8_t * restrict q8 = y[i].qs; + + const int8_t * restrict scale = x[i].scales; + + const int16x8x2_t q8sums = vld1q_s16_x2(y[i].bsums); + const int8x16_t scales = vld1q_s8(scale); + const int16x8x2_t q6scales = {vmovl_s8(vget_low_s8(scales)), vmovl_s8(vget_high_s8(scales))}; + + const int32x4_t prod = vaddq_s32(vaddq_s32(vmull_s16(vget_low_s16 (q8sums.val[0]), vget_low_s16 (q6scales.val[0])), + vmull_s16(vget_high_s16(q8sums.val[0]), vget_high_s16(q6scales.val[0]))), + vaddq_s32(vmull_s16(vget_low_s16 (q8sums.val[1]), vget_low_s16 (q6scales.val[1])), + vmull_s16(vget_high_s16(q8sums.val[1]), vget_high_s16(q6scales.val[1])))); + int32_t isum_mins = vaddvq_s32(prod); + + int32_t isum = 0; + + for (int j = 0; j < QK_K/128; ++j) { + + uint8x16x2_t qhbits = vld1q_u8_x2(qh); qh += 32; + uint8x16x4_t q6bits = vld1q_u8_x4(q6); q6 += 64; + int8x16x4_t q8bytes = vld1q_s8_x4(q8); q8 += 64; + + q6h.val[0] = vshlq_n_u8(vandq_u8(mone, qhbits.val[0]), 4); + q6h.val[1] = vshlq_n_u8(vandq_u8(mone, qhbits.val[1]), 4); + uint8x16_t shifted = vshrq_n_u8(qhbits.val[0], 2); + q6h.val[2] = vshlq_n_u8(vandq_u8(mone, shifted), 4); + shifted = vshrq_n_u8(qhbits.val[1], 2); + q6h.val[3] = vshlq_n_u8(vandq_u8(mone, shifted), 4); + + //q6bytes.val[0] = vsubq_s8(vreinterpretq_s8_u8(vorrq_u8(vandq_u8(q6bits.val[0], m4b), q6h.val[0])), m32s); + //q6bytes.val[1] = vsubq_s8(vreinterpretq_s8_u8(vorrq_u8(vandq_u8(q6bits.val[1], m4b), q6h.val[1])), m32s); + //q6bytes.val[2] = vsubq_s8(vreinterpretq_s8_u8(vorrq_u8(vandq_u8(q6bits.val[2], m4b), q6h.val[2])), m32s); + //q6bytes.val[3] = vsubq_s8(vreinterpretq_s8_u8(vorrq_u8(vandq_u8(q6bits.val[3], m4b), q6h.val[3])), m32s); + q6bytes.val[0] = vreinterpretq_s8_u8(vorrq_u8(vandq_u8(q6bits.val[0], m4b), q6h.val[0])); + q6bytes.val[1] = vreinterpretq_s8_u8(vorrq_u8(vandq_u8(q6bits.val[1], m4b), q6h.val[1])); + q6bytes.val[2] = vreinterpretq_s8_u8(vorrq_u8(vandq_u8(q6bits.val[2], m4b), q6h.val[2])); + q6bytes.val[3] = vreinterpretq_s8_u8(vorrq_u8(vandq_u8(q6bits.val[3], m4b), q6h.val[3])); + +#if defined(__ARM_FEATURE_DOTPROD) + + isum += vaddvq_s32(vdotq_s32(vzero, q6bytes.val[0], q8bytes.val[0])) * scale[0] + + vaddvq_s32(vdotq_s32(vzero, q6bytes.val[1], q8bytes.val[1])) * scale[1] + + vaddvq_s32(vdotq_s32(vzero, q6bytes.val[2], q8bytes.val[2])) * scale[2] + + vaddvq_s32(vdotq_s32(vzero, q6bytes.val[3], q8bytes.val[3])) * scale[3]; + scale += 4; + +#else + + int16x8_t p0 = vaddq_s16(vmull_s8(vget_low_s8 (q6bytes.val[0]), vget_low_s8 (q8bytes.val[0])), + vmull_s8(vget_high_s8(q6bytes.val[0]), vget_high_s8(q8bytes.val[0]))); + int16x8_t p1 = vaddq_s16(vmull_s8(vget_low_s8 (q6bytes.val[1]), vget_low_s8 (q8bytes.val[1])), + vmull_s8(vget_high_s8(q6bytes.val[1]), vget_high_s8(q8bytes.val[1]))); + isum += vaddvq_s16(p0) * scale[0] + vaddvq_s16(p1) * scale[1]; + scale += 2; + + int16x8_t p2 = vaddq_s16(vmull_s8(vget_low_s8 (q6bytes.val[2]), vget_low_s8 (q8bytes.val[2])), + vmull_s8(vget_high_s8(q6bytes.val[2]), vget_high_s8(q8bytes.val[2]))); + int16x8_t p3 = vaddq_s16(vmull_s8(vget_low_s8 (q6bytes.val[3]), vget_low_s8 (q8bytes.val[3])), + vmull_s8(vget_high_s8(q6bytes.val[3]), vget_high_s8(q8bytes.val[3]))); + isum += vaddvq_s16(p2) * scale[0] + vaddvq_s16(p3) * scale[1]; + scale += 2; +#endif + + q8bytes = vld1q_s8_x4(q8); q8 += 64; + + shifted = vshrq_n_u8(qhbits.val[0], 4); + q6h.val[0] = vshlq_n_u8(vandq_u8(mone, shifted), 4); + shifted = vshrq_n_u8(qhbits.val[1], 4); + q6h.val[1] = vshlq_n_u8(vandq_u8(mone, shifted), 4); + shifted = vshrq_n_u8(qhbits.val[0], 6); + q6h.val[2] = vshlq_n_u8(vandq_u8(mone, shifted), 4); + shifted = vshrq_n_u8(qhbits.val[1], 6); + q6h.val[3] = vshlq_n_u8(vandq_u8(mone, shifted), 4); + + //q6bytes.val[0] = vsubq_s8(vreinterpretq_s8_u8(vorrq_u8(vshrq_n_u8(q6bits.val[0], 4), q6h.val[0])), m32s); + //q6bytes.val[1] = vsubq_s8(vreinterpretq_s8_u8(vorrq_u8(vshrq_n_u8(q6bits.val[1], 4), q6h.val[1])), m32s); + //q6bytes.val[2] = vsubq_s8(vreinterpretq_s8_u8(vorrq_u8(vshrq_n_u8(q6bits.val[2], 4), q6h.val[2])), m32s); + //q6bytes.val[3] = vsubq_s8(vreinterpretq_s8_u8(vorrq_u8(vshrq_n_u8(q6bits.val[3], 4), q6h.val[3])), m32s); + q6bytes.val[0] = vreinterpretq_s8_u8(vorrq_u8(vshrq_n_u8(q6bits.val[0], 4), q6h.val[0])); + q6bytes.val[1] = vreinterpretq_s8_u8(vorrq_u8(vshrq_n_u8(q6bits.val[1], 4), q6h.val[1])); + q6bytes.val[2] = vreinterpretq_s8_u8(vorrq_u8(vshrq_n_u8(q6bits.val[2], 4), q6h.val[2])); + q6bytes.val[3] = vreinterpretq_s8_u8(vorrq_u8(vshrq_n_u8(q6bits.val[3], 4), q6h.val[3])); + +#if defined(__ARM_FEATURE_DOTPROD) + + isum += vaddvq_s32(vdotq_s32(vzero, q6bytes.val[0], q8bytes.val[0])) * scale[0] + + vaddvq_s32(vdotq_s32(vzero, q6bytes.val[1], q8bytes.val[1])) * scale[1] + + vaddvq_s32(vdotq_s32(vzero, q6bytes.val[2], q8bytes.val[2])) * scale[2] + + vaddvq_s32(vdotq_s32(vzero, q6bytes.val[3], q8bytes.val[3])) * scale[3]; + scale += 4; + + //for (int l = 0; l < 4; ++l) { + // const int32x4_t p = vdotq_s32(vzero, q6bytes.val[l], q8bytes.val[l]); + // isum += vaddvq_s32(p) * *scale++; + //} +#else + p0 = vaddq_s16(vmull_s8(vget_low_s8 (q6bytes.val[0]), vget_low_s8 (q8bytes.val[0])), + vmull_s8(vget_high_s8(q6bytes.val[0]), vget_high_s8(q8bytes.val[0]))); + p1 = vaddq_s16(vmull_s8(vget_low_s8 (q6bytes.val[1]), vget_low_s8 (q8bytes.val[1])), + vmull_s8(vget_high_s8(q6bytes.val[1]), vget_high_s8(q8bytes.val[1]))); + isum += vaddvq_s16(p0) * scale[0] + vaddvq_s16(p1) * scale[1]; + scale += 2; + + p2 = vaddq_s16(vmull_s8(vget_low_s8 (q6bytes.val[2]), vget_low_s8 (q8bytes.val[2])), + vmull_s8(vget_high_s8(q6bytes.val[2]), vget_high_s8(q8bytes.val[2]))); + p3 = vaddq_s16(vmull_s8(vget_low_s8 (q6bytes.val[3]), vget_low_s8 (q8bytes.val[3])), + vmull_s8(vget_high_s8(q6bytes.val[3]), vget_high_s8(q8bytes.val[3]))); + isum += vaddvq_s16(p2) * scale[0] + vaddvq_s16(p3) * scale[1]; + scale += 2; +#endif + + } + //sum += isum * d_all * y[i].d; + sum += d_all * y[i].d * (isum - 32 * isum_mins); + + } + *s = sum; + +#elif defined __AVX2__ + + const __m256i m4 = _mm256_set1_epi8(0xF); + const __m256i m2 = _mm256_set1_epi8(3); + const __m256i m32s = _mm256_set1_epi8(32); + + __m256 acc = _mm256_setzero_ps(); + + for (int i = 0; i < nb; ++i) { + + const float d = y[i].d * GGML_FP16_TO_FP32(x[i].d); + + const uint8_t * restrict q4 = x[i].ql; + const uint8_t * restrict qh = x[i].qh; + const int8_t * restrict q8 = y[i].qs; + + const __m128i scales = _mm_loadu_si128((const __m128i*)x[i].scales); + + __m256i sumi = _mm256_setzero_si256(); + + int is = 0; + + for (int j = 0; j < QK_K/128; ++j) { + + const __m128i scale_0 = _mm_shuffle_epi8(scales, get_scale_shuffle(is + 0)); + const __m128i scale_1 = _mm_shuffle_epi8(scales, get_scale_shuffle(is + 1)); + const __m128i scale_2 = _mm_shuffle_epi8(scales, get_scale_shuffle(is + 2)); + const __m128i scale_3 = _mm_shuffle_epi8(scales, get_scale_shuffle(is + 3)); + is += 4; + + const __m256i q4bits1 = _mm256_loadu_si256((const __m256i*)q4); q4 += 32; + const __m256i q4bits2 = _mm256_loadu_si256((const __m256i*)q4); q4 += 32; + const __m256i q4bitsH = _mm256_loadu_si256((const __m256i*)qh); qh += 32; + + const __m256i q4h_0 = _mm256_slli_epi16(_mm256_and_si256(q4bitsH, m2), 4); + const __m256i q4h_1 = _mm256_slli_epi16(_mm256_and_si256(_mm256_srli_epi16(q4bitsH, 2), m2), 4); + const __m256i q4h_2 = _mm256_slli_epi16(_mm256_and_si256(_mm256_srli_epi16(q4bitsH, 4), m2), 4); + const __m256i q4h_3 = _mm256_slli_epi16(_mm256_and_si256(_mm256_srli_epi16(q4bitsH, 6), m2), 4); + + const __m256i q4_0 = _mm256_or_si256(_mm256_and_si256(q4bits1, m4), q4h_0); + const __m256i q4_1 = _mm256_or_si256(_mm256_and_si256(q4bits2, m4), q4h_1); + const __m256i q4_2 = _mm256_or_si256(_mm256_and_si256(_mm256_srli_epi16(q4bits1, 4), m4), q4h_2); + const __m256i q4_3 = _mm256_or_si256(_mm256_and_si256(_mm256_srli_epi16(q4bits2, 4), m4), q4h_3); + + const __m256i q8_0 = _mm256_loadu_si256((const __m256i*)q8); q8 += 32; + const __m256i q8_1 = _mm256_loadu_si256((const __m256i*)q8); q8 += 32; + const __m256i q8_2 = _mm256_loadu_si256((const __m256i*)q8); q8 += 32; + const __m256i q8_3 = _mm256_loadu_si256((const __m256i*)q8); q8 += 32; + + __m256i q8s_0 = _mm256_maddubs_epi16(m32s, q8_0); + __m256i q8s_1 = _mm256_maddubs_epi16(m32s, q8_1); + __m256i q8s_2 = _mm256_maddubs_epi16(m32s, q8_2); + __m256i q8s_3 = _mm256_maddubs_epi16(m32s, q8_3); + + __m256i p16_0 = _mm256_maddubs_epi16(q4_0, q8_0); + __m256i p16_1 = _mm256_maddubs_epi16(q4_1, q8_1); + __m256i p16_2 = _mm256_maddubs_epi16(q4_2, q8_2); + __m256i p16_3 = _mm256_maddubs_epi16(q4_3, q8_3); + + p16_0 = _mm256_sub_epi16(p16_0, q8s_0); + p16_1 = _mm256_sub_epi16(p16_1, q8s_1); + p16_2 = _mm256_sub_epi16(p16_2, q8s_2); + p16_3 = _mm256_sub_epi16(p16_3, q8s_3); + + p16_0 = _mm256_madd_epi16(_mm256_cvtepi8_epi16(scale_0), p16_0); + p16_1 = _mm256_madd_epi16(_mm256_cvtepi8_epi16(scale_1), p16_1); + p16_2 = _mm256_madd_epi16(_mm256_cvtepi8_epi16(scale_2), p16_2); + p16_3 = _mm256_madd_epi16(_mm256_cvtepi8_epi16(scale_3), p16_3); + + sumi = _mm256_add_epi32(sumi, _mm256_add_epi32(p16_0, p16_1)); + sumi = _mm256_add_epi32(sumi, _mm256_add_epi32(p16_2, p16_3)); + + } + + acc = _mm256_fmadd_ps(_mm256_broadcast_ss(&d), _mm256_cvtepi32_ps(sumi), acc); + } + + *s = hsum_float_8(acc); + +#elif defined __AVX__ + + const __m128i m4 = _mm_set1_epi8(0xF); + const __m128i m3 = _mm_set1_epi8(3); + const __m128i m32s = _mm_set1_epi8(32); + const __m128i m2 = _mm_set1_epi8(2); + + __m256 acc = _mm256_setzero_ps(); + + for (int i = 0; i < nb; ++i) { + + const float d = y[i].d * GGML_FP16_TO_FP32(x[i].d); + + const uint8_t * restrict q4 = x[i].ql; + const uint8_t * restrict qh = x[i].qh; + const int8_t * restrict q8 = y[i].qs; + + const __m128i scales = _mm_loadu_si128((const __m128i*)x[i].scales); + + __m128i sumi_0 = _mm_setzero_si128(); + __m128i sumi_1 = _mm_setzero_si128(); + + __m128i shuffle = _mm_set_epi64x(0x0101010101010101, 0x0000000000000000); + for (int j = 0; j < QK_K/128; ++j) { + + const __m128i q4bitsH_0 = _mm_loadu_si128((const __m128i*)qh); qh += 16; + const __m128i q4bitsH_1 = _mm_loadu_si128((const __m128i*)qh); qh += 16; + + const __m128i q4h_0 = _mm_slli_epi16(_mm_and_si128(q4bitsH_0, m3), 4); + const __m128i q4h_1 = _mm_slli_epi16(_mm_and_si128(q4bitsH_1, m3), 4); + const __m128i q4h_2 = _mm_slli_epi16(_mm_and_si128(_mm_srli_epi16(q4bitsH_0, 2), m3), 4); + const __m128i q4h_3 = _mm_slli_epi16(_mm_and_si128(_mm_srli_epi16(q4bitsH_1, 2), m3), 4); + const __m128i q4h_4 = _mm_slli_epi16(_mm_and_si128(_mm_srli_epi16(q4bitsH_0, 4), m3), 4); + const __m128i q4h_5 = _mm_slli_epi16(_mm_and_si128(_mm_srli_epi16(q4bitsH_1, 4), m3), 4); + const __m128i q4h_6 = _mm_slli_epi16(_mm_and_si128(_mm_srli_epi16(q4bitsH_0, 6), m3), 4); + const __m128i q4h_7 = _mm_slli_epi16(_mm_and_si128(_mm_srli_epi16(q4bitsH_1, 6), m3), 4); + + const __m128i q4bits1_0 = _mm_loadu_si128((const __m128i*)q4); q4 += 16; + const __m128i q4bits1_1 = _mm_loadu_si128((const __m128i*)q4); q4 += 16; + const __m128i q4bits2_0 = _mm_loadu_si128((const __m128i*)q4); q4 += 16; + const __m128i q4bits2_1 = _mm_loadu_si128((const __m128i*)q4); q4 += 16; + + const __m128i q4_0 = _mm_or_si128(_mm_and_si128(q4bits1_0, m4), q4h_0); + const __m128i q4_1 = _mm_or_si128(_mm_and_si128(q4bits1_1, m4), q4h_1); + const __m128i q4_2 = _mm_or_si128(_mm_and_si128(q4bits2_0, m4), q4h_2); + const __m128i q4_3 = _mm_or_si128(_mm_and_si128(q4bits2_1, m4), q4h_3); + const __m128i q4_4 = _mm_or_si128(_mm_and_si128(_mm_srli_epi16(q4bits1_0, 4), m4), q4h_4); + const __m128i q4_5 = _mm_or_si128(_mm_and_si128(_mm_srli_epi16(q4bits1_1, 4), m4), q4h_5); + const __m128i q4_6 = _mm_or_si128(_mm_and_si128(_mm_srli_epi16(q4bits2_0, 4), m4), q4h_6); + const __m128i q4_7 = _mm_or_si128(_mm_and_si128(_mm_srli_epi16(q4bits2_1, 4), m4), q4h_7); + + const __m128i q8_0 = _mm_loadu_si128((const __m128i*)q8); q8 += 16; + const __m128i q8_1 = _mm_loadu_si128((const __m128i*)q8); q8 += 16; + const __m128i q8_2 = _mm_loadu_si128((const __m128i*)q8); q8 += 16; + const __m128i q8_3 = _mm_loadu_si128((const __m128i*)q8); q8 += 16; + const __m128i q8_4 = _mm_loadu_si128((const __m128i*)q8); q8 += 16; + const __m128i q8_5 = _mm_loadu_si128((const __m128i*)q8); q8 += 16; + const __m128i q8_6 = _mm_loadu_si128((const __m128i*)q8); q8 += 16; + const __m128i q8_7 = _mm_loadu_si128((const __m128i*)q8); q8 += 16; + + __m128i q8s_0 = _mm_maddubs_epi16(m32s, q8_0); + __m128i q8s_1 = _mm_maddubs_epi16(m32s, q8_1); + __m128i q8s_2 = _mm_maddubs_epi16(m32s, q8_2); + __m128i q8s_3 = _mm_maddubs_epi16(m32s, q8_3); + __m128i q8s_4 = _mm_maddubs_epi16(m32s, q8_4); + __m128i q8s_5 = _mm_maddubs_epi16(m32s, q8_5); + __m128i q8s_6 = _mm_maddubs_epi16(m32s, q8_6); + __m128i q8s_7 = _mm_maddubs_epi16(m32s, q8_7); + + __m128i p16_0 = _mm_maddubs_epi16(q4_0, q8_0); + __m128i p16_1 = _mm_maddubs_epi16(q4_1, q8_1); + __m128i p16_2 = _mm_maddubs_epi16(q4_2, q8_2); + __m128i p16_3 = _mm_maddubs_epi16(q4_3, q8_3); + __m128i p16_4 = _mm_maddubs_epi16(q4_4, q8_4); + __m128i p16_5 = _mm_maddubs_epi16(q4_5, q8_5); + __m128i p16_6 = _mm_maddubs_epi16(q4_6, q8_6); + __m128i p16_7 = _mm_maddubs_epi16(q4_7, q8_7); + + p16_0 = _mm_sub_epi16(p16_0, q8s_0); + p16_1 = _mm_sub_epi16(p16_1, q8s_1); + p16_2 = _mm_sub_epi16(p16_2, q8s_2); + p16_3 = _mm_sub_epi16(p16_3, q8s_3); + p16_4 = _mm_sub_epi16(p16_4, q8s_4); + p16_5 = _mm_sub_epi16(p16_5, q8s_5); + p16_6 = _mm_sub_epi16(p16_6, q8s_6); + p16_7 = _mm_sub_epi16(p16_7, q8s_7); + + const __m128i scale_0 = _mm_shuffle_epi8(scales, shuffle); + shuffle = _mm_add_epi8(shuffle, m2); + const __m128i scale_1 = _mm_shuffle_epi8(scales, shuffle); + shuffle = _mm_add_epi8(shuffle, m2); + const __m128i scale_2 = _mm_shuffle_epi8(scales, shuffle); + shuffle = _mm_add_epi8(shuffle, m2); + const __m128i scale_3 = _mm_shuffle_epi8(scales, shuffle); + shuffle = _mm_add_epi8(shuffle, m2); + + p16_0 = _mm_madd_epi16(_mm_cvtepi8_epi16(scale_0), p16_0); + p16_1 = _mm_madd_epi16(_mm_cvtepi8_epi16(_mm_unpackhi_epi64(scale_0, scale_0)), p16_1); + p16_2 = _mm_madd_epi16(_mm_cvtepi8_epi16(scale_1), p16_2); + p16_3 = _mm_madd_epi16(_mm_cvtepi8_epi16(_mm_unpackhi_epi64(scale_1, scale_1)), p16_3); + p16_4 = _mm_madd_epi16(_mm_cvtepi8_epi16(scale_2), p16_4); + p16_5 = _mm_madd_epi16(_mm_cvtepi8_epi16(_mm_unpackhi_epi64(scale_2, scale_2)), p16_5); + p16_6 = _mm_madd_epi16(_mm_cvtepi8_epi16(scale_3), p16_6); + p16_7 = _mm_madd_epi16(_mm_cvtepi8_epi16(_mm_unpackhi_epi64(scale_3, scale_3)), p16_7); + + sumi_0 = _mm_add_epi32(sumi_0, _mm_add_epi32(p16_0, p16_2)); + sumi_1 = _mm_add_epi32(sumi_1, _mm_add_epi32(p16_1, p16_3)); + sumi_0 = _mm_add_epi32(sumi_0, _mm_add_epi32(p16_4, p16_6)); + sumi_1 = _mm_add_epi32(sumi_1, _mm_add_epi32(p16_5, p16_7)); + + } + + __m256i sumi = MM256_SET_M128I(sumi_1, sumi_0); + acc = _mm256_add_ps(_mm256_mul_ps(_mm256_broadcast_ss(&d), _mm256_cvtepi32_ps(sumi)), acc); + } + + *s = hsum_float_8(acc); + +#elif defined __riscv_v_intrinsic + + float sumf = 0; + for (int i = 0; i < nb; ++i) { + + const float d = GGML_FP16_TO_FP32(x[i].d) * y[i].d; + + const uint8_t * restrict q6 = x[i].ql; + const uint8_t * restrict qh = x[i].qh; + const int8_t * restrict q8 = y[i].qs; + + const int8_t * restrict scale = x[i].scales; + + size_t vl; + + vint32m1_t vzero = __riscv_vmv_v_x_i32m1(0, 1); + + int sum_t = 0; + int is = 0; + + for (int j = 0; j < QK_K/128; ++j) { + + vl = 32; + + // load qh + vuint8m1_t qh_x = __riscv_vle8_v_u8m1(qh, vl); + + // load Q6 + vuint8m1_t q6_0 = __riscv_vle8_v_u8m1(q6, vl); + vuint8m1_t q6_1 = __riscv_vle8_v_u8m1(q6+32, vl); + + vuint8m1_t q6a_0 = __riscv_vand_vx_u8m1(q6_0, 0x0F, vl); + vuint8m1_t q6a_1 = __riscv_vand_vx_u8m1(q6_1, 0x0F, vl); + vuint8m1_t q6s_0 = __riscv_vsrl_vx_u8m1(q6_0, 0x04, vl); + vuint8m1_t q6s_1 = __riscv_vsrl_vx_u8m1(q6_1, 0x04, vl); + + vuint8m1_t qh_0 = __riscv_vand_vx_u8m1(qh_x, 0x03, vl); + vuint8m1_t qh_1 = __riscv_vand_vx_u8m1(__riscv_vsrl_vx_u8m1(qh_x, 0x2, vl), 0x03 , vl); + vuint8m1_t qh_2 = __riscv_vand_vx_u8m1(__riscv_vsrl_vx_u8m1(qh_x, 0x4, vl), 0x03 , vl); + vuint8m1_t qh_3 = __riscv_vand_vx_u8m1(__riscv_vsrl_vx_u8m1(qh_x, 0x6, vl), 0x03 , vl); + + vuint8m1_t qhi_0 = __riscv_vor_vv_u8m1(q6a_0, __riscv_vsll_vx_u8m1(qh_0, 0x04, vl), vl); + vuint8m1_t qhi_1 = __riscv_vor_vv_u8m1(q6a_1, __riscv_vsll_vx_u8m1(qh_1, 0x04, vl), vl); + vuint8m1_t qhi_2 = __riscv_vor_vv_u8m1(q6s_0, __riscv_vsll_vx_u8m1(qh_2, 0x04, vl), vl); + vuint8m1_t qhi_3 = __riscv_vor_vv_u8m1(q6s_1, __riscv_vsll_vx_u8m1(qh_3, 0x04, vl), vl); + + vint8m1_t a_0 = __riscv_vsub_vx_i8m1(__riscv_vreinterpret_v_u8m1_i8m1(qhi_0), 32, vl); + vint8m1_t a_1 = __riscv_vsub_vx_i8m1(__riscv_vreinterpret_v_u8m1_i8m1(qhi_1), 32, vl); + vint8m1_t a_2 = __riscv_vsub_vx_i8m1(__riscv_vreinterpret_v_u8m1_i8m1(qhi_2), 32, vl); + vint8m1_t a_3 = __riscv_vsub_vx_i8m1(__riscv_vreinterpret_v_u8m1_i8m1(qhi_3), 32, vl); + + // load Q8 and take product + vint16m2_t va_q_0 = __riscv_vwmul_vv_i16m2(a_0, __riscv_vle8_v_i8m1(q8, vl), vl); + vint16m2_t va_q_1 = __riscv_vwmul_vv_i16m2(a_1, __riscv_vle8_v_i8m1(q8+32, vl), vl); + vint16m2_t va_q_2 = __riscv_vwmul_vv_i16m2(a_2, __riscv_vle8_v_i8m1(q8+64, vl), vl); + vint16m2_t va_q_3 = __riscv_vwmul_vv_i16m2(a_3, __riscv_vle8_v_i8m1(q8+96, vl), vl); + + vl = 16; + + vint32m2_t vaux_0 = __riscv_vwmul_vx_i32m2(__riscv_vget_v_i16m2_i16m1(va_q_0, 0), scale[is+0], vl); + vint32m2_t vaux_1 = __riscv_vwmul_vx_i32m2(__riscv_vget_v_i16m2_i16m1(va_q_0, 1), scale[is+1], vl); + vint32m2_t vaux_2 = __riscv_vwmul_vx_i32m2(__riscv_vget_v_i16m2_i16m1(va_q_1, 0), scale[is+2], vl); + vint32m2_t vaux_3 = __riscv_vwmul_vx_i32m2(__riscv_vget_v_i16m2_i16m1(va_q_1, 1), scale[is+3], vl); + vint32m2_t vaux_4 = __riscv_vwmul_vx_i32m2(__riscv_vget_v_i16m2_i16m1(va_q_2, 0), scale[is+4], vl); + vint32m2_t vaux_5 = __riscv_vwmul_vx_i32m2(__riscv_vget_v_i16m2_i16m1(va_q_2, 1), scale[is+5], vl); + vint32m2_t vaux_6 = __riscv_vwmul_vx_i32m2(__riscv_vget_v_i16m2_i16m1(va_q_3, 0), scale[is+6], vl); + vint32m2_t vaux_7 = __riscv_vwmul_vx_i32m2(__riscv_vget_v_i16m2_i16m1(va_q_3, 1), scale[is+7], vl); + + vint32m1_t isum0 = __riscv_vredsum_vs_i32m2_i32m1(__riscv_vadd_vv_i32m2(vaux_0, vaux_1, vl), vzero, vl); + vint32m1_t isum1 = __riscv_vredsum_vs_i32m2_i32m1(__riscv_vadd_vv_i32m2(vaux_2, vaux_3, vl), isum0, vl); + vint32m1_t isum2 = __riscv_vredsum_vs_i32m2_i32m1(__riscv_vadd_vv_i32m2(vaux_4, vaux_5, vl), isum1, vl); + vint32m1_t isum3 = __riscv_vredsum_vs_i32m2_i32m1(__riscv_vadd_vv_i32m2(vaux_6, vaux_7, vl), isum2, vl); + + sum_t += __riscv_vmv_x_s_i32m1_i32(isum3); + + q6 += 64; qh += 32; q8 += 128; is=8; + + } + + sumf += d * sum_t; + + } + + *s = sumf; + +#else + + int8_t aux8[QK_K]; + int16_t aux16[8]; + float sums [8]; + int32_t aux32[8]; + memset(sums, 0, 8*sizeof(float)); + + float sumf = 0; + for (int i = 0; i < nb; ++i) { + const uint8_t * restrict q4 = x[i].ql; + const uint8_t * restrict qh = x[i].qh; + const int8_t * restrict q8 = y[i].qs; + memset(aux32, 0, 8*sizeof(int32_t)); + int8_t * restrict a = aux8; + for (int j = 0; j < QK_K; j += 128) { + for (int l = 0; l < 32; ++l) { + a[l + 0] = (int8_t)((q4[l + 0] & 0xF) | (((qh[l] >> 0) & 3) << 4)) - 32; + a[l + 32] = (int8_t)((q4[l + 32] & 0xF) | (((qh[l] >> 2) & 3) << 4)) - 32; + a[l + 64] = (int8_t)((q4[l + 0] >> 4) | (((qh[l] >> 4) & 3) << 4)) - 32; + a[l + 96] = (int8_t)((q4[l + 32] >> 4) | (((qh[l] >> 6) & 3) << 4)) - 32; + } + a += 128; + q4 += 64; + qh += 32; + } + a = aux8; + int is = 0; + for (int j = 0; j < QK_K/16; ++j) { + int scale = x[i].scales[is++]; + for (int l = 0; l < 8; ++l) aux16[l] = q8[l] * a[l]; + for (int l = 0; l < 8; ++l) aux32[l] += scale * aux16[l]; + q8 += 8; a += 8; + for (int l = 0; l < 8; ++l) aux16[l] = q8[l] * a[l]; + for (int l = 0; l < 8; ++l) aux32[l] += scale * aux16[l]; + q8 += 8; a += 8; + } + const float d = GGML_FP16_TO_FP32(x[i].d) * y[i].d; + for (int l = 0; l < 8; ++l) sums[l] += d * aux32[l]; + } + for (int l = 0; l < 8; ++l) sumf += sums[l]; + *s = sumf; +#endif +} + +#else + +void ggml_vec_dot_q6_K_q8_K(const int n, float * restrict s, const void * restrict vx, const void * restrict vy) { + assert(n % QK_K == 0); + + const block_q6_K * restrict x = vx; + const block_q8_K * restrict y = vy; + + const int nb = n / QK_K; + +#ifdef __ARM_NEON + + float sum = 0; + + const uint8x16_t m4b = vdupq_n_u8(0xF); + const int8x16_t m32s = vdupq_n_s8(32); +#if defined(__ARM_FEATURE_DOTPROD) + const int32x4_t vzero = vdupq_n_s32(0); +#endif + + const uint8x16_t mone = vdupq_n_u8(3); + + int8x16x4_t q6bytes; + uint8x16x4_t q6h; + + for (int i = 0; i < nb; ++i) { + + const float d_all = (float)x[i].d; + + const uint8_t * restrict q6 = x[i].ql; + const uint8_t * restrict qh = x[i].qh; + const int8_t * restrict q8 = y[i].qs; + + const int8_t * restrict scale = x[i].scales; + + int32_t isum = 0; + + uint8x16_t qhbits = vld1q_u8(qh); + uint8x16x2_t q6bits = vld1q_u8_x2(q6); + int8x16x4_t q8bytes = vld1q_s8_x4(q8); + + q6h.val[0] = vshlq_n_u8(vandq_u8(mone, qhbits), 4); + uint8x16_t shifted = vshrq_n_u8(qhbits, 2); + q6h.val[1] = vshlq_n_u8(vandq_u8(mone, shifted), 4); + shifted = vshrq_n_u8(qhbits, 4); + q6h.val[2] = vshlq_n_u8(vandq_u8(mone, shifted), 4); + shifted = vshrq_n_u8(qhbits, 6); + q6h.val[3] = vshlq_n_u8(vandq_u8(mone, shifted), 4); + + q6bytes.val[0] = vsubq_s8(vreinterpretq_s8_u8(vorrq_u8(vandq_u8(q6bits.val[0], m4b), q6h.val[0])), m32s); + q6bytes.val[1] = vsubq_s8(vreinterpretq_s8_u8(vorrq_u8(vandq_u8(q6bits.val[1], m4b), q6h.val[1])), m32s); + q6bytes.val[2] = vsubq_s8(vreinterpretq_s8_u8(vorrq_u8(vshrq_n_u8(q6bits.val[0], 4), q6h.val[2])), m32s); + q6bytes.val[3] = vsubq_s8(vreinterpretq_s8_u8(vorrq_u8(vshrq_n_u8(q6bits.val[1], 4), q6h.val[3])), m32s); + +#if defined(__ARM_FEATURE_DOTPROD) + + isum += vaddvq_s32(vdotq_s32(vzero, q6bytes.val[0], q8bytes.val[0])) * scale[0] + + vaddvq_s32(vdotq_s32(vzero, q6bytes.val[1], q8bytes.val[1])) * scale[1] + + vaddvq_s32(vdotq_s32(vzero, q6bytes.val[2], q8bytes.val[2])) * scale[2] + + vaddvq_s32(vdotq_s32(vzero, q6bytes.val[3], q8bytes.val[3])) * scale[3]; +#else + + int16x8_t p0 = vaddq_s16(vmull_s8(vget_low_s8 (q6bytes.val[0]), vget_low_s8 (q8bytes.val[0])), + vmull_s8(vget_high_s8(q6bytes.val[0]), vget_high_s8(q8bytes.val[0]))); + int16x8_t p1 = vaddq_s16(vmull_s8(vget_low_s8 (q6bytes.val[1]), vget_low_s8 (q8bytes.val[1])), + vmull_s8(vget_high_s8(q6bytes.val[1]), vget_high_s8(q8bytes.val[1]))); + isum += vaddvq_s16(p0) * scale[0] + vaddvq_s16(p1) * scale[1]; + + int16x8_t p2 = vaddq_s16(vmull_s8(vget_low_s8 (q6bytes.val[2]), vget_low_s8 (q8bytes.val[2])), + vmull_s8(vget_high_s8(q6bytes.val[2]), vget_high_s8(q8bytes.val[2]))); + int16x8_t p3 = vaddq_s16(vmull_s8(vget_low_s8 (q6bytes.val[3]), vget_low_s8 (q8bytes.val[3])), + vmull_s8(vget_high_s8(q6bytes.val[3]), vget_high_s8(q8bytes.val[3]))); + isum += vaddvq_s16(p2) * scale[2] + vaddvq_s16(p3) * scale[3]; +#endif + + sum += isum * d_all * y[i].d; + + } + *s = sum; + +#elif defined __AVX2__ + + const __m256i m4 = _mm256_set1_epi8(0xF); + const __m256i m2 = _mm256_set1_epi8(3); + const __m256i m32s = _mm256_set1_epi8(32); + + __m256 acc = _mm256_setzero_ps(); + + for (int i = 0; i < nb; ++i) { + + const float d = y[i].d * GGML_FP16_TO_FP32(x[i].d); + + const uint8_t * restrict q4 = x[i].ql; + const uint8_t * restrict qh = x[i].qh; + const int8_t * restrict q8 = y[i].qs; + + const __m64 scales_1 = _mm_set1_pi8(x[i].scales[0]); + const __m64 scales_2 = _mm_set1_pi8(x[i].scales[1]); + const __m64 scales_3 = _mm_set1_pi8(x[i].scales[2]); + const __m64 scales_4 = _mm_set1_pi8(x[i].scales[3]); + + __m256i sumi = _mm256_setzero_si256(); + + const __m128i scale_0 = _mm_set_epi64(scales_2, scales_1); + const __m128i scale_1 = _mm_set_epi64(scales_4, scales_3); + + const __m256i q4bits1 = _mm256_loadu_si256((const __m256i*)q4); + const __m128i q4bitsH = _mm_loadu_si128((const __m128i*)qh); + + const __m256i q4h_0 = _mm256_slli_epi16(_mm256_and_si256(MM256_SET_M128I(_mm_srli_epi16(q4bitsH, 2), q4bitsH), m2), 4); + const __m256i q4h_1 = _mm256_slli_epi16(_mm256_and_si256(MM256_SET_M128I(_mm_srli_epi16(q4bitsH, 6), _mm_srli_epi16(q4bitsH, 4)), m2), 4); + + const __m256i q4_0 = _mm256_or_si256(_mm256_and_si256(q4bits1, m4), q4h_0); + const __m256i q4_1 = _mm256_or_si256(_mm256_and_si256(_mm256_srli_epi16(q4bits1, 4), m4), q4h_1); + + const __m256i q8_0 = _mm256_loadu_si256((const __m256i*)(q8+ 0)); + const __m256i q8_1 = _mm256_loadu_si256((const __m256i*)(q8+32)); + + __m256i q8s_0 = _mm256_maddubs_epi16(m32s, q8_0); + __m256i q8s_1 = _mm256_maddubs_epi16(m32s, q8_1); + + __m256i p16_0 = _mm256_maddubs_epi16(q4_0, q8_0); + __m256i p16_1 = _mm256_maddubs_epi16(q4_1, q8_1); + + p16_0 = _mm256_sub_epi16(p16_0, q8s_0); + p16_1 = _mm256_sub_epi16(p16_1, q8s_1); + + p16_0 = _mm256_madd_epi16(_mm256_cvtepi8_epi16(scale_0), p16_0); + p16_1 = _mm256_madd_epi16(_mm256_cvtepi8_epi16(scale_1), p16_1); + + sumi = _mm256_add_epi32(sumi, _mm256_add_epi32(p16_0, p16_1)); + + acc = _mm256_fmadd_ps(_mm256_broadcast_ss(&d), _mm256_cvtepi32_ps(sumi), acc); + } + + *s = hsum_float_8(acc); + +#elif defined __AVX__ + + const __m128i m4 = _mm_set1_epi8(0xF); + const __m128i m2 = _mm_set1_epi8(3); + const __m128i m32s = _mm_set1_epi8(32); + + __m256 acc = _mm256_setzero_ps(); + + for (int i = 0; i < nb; ++i) { + + const float d = y[i].d * GGML_FP16_TO_FP32(x[i].d); + + const uint8_t * restrict q4 = x[i].ql; + const uint8_t * restrict qh = x[i].qh; + const int8_t * restrict q8 = y[i].qs; + + const __m64 scales_1 = _mm_set1_pi8(x[i].scales[0]); + const __m64 scales_2 = _mm_set1_pi8(x[i].scales[1]); + const __m64 scales_3 = _mm_set1_pi8(x[i].scales[2]); + const __m64 scales_4 = _mm_set1_pi8(x[i].scales[3]); + + __m128i sumi_0 = _mm_setzero_si128(); + __m128i sumi_1 = _mm_setzero_si128(); + + const __m128i scale_0 = _mm_set_epi64(scales_2, scales_1); + const __m128i scale_1 = _mm_set_epi64(scales_4, scales_3); + + const __m256i q4bits1 = _mm256_loadu_si256((const __m256i*)q4); + const __m128i q4bitsH = _mm_loadu_si128((const __m128i*)qh); + + const __m128i q4h_0 = _mm_slli_epi16(_mm_and_si128(q4bitsH, m2), 4); + const __m128i q4h_1 = _mm_slli_epi16(_mm_and_si128(_mm_srli_epi16(q4bitsH, 2), m2), 4); + const __m128i q4h_2 = _mm_slli_epi16(_mm_and_si128(_mm_srli_epi16(q4bitsH, 4), m2), 4); + const __m128i q4h_3 = _mm_slli_epi16(_mm_and_si128(_mm_srli_epi16(q4bitsH, 6), m2), 4); + + const __m128i q4_0 = _mm_or_si128(_mm_and_si128(_mm256_extractf128_si256(q4bits1, 0), m4), q4h_0); + const __m128i q4_1 = _mm_or_si128(_mm_and_si128(_mm256_extractf128_si256(q4bits1, 1), m4), q4h_1); + const __m128i q4_2 = _mm_or_si128(_mm_and_si128(_mm_srli_epi16(_mm256_extractf128_si256(q4bits1, 0), 4), m4), q4h_2); + const __m128i q4_3 = _mm_or_si128(_mm_and_si128(_mm_srli_epi16(_mm256_extractf128_si256(q4bits1, 1), 4), m4), q4h_3); + + const __m256i q8_0 = _mm256_loadu_si256((const __m256i*)(q8+ 0)); + const __m256i q8_1 = _mm256_loadu_si256((const __m256i*)(q8+32)); + + __m128i q8s_0 = _mm_maddubs_epi16(m32s, _mm256_extractf128_si256(q8_0, 0)); + __m128i q8s_1 = _mm_maddubs_epi16(m32s, _mm256_extractf128_si256(q8_0, 1)); + __m128i q8s_2 = _mm_maddubs_epi16(m32s, _mm256_extractf128_si256(q8_1, 0)); + __m128i q8s_3 = _mm_maddubs_epi16(m32s, _mm256_extractf128_si256(q8_1, 1)); + + __m128i p16_0 = _mm_maddubs_epi16(q4_0, _mm256_extractf128_si256(q8_0, 0)); + __m128i p16_1 = _mm_maddubs_epi16(q4_1, _mm256_extractf128_si256(q8_0, 1)); + __m128i p16_2 = _mm_maddubs_epi16(q4_2, _mm256_extractf128_si256(q8_1, 0)); + __m128i p16_3 = _mm_maddubs_epi16(q4_3, _mm256_extractf128_si256(q8_1, 1)); + + p16_0 = _mm_sub_epi16(p16_0, q8s_0); + p16_1 = _mm_sub_epi16(p16_1, q8s_1); + p16_2 = _mm_sub_epi16(p16_2, q8s_2); + p16_3 = _mm_sub_epi16(p16_3, q8s_3); + + p16_0 = _mm_madd_epi16(_mm_cvtepi8_epi16(scale_0), p16_0); + p16_1 = _mm_madd_epi16(_mm_cvtepi8_epi16(_mm_unpackhi_epi64(scale_0, scale_0)), p16_1); + p16_2 = _mm_madd_epi16(_mm_cvtepi8_epi16(scale_1), p16_2); + p16_3 = _mm_madd_epi16(_mm_cvtepi8_epi16(_mm_unpackhi_epi64(scale_1, scale_1)), p16_3); + + sumi_0 = _mm_add_epi32(sumi_0, _mm_add_epi32(p16_0, p16_2)); + sumi_1 = _mm_add_epi32(sumi_1, _mm_add_epi32(p16_1, p16_3)); + + acc = _mm256_add_ps(_mm256_mul_ps(_mm256_broadcast_ss(&d), _mm256_cvtepi32_ps(MM256_SET_M128I(sumi_1, sumi_0))), acc); + } + + *s = hsum_float_8(acc); + +#elif defined __riscv_v_intrinsic + + float sumf = 0; + + for (int i = 0; i < nb; ++i) { + + const float d_all = (float)x[i].d; + + const uint8_t * restrict q6 = x[i].ql; + const uint8_t * restrict qh = x[i].qh; + const int8_t * restrict q8 = y[i].qs; + + const int8_t * restrict scale = x[i].scales; + + int32_t isum = 0; + + size_t vl = 16; + + vint32m1_t vzero = __riscv_vmv_v_x_i32m1(0, 1); + + // load Q6 + vuint8mf2_t q6_0 = __riscv_vle8_v_u8mf2(q6, vl); + vuint8mf2_t q6_1 = __riscv_vle8_v_u8mf2(q6+16, vl); + + // load qh + vuint8mf2_t qh_x = __riscv_vle8_v_u8mf2(qh, vl); + + vuint8mf2_t qh0 = __riscv_vsll_vx_u8mf2(__riscv_vand_vx_u8mf2(qh_x, 0x3, vl), 0x4, vl); + qh_x = __riscv_vsrl_vx_u8mf2(qh_x, 0x2, vl); + vuint8mf2_t qh1 = __riscv_vsll_vx_u8mf2(__riscv_vand_vx_u8mf2(qh_x, 0x3, vl), 0x4, vl); + qh_x = __riscv_vsrl_vx_u8mf2(qh_x, 0x2, vl); + vuint8mf2_t qh2 = __riscv_vsll_vx_u8mf2(__riscv_vand_vx_u8mf2(qh_x, 0x3, vl), 0x4, vl); + qh_x = __riscv_vsrl_vx_u8mf2(qh_x, 0x2, vl); + vuint8mf2_t qh3 = __riscv_vsll_vx_u8mf2(__riscv_vand_vx_u8mf2(qh_x, 0x3, vl), 0x4, vl); + + vuint8mf2_t q6h_0 = __riscv_vor_vv_u8mf2(__riscv_vand_vx_u8mf2(q6_0, 0xF, vl), qh0, vl); + vuint8mf2_t q6h_1 = __riscv_vor_vv_u8mf2(__riscv_vand_vx_u8mf2(q6_1, 0xF, vl), qh1, vl); + vuint8mf2_t q6h_2 = __riscv_vor_vv_u8mf2(__riscv_vsrl_vx_u8mf2(q6_0, 0x4, vl), qh2, vl); + vuint8mf2_t q6h_3 = __riscv_vor_vv_u8mf2(__riscv_vsrl_vx_u8mf2(q6_1, 0x4, vl), qh3, vl); + + vint8mf2_t q6v_0 = __riscv_vsub_vx_i8mf2(__riscv_vreinterpret_v_u8mf2_i8mf2(q6h_0), 32, vl); + vint8mf2_t q6v_1 = __riscv_vsub_vx_i8mf2(__riscv_vreinterpret_v_u8mf2_i8mf2(q6h_1), 32, vl); + vint8mf2_t q6v_2 = __riscv_vsub_vx_i8mf2(__riscv_vreinterpret_v_u8mf2_i8mf2(q6h_2), 32, vl); + vint8mf2_t q6v_3 = __riscv_vsub_vx_i8mf2(__riscv_vreinterpret_v_u8mf2_i8mf2(q6h_3), 32, vl); + + // load Q8 and take product + vint16m1_t p0 = __riscv_vwmul_vv_i16m1(q6v_0, __riscv_vle8_v_i8mf2(q8, vl), vl); + vint16m1_t p1 = __riscv_vwmul_vv_i16m1(q6v_1, __riscv_vle8_v_i8mf2(q8+16, vl), vl); + vint16m1_t p2 = __riscv_vwmul_vv_i16m1(q6v_2, __riscv_vle8_v_i8mf2(q8+32, vl), vl); + vint16m1_t p3 = __riscv_vwmul_vv_i16m1(q6v_3, __riscv_vle8_v_i8mf2(q8+48, vl), vl); + + vint32m1_t vs_0 = __riscv_vwredsum_vs_i16m1_i32m1(p0, vzero, vl); + vint32m1_t vs_1 = __riscv_vwredsum_vs_i16m1_i32m1(p1, vzero, vl); + vint32m1_t vs_2 = __riscv_vwredsum_vs_i16m1_i32m1(p2, vzero, vl); + vint32m1_t vs_3 = __riscv_vwredsum_vs_i16m1_i32m1(p3, vzero, vl); + + isum += __riscv_vmv_x_s_i32m1_i32(vs_0) * scale[0]; + isum += __riscv_vmv_x_s_i32m1_i32(vs_1) * scale[1]; + isum += __riscv_vmv_x_s_i32m1_i32(vs_2) * scale[2]; + isum += __riscv_vmv_x_s_i32m1_i32(vs_3) * scale[3]; + + sumf += isum * d_all * y[i].d; + + } + + *s = sumf; + +#else + + int8_t aux8[QK_K]; + int16_t aux16[8]; + float sums [8]; + int32_t aux32[8]; + memset(sums, 0, 8*sizeof(float)); + + float sumf = 0; + for (int i = 0; i < nb; ++i) { + const uint8_t * restrict q4 = x[i].ql; + const uint8_t * restrict qh = x[i].qh; + const int8_t * restrict q8 = y[i].qs; + memset(aux32, 0, 8*sizeof(int32_t)); + int8_t * restrict a = aux8; + for (int l = 0; l < 16; ++l) { + a[l+ 0] = (int8_t)((q4[l+ 0] & 0xF) | (((qh[l] >> 0) & 3) << 4)) - 32; + a[l+16] = (int8_t)((q4[l+16] & 0xF) | (((qh[l] >> 2) & 3) << 4)) - 32; + a[l+32] = (int8_t)((q4[l+ 0] >> 4) | (((qh[l] >> 4) & 3) << 4)) - 32; + a[l+48] = (int8_t)((q4[l+16] >> 4) | (((qh[l] >> 6) & 3) << 4)) - 32; + } + int is = 0; + for (int j = 0; j < QK_K/16; ++j) { + int scale = x[i].scales[is++]; + for (int l = 0; l < 8; ++l) aux16[l] = q8[l] * a[l]; + for (int l = 0; l < 8; ++l) aux32[l] += scale * aux16[l]; + q8 += 8; a += 8; + for (int l = 0; l < 8; ++l) aux16[l] = q8[l] * a[l]; + for (int l = 0; l < 8; ++l) aux32[l] += scale * aux16[l]; + q8 += 8; a += 8; + } + const float d = GGML_FP16_TO_FP32(x[i].d) * y[i].d; + for (int l = 0; l < 8; ++l) sums[l] += d * aux32[l]; + } + for (int l = 0; l < 8; ++l) sumf += sums[l]; + *s = sumf; +#endif +} + +#endif diff --git a/sys/whisper.cpp/bindings/ruby/ext/ggml-quants.h b/sys/whisper.cpp/bindings/ruby/ext/ggml-quants.h new file mode 100644 index 0000000..70c12c2 --- /dev/null +++ b/sys/whisper.cpp/bindings/ruby/ext/ggml-quants.h @@ -0,0 +1,224 @@ +#pragma once + +#include "ggml-impl.h" + +// GGML internal header + +#include +#include + +#define QK4_0 32 +typedef struct { + ggml_fp16_t d; // delta + uint8_t qs[QK4_0 / 2]; // nibbles / quants +} block_q4_0; +static_assert(sizeof(block_q4_0) == sizeof(ggml_fp16_t) + QK4_0 / 2, "wrong q4_0 block size/padding"); + +#define QK4_1 32 +typedef struct { + ggml_fp16_t d; // delta + ggml_fp16_t m; // min + uint8_t qs[QK4_1 / 2]; // nibbles / quants +} block_q4_1; +static_assert(sizeof(block_q4_1) == 2 * sizeof(ggml_fp16_t) + QK4_1 / 2, "wrong q4_1 block size/padding"); + +#define QK5_0 32 +typedef struct { + ggml_fp16_t d; // delta + uint8_t qh[4]; // 5-th bit of quants + uint8_t qs[QK5_0 / 2]; // nibbles / quants +} block_q5_0; +static_assert(sizeof(block_q5_0) == sizeof(ggml_fp16_t) + sizeof(uint32_t) + QK5_0 / 2, "wrong q5_0 block size/padding"); + +#define QK5_1 32 +typedef struct { + ggml_fp16_t d; // delta + ggml_fp16_t m; // min + uint8_t qh[4]; // 5-th bit of quants + uint8_t qs[QK5_1 / 2]; // nibbles / quants +} block_q5_1; +static_assert(sizeof(block_q5_1) == 2 * sizeof(ggml_fp16_t) + sizeof(uint32_t) + QK5_1 / 2, "wrong q5_1 block size/padding"); + +#define QK8_0 32 +typedef struct { + ggml_fp16_t d; // delta + int8_t qs[QK8_0]; // quants +} block_q8_0; +static_assert(sizeof(block_q8_0) == sizeof(ggml_fp16_t) + QK8_0, "wrong q8_0 block size/padding"); + +#define QK8_1 32 +typedef struct { + float d; // delta + float s; // d * sum(qs[i]) + int8_t qs[QK8_1]; // quants +} block_q8_1; +static_assert(sizeof(block_q8_1) == 2*sizeof(float) + QK8_1, "wrong q8_1 block size/padding"); + +// +// Super-block quantization structures +// + +// Super-block size +#ifdef GGML_QKK_64 +#define QK_K 64 +#define K_SCALE_SIZE 4 +#else +#define QK_K 256 +#define K_SCALE_SIZE 12 +#endif + +// 2-bit quantization +// weight is represented as x = a * q + b +// 16 blocks of 16 elements each +// Effectively 2.5625 bits per weight +typedef struct { + uint8_t scales[QK_K/16]; // scales and mins, quantized with 4 bits + uint8_t qs[QK_K/4]; // quants + ggml_fp16_t d; // super-block scale for quantized scales + ggml_fp16_t dmin; // super-block scale for quantized mins +} block_q2_K; +static_assert(sizeof(block_q2_K) == 2*sizeof(ggml_fp16_t) + QK_K/16 + QK_K/4, "wrong q2_K block size/padding"); + +// 3-bit quantization +// weight is represented as x = a * q +// 16 blocks of 16 elements each +// Effectively 3.4375 bits per weight +#ifdef GGML_QKK_64 +typedef struct { + uint8_t hmask[QK_K/8]; // quants - high bit + uint8_t qs[QK_K/4]; // quants - low 2 bits + uint8_t scales[2]; + ggml_fp16_t d; // super-block scale +} block_q3_K; +static_assert(sizeof(block_q3_K) == sizeof(ggml_fp16_t) + QK_K / 4 + QK_K / 8 + 2, "wrong q3_K block size/padding"); +#else +typedef struct { + uint8_t hmask[QK_K/8]; // quants - high bit + uint8_t qs[QK_K/4]; // quants - low 2 bits + uint8_t scales[12]; // scales, quantized with 6 bits + ggml_fp16_t d; // super-block scale +} block_q3_K; +static_assert(sizeof(block_q3_K) == sizeof(ggml_fp16_t) + QK_K / 4 + QK_K / 8 + 12, "wrong q3_K block size/padding"); +#endif + +// 4-bit quantization +// 8 blocks of 32 elements each +// weight is represented as x = a * q + b +// Effectively 4.5 bits per weight +#ifdef GGML_QKK_64 +typedef struct { + ggml_fp16_t d[2]; // super-block scales/mins + uint8_t scales[2]; // 4-bit block scales/mins + uint8_t qs[QK_K/2]; // 4--bit quants +} block_q4_K; +static_assert(sizeof(block_q4_K) == 2*sizeof(ggml_fp16_t) + QK_K/2 + 2, "wrong q4_K block size/padding"); +#else +typedef struct { + ggml_fp16_t d; // super-block scale for quantized scales + ggml_fp16_t dmin; // super-block scale for quantized mins + uint8_t scales[K_SCALE_SIZE]; // scales and mins, quantized with 6 bits + uint8_t qs[QK_K/2]; // 4--bit quants +} block_q4_K; +static_assert(sizeof(block_q4_K) == 2*sizeof(ggml_fp16_t) + K_SCALE_SIZE + QK_K/2, "wrong q4_K block size/padding"); +#endif + +// 5-bit quantization +// 8 blocks of 32 elements each +// weight is represented as x = a * q + b +// Effectively 5.5 bits per weight +#ifdef GGML_QKK_64 +typedef struct { + ggml_fp16_t d; // super-block scale + int8_t scales[QK_K/16]; // 8-bit block scales + uint8_t qh[QK_K/8]; // quants, high bit + uint8_t qs[QK_K/2]; // quants, low 4 bits +} block_q5_K; +static_assert(sizeof(block_q5_K) == sizeof(ggml_fp16_t) + QK_K/2 + QK_K/8 + QK_K/16, "wrong q5_K block size/padding"); +#else +typedef struct { + ggml_fp16_t d; // super-block scale for quantized scales + ggml_fp16_t dmin; // super-block scale for quantized mins + uint8_t scales[K_SCALE_SIZE]; // scales and mins, quantized with 6 bits + uint8_t qh[QK_K/8]; // quants, high bit + uint8_t qs[QK_K/2]; // quants, low 4 bits +} block_q5_K; +static_assert(sizeof(block_q5_K) == 2*sizeof(ggml_fp16_t) + K_SCALE_SIZE + QK_K/2 + QK_K/8, "wrong q5_K block size/padding"); +#endif + +// 6-bit quantization +// weight is represented as x = a * q +// 16 blocks of 16 elements each +// Effectively 6.5625 bits per weight +typedef struct { + uint8_t ql[QK_K/2]; // quants, lower 4 bits + uint8_t qh[QK_K/4]; // quants, upper 2 bits + int8_t scales[QK_K/16]; // scales, quantized with 8 bits + ggml_fp16_t d; // super-block scale +} block_q6_K; +static_assert(sizeof(block_q6_K) == sizeof(ggml_fp16_t) + QK_K / 16 + 3*QK_K/4, "wrong q6_K block size/padding"); + +// This is only used for intermediate quantization and dot products +typedef struct { + float d; // delta + int8_t qs[QK_K]; // quants + int16_t bsums[QK_K/16]; // sum of quants in groups of 16 +} block_q8_K; +static_assert(sizeof(block_q8_K) == sizeof(float) + QK_K + QK_K/16*sizeof(int16_t), "wrong q8_K block size/padding"); + + +// Quantization +void quantize_row_q4_0_reference(const float * restrict x, block_q4_0 * restrict y, int k); +void quantize_row_q4_1_reference(const float * restrict x, block_q4_1 * restrict y, int k); +void quantize_row_q5_0_reference(const float * restrict x, block_q5_0 * restrict y, int k); +void quantize_row_q5_1_reference(const float * restrict x, block_q5_1 * restrict y, int k); +void quantize_row_q8_0_reference(const float * restrict x, block_q8_0 * restrict y, int k); +void quantize_row_q8_1_reference(const float * restrict x, block_q8_1 * restrict y, int k); + +void quantize_row_q2_K_reference(const float * restrict x, block_q2_K * restrict y, int k); +void quantize_row_q3_K_reference(const float * restrict x, block_q3_K * restrict y, int k); +void quantize_row_q4_K_reference(const float * restrict x, block_q4_K * restrict y, int k); +void quantize_row_q5_K_reference(const float * restrict x, block_q5_K * restrict y, int k); +void quantize_row_q6_K_reference(const float * restrict x, block_q6_K * restrict y, int k); +void quantize_row_q8_K_reference(const float * restrict x, block_q8_K * restrict y, int k); + +void quantize_row_q4_0(const float * restrict x, void * restrict y, int k); +void quantize_row_q4_1(const float * restrict x, void * restrict y, int k); +void quantize_row_q5_0(const float * restrict x, void * restrict y, int k); +void quantize_row_q5_1(const float * restrict x, void * restrict y, int k); +void quantize_row_q8_0(const float * restrict x, void * restrict y, int k); +void quantize_row_q8_1(const float * restrict x, void * restrict y, int k); + +void quantize_row_q2_K(const float * restrict x, void * restrict y, int k); +void quantize_row_q3_K(const float * restrict x, void * restrict y, int k); +void quantize_row_q4_K(const float * restrict x, void * restrict y, int k); +void quantize_row_q5_K(const float * restrict x, void * restrict y, int k); +void quantize_row_q6_K(const float * restrict x, void * restrict y, int k); +void quantize_row_q8_K(const float * restrict x, void * restrict y, int k); + +// Dequantization +void dequantize_row_q4_0(const block_q4_0 * restrict x, float * restrict y, int k); +void dequantize_row_q4_1(const block_q4_1 * restrict x, float * restrict y, int k); +void dequantize_row_q5_0(const block_q5_0 * restrict x, float * restrict y, int k); +void dequantize_row_q5_1(const block_q5_1 * restrict x, float * restrict y, int k); +void dequantize_row_q8_0(const block_q8_0 * restrict x, float * restrict y, int k); +//void dequantize_row_q8_1(const block_q8_1 * restrict x, float * restrict y, int k); + +void dequantize_row_q2_K(const block_q2_K * restrict x, float * restrict y, int k); +void dequantize_row_q3_K(const block_q3_K * restrict x, float * restrict y, int k); +void dequantize_row_q4_K(const block_q4_K * restrict x, float * restrict y, int k); +void dequantize_row_q5_K(const block_q5_K * restrict x, float * restrict y, int k); +void dequantize_row_q6_K(const block_q6_K * restrict x, float * restrict y, int k); +void dequantize_row_q8_K(const block_q8_K * restrict x, float * restrict y, int k); + +// Dot product +void ggml_vec_dot_q4_0_q8_0(int n, float * restrict s, const void * restrict vx, const void * restrict vy); +void ggml_vec_dot_q4_1_q8_1(int n, float * restrict s, const void * restrict vx, const void * restrict vy); +void ggml_vec_dot_q5_0_q8_0(int n, float * restrict s, const void * restrict vx, const void * restrict vy); +void ggml_vec_dot_q5_1_q8_1(int n, float * restrict s, const void * restrict vx, const void * restrict vy); +void ggml_vec_dot_q8_0_q8_0(int n, float * restrict s, const void * restrict vx, const void * restrict vy); + +void ggml_vec_dot_q2_K_q8_K(int n, float * restrict s, const void * restrict vx, const void * restrict vy); +void ggml_vec_dot_q3_K_q8_K(int n, float * restrict s, const void * restrict vx, const void * restrict vy); +void ggml_vec_dot_q4_K_q8_K(int n, float * restrict s, const void * restrict vx, const void * restrict vy); +void ggml_vec_dot_q5_K_q8_K(int n, float * restrict s, const void * restrict vx, const void * restrict vy); +void ggml_vec_dot_q6_K_q8_K(int n, float * restrict s, const void * restrict vx, const void * restrict vy); diff --git a/sys/whisper.cpp/bindings/ruby/ext/ruby_whisper.cpp b/sys/whisper.cpp/bindings/ruby/ext/ruby_whisper.cpp new file mode 100644 index 0000000..86af939 --- /dev/null +++ b/sys/whisper.cpp/bindings/ruby/ext/ruby_whisper.cpp @@ -0,0 +1,426 @@ +#include +#include "ruby_whisper.h" +#define DR_WAV_IMPLEMENTATION +#include "dr_wav.h" +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define BOOL_PARAMS_SETTER(self, prop, value) \ + ruby_whisper_params *rwp; \ + Data_Get_Struct(self, ruby_whisper_params, rwp); \ + if (value == Qfalse || value == Qnil) { \ + rwp->params.prop = false; \ + } else { \ + rwp->params.prop = true; \ + } \ + return value; \ + +#define BOOL_PARAMS_GETTER(self, prop) \ + ruby_whisper_params *rwp; \ + Data_Get_Struct(self, ruby_whisper_params, rwp); \ + if (rwp->params.prop) { \ + return Qtrue; \ + } else { \ + return Qfalse; \ + } + +VALUE mWhisper; +VALUE cContext; +VALUE cParams; + +static void ruby_whisper_free(ruby_whisper *rw) { + if (rw->context) { + whisper_free(rw->context); + rw->context = NULL; + } +} +static void ruby_whisper_params_free(ruby_whisper_params *rwp) { +} + +void rb_whisper_mark(ruby_whisper *rw) { + // call rb_gc_mark on any ruby references in rw +} + +void rb_whisper_free(ruby_whisper *rw) { + ruby_whisper_free(rw); + free(rw); +} + +void rb_whisper_params_mark(ruby_whisper_params *rwp) { +} + +void rb_whisper_params_free(ruby_whisper_params *rwp) { + ruby_whisper_params_free(rwp); + free(rwp); +} + +static VALUE ruby_whisper_allocate(VALUE klass) { + ruby_whisper *rw; + rw = ALLOC(ruby_whisper); + rw->context = NULL; + return Data_Wrap_Struct(klass, rb_whisper_mark, rb_whisper_free, rw); +} + +static VALUE ruby_whisper_params_allocate(VALUE klass) { + ruby_whisper_params *rwp; + rwp = ALLOC(ruby_whisper_params); + rwp->params = whisper_full_default_params(WHISPER_SAMPLING_GREEDY); + return Data_Wrap_Struct(klass, rb_whisper_params_mark, rb_whisper_params_free, rwp); +} + +static VALUE ruby_whisper_initialize(int argc, VALUE *argv, VALUE self) { + ruby_whisper *rw; + VALUE whisper_model_file_path; + + // TODO: we can support init from buffer here too maybe another ruby object to expose + rb_scan_args(argc, argv, "01", &whisper_model_file_path); + Data_Get_Struct(self, ruby_whisper, rw); + + if (!rb_respond_to(whisper_model_file_path, rb_intern("to_s"))) { + rb_raise(rb_eRuntimeError, "Expected file path to model to initialize Whisper::Context"); + } + rw->context = whisper_init_from_file_with_params(StringValueCStr(whisper_model_file_path), whisper_context_default_params()); + if (rw->context == nullptr) { + rb_raise(rb_eRuntimeError, "error: failed to initialize whisper context"); + } + return self; +} + +/* + * transcribe a single file + * can emit to a block results + * + **/ +static VALUE ruby_whisper_transcribe(int argc, VALUE *argv, VALUE self) { + ruby_whisper *rw; + ruby_whisper_params *rwp; + VALUE wave_file_path, blk, params; + + rb_scan_args(argc, argv, "02&", &wave_file_path, ¶ms, &blk); + Data_Get_Struct(self, ruby_whisper, rw); + Data_Get_Struct(params, ruby_whisper_params, rwp); + + if (!rb_respond_to(wave_file_path, rb_intern("to_s"))) { + rb_raise(rb_eRuntimeError, "Expected file path to wave file"); + } + + std::string fname_inp = StringValueCStr(wave_file_path); + + std::vector pcmf32; // mono-channel F32 PCM + std::vector> pcmf32s; // stereo-channel F32 PCM + + // WAV input - this is directly from main.cpp example + { + drwav wav; + std::vector wav_data; // used for pipe input from stdin + + if (fname_inp == "-") { + { + uint8_t buf[1024]; + while (true) { + const size_t n = fread(buf, 1, sizeof(buf), stdin); + if (n == 0) { + break; + } + wav_data.insert(wav_data.end(), buf, buf + n); + } + } + + if (drwav_init_memory(&wav, wav_data.data(), wav_data.size(), nullptr) == false) { + fprintf(stderr, "error: failed to open WAV file from stdin\n"); + return self; + } + + fprintf(stderr, "%s: read %zu bytes from stdin\n", __func__, wav_data.size()); + } else if (drwav_init_file(&wav, fname_inp.c_str(), nullptr) == false) { + fprintf(stderr, "error: failed to open '%s' as WAV file\n", fname_inp.c_str()); + return self; + } + + if (wav.channels != 1 && wav.channels != 2) { + fprintf(stderr, "WAV file '%s' must be mono or stereo\n", fname_inp.c_str()); + return self; + } + + if (rwp->diarize && wav.channels != 2 && rwp->params.print_timestamps == false) { + fprintf(stderr, "WAV file '%s' must be stereo for diarization and timestamps have to be enabled\n", fname_inp.c_str()); + return self; + } + + if (wav.sampleRate != WHISPER_SAMPLE_RATE) { + fprintf(stderr, "WAV file '%s' must be %i kHz\n", fname_inp.c_str(), WHISPER_SAMPLE_RATE/1000); + return self; + } + + if (wav.bitsPerSample != 16) { + fprintf(stderr, "WAV file '%s' must be 16-bit\n", fname_inp.c_str()); + return self; + } + + const uint64_t n = wav_data.empty() ? wav.totalPCMFrameCount : wav_data.size()/(wav.channels*wav.bitsPerSample/8); + + std::vector pcm16; + pcm16.resize(n*wav.channels); + drwav_read_pcm_frames_s16(&wav, n, pcm16.data()); + drwav_uninit(&wav); + + // convert to mono, float + pcmf32.resize(n); + if (wav.channels == 1) { + for (uint64_t i = 0; i < n; i++) { + pcmf32[i] = float(pcm16[i])/32768.0f; + } + } else { + for (uint64_t i = 0; i < n; i++) { + pcmf32[i] = float(pcm16[2*i] + pcm16[2*i + 1])/65536.0f; + } + } + + if (rwp->diarize) { + // convert to stereo, float + pcmf32s.resize(2); + + pcmf32s[0].resize(n); + pcmf32s[1].resize(n); + for (uint64_t i = 0; i < n; i++) { + pcmf32s[0][i] = float(pcm16[2*i])/32768.0f; + pcmf32s[1][i] = float(pcm16[2*i + 1])/32768.0f; + } + } + } + { + static bool is_aborted = false; // NOTE: this should be atomic to avoid data race + + rwp->params.encoder_begin_callback = [](struct whisper_context * /*ctx*/, struct whisper_state * /*state*/, void * user_data) { + bool is_aborted = *(bool*)user_data; + return !is_aborted; + }; + rwp->params.encoder_begin_callback_user_data = &is_aborted; + } + + if (whisper_full_parallel(rw->context, rwp->params, pcmf32.data(), pcmf32.size(), 1) != 0) { + fprintf(stderr, "failed to process audio\n"); + return self; + } + const int n_segments = whisper_full_n_segments(rw->context); + VALUE output = rb_str_new2(""); + for (int i = 0; i < n_segments; ++i) { + const char * text = whisper_full_get_segment_text(rw->context, i); + output = rb_str_concat(output, rb_str_new2(text)); + } + VALUE idCall = rb_intern("call"); + if (blk != Qnil) { + rb_funcall(blk, idCall, 1, output); + } + return self; +} + +/* + * params.language = "auto" | "en", etc... + */ +static VALUE ruby_whisper_params_set_language(VALUE self, VALUE value) { + ruby_whisper_params *rwp; + Data_Get_Struct(self, ruby_whisper_params, rwp); + if (value == Qfalse || value == Qnil) { + rwp->params.language = "auto"; + } else { + rwp->params.language = StringValueCStr(value); + } + return value; +} +static VALUE ruby_whisper_params_get_language(VALUE self) { + ruby_whisper_params *rwp; + Data_Get_Struct(self, ruby_whisper_params, rwp); + if (rwp->params.language) { + return rb_str_new2(rwp->params.language); + } else { + return rb_str_new2("auto"); + } +} +static VALUE ruby_whisper_params_set_translate(VALUE self, VALUE value) { + BOOL_PARAMS_SETTER(self, translate, value) +} +static VALUE ruby_whisper_params_get_translate(VALUE self) { + BOOL_PARAMS_GETTER(self, translate) +} +static VALUE ruby_whisper_params_set_no_context(VALUE self, VALUE value) { + BOOL_PARAMS_SETTER(self, no_context, value) +} +static VALUE ruby_whisper_params_get_no_context(VALUE self) { + BOOL_PARAMS_GETTER(self, no_context) +} +static VALUE ruby_whisper_params_set_single_segment(VALUE self, VALUE value) { + BOOL_PARAMS_SETTER(self, single_segment, value) +} +static VALUE ruby_whisper_params_get_single_segment(VALUE self) { + BOOL_PARAMS_GETTER(self, single_segment) +} +static VALUE ruby_whisper_params_set_print_special(VALUE self, VALUE value) { + BOOL_PARAMS_SETTER(self, print_special, value) +} +static VALUE ruby_whisper_params_get_print_special(VALUE self) { + BOOL_PARAMS_GETTER(self, print_special) +} +static VALUE ruby_whisper_params_set_print_progress(VALUE self, VALUE value) { + BOOL_PARAMS_SETTER(self, print_progress, value) +} +static VALUE ruby_whisper_params_get_print_progress(VALUE self) { + BOOL_PARAMS_GETTER(self, print_progress) +} +static VALUE ruby_whisper_params_set_print_realtime(VALUE self, VALUE value) { + BOOL_PARAMS_SETTER(self, print_realtime, value) +} +static VALUE ruby_whisper_params_get_print_realtime(VALUE self) { + BOOL_PARAMS_GETTER(self, print_realtime) +} +static VALUE ruby_whisper_params_set_print_timestamps(VALUE self, VALUE value) { + BOOL_PARAMS_SETTER(self, print_timestamps, value) +} +static VALUE ruby_whisper_params_get_print_timestamps(VALUE self) { + BOOL_PARAMS_GETTER(self, print_timestamps) +} +static VALUE ruby_whisper_params_set_suppress_blank(VALUE self, VALUE value) { + BOOL_PARAMS_SETTER(self, suppress_blank, value) +} +static VALUE ruby_whisper_params_get_suppress_blank(VALUE self) { + BOOL_PARAMS_GETTER(self, suppress_blank) +} +static VALUE ruby_whisper_params_set_suppress_non_speech_tokens(VALUE self, VALUE value) { + BOOL_PARAMS_SETTER(self, suppress_non_speech_tokens, value) +} +static VALUE ruby_whisper_params_get_suppress_non_speech_tokens(VALUE self) { + BOOL_PARAMS_GETTER(self, suppress_non_speech_tokens) +} +static VALUE ruby_whisper_params_get_token_timestamps(VALUE self) { + BOOL_PARAMS_GETTER(self, token_timestamps) +} +static VALUE ruby_whisper_params_set_token_timestamps(VALUE self, VALUE value) { + BOOL_PARAMS_SETTER(self, token_timestamps, value) +} +static VALUE ruby_whisper_params_get_split_on_word(VALUE self) { + BOOL_PARAMS_GETTER(self, split_on_word) +} +static VALUE ruby_whisper_params_set_split_on_word(VALUE self, VALUE value) { + BOOL_PARAMS_SETTER(self, split_on_word, value) +} +static VALUE ruby_whisper_params_get_speed_up(VALUE self) { + BOOL_PARAMS_GETTER(self, speed_up) +} +static VALUE ruby_whisper_params_set_speed_up(VALUE self, VALUE value) { + BOOL_PARAMS_SETTER(self, speed_up, value) +} +static VALUE ruby_whisper_params_get_diarize(VALUE self) { + ruby_whisper_params *rwp; + Data_Get_Struct(self, ruby_whisper_params, rwp); + if (rwp->diarize) { + return Qtrue; + } else { + return Qfalse; + } +} +static VALUE ruby_whisper_params_set_diarize(VALUE self, VALUE value) { + ruby_whisper_params *rwp; + Data_Get_Struct(self, ruby_whisper_params, rwp); + if (value == Qfalse || value == Qnil) { + rwp->diarize = false; + } else { + rwp->diarize = true; + } \ + return value; +} + +static VALUE ruby_whisper_params_get_offset(VALUE self) { + ruby_whisper_params *rwp; + Data_Get_Struct(self, ruby_whisper_params, rwp); + return INT2NUM(rwp->params.offset_ms); +} +static VALUE ruby_whisper_params_set_offset(VALUE self, VALUE value) { + ruby_whisper_params *rwp; + Data_Get_Struct(self, ruby_whisper_params, rwp); + rwp->params.offset_ms = NUM2INT(value); + return value; +} +static VALUE ruby_whisper_params_get_duration(VALUE self) { + ruby_whisper_params *rwp; + Data_Get_Struct(self, ruby_whisper_params, rwp); + return INT2NUM(rwp->params.duration_ms); +} +static VALUE ruby_whisper_params_set_duration(VALUE self, VALUE value) { + ruby_whisper_params *rwp; + Data_Get_Struct(self, ruby_whisper_params, rwp); + rwp->params.duration_ms = NUM2INT(value); + return value; +} + +static VALUE ruby_whisper_params_get_max_text_tokens(VALUE self) { + ruby_whisper_params *rwp; + Data_Get_Struct(self, ruby_whisper_params, rwp); + return INT2NUM(rwp->params.n_max_text_ctx); +} +static VALUE ruby_whisper_params_set_max_text_tokens(VALUE self, VALUE value) { + ruby_whisper_params *rwp; + Data_Get_Struct(self, ruby_whisper_params, rwp); + rwp->params.n_max_text_ctx = NUM2INT(value); + return value; +} + +void Init_whisper() { + mWhisper = rb_define_module("Whisper"); + cContext = rb_define_class_under(mWhisper, "Context", rb_cObject); + cParams = rb_define_class_under(mWhisper, "Params", rb_cObject); + + rb_define_alloc_func(cContext, ruby_whisper_allocate); + rb_define_method(cContext, "initialize", ruby_whisper_initialize, -1); + + rb_define_method(cContext, "transcribe", ruby_whisper_transcribe, -1); + + rb_define_alloc_func(cParams, ruby_whisper_params_allocate); + + rb_define_method(cParams, "language=", ruby_whisper_params_set_language, 1); + rb_define_method(cParams, "language", ruby_whisper_params_get_language, 0); + rb_define_method(cParams, "translate=", ruby_whisper_params_set_translate, 1); + rb_define_method(cParams, "translate", ruby_whisper_params_get_translate, 0); + rb_define_method(cParams, "no_context=", ruby_whisper_params_set_no_context, 1); + rb_define_method(cParams, "no_context", ruby_whisper_params_get_no_context, 0); + rb_define_method(cParams, "single_segment=", ruby_whisper_params_set_single_segment, 1); + rb_define_method(cParams, "single_segment", ruby_whisper_params_get_single_segment, 0); + rb_define_method(cParams, "print_special", ruby_whisper_params_get_print_special, 0); + rb_define_method(cParams, "print_special=", ruby_whisper_params_set_print_special, 1); + rb_define_method(cParams, "print_progress", ruby_whisper_params_get_print_progress, 0); + rb_define_method(cParams, "print_progress=", ruby_whisper_params_set_print_progress, 1); + rb_define_method(cParams, "print_realtime", ruby_whisper_params_get_print_realtime, 0); + rb_define_method(cParams, "print_realtime=", ruby_whisper_params_set_print_realtime, 1); + rb_define_method(cParams, "print_timestamps", ruby_whisper_params_get_print_timestamps, 0); + rb_define_method(cParams, "print_timestamps=", ruby_whisper_params_set_print_timestamps, 1); + rb_define_method(cParams, "suppress_blank", ruby_whisper_params_get_suppress_blank, 0); + rb_define_method(cParams, "suppress_blank=", ruby_whisper_params_set_suppress_blank, 1); + rb_define_method(cParams, "suppress_non_speech_tokens", ruby_whisper_params_get_suppress_non_speech_tokens, 0); + rb_define_method(cParams, "suppress_non_speech_tokens=", ruby_whisper_params_set_suppress_non_speech_tokens, 1); + rb_define_method(cParams, "token_timestamps", ruby_whisper_params_get_token_timestamps, 0); + rb_define_method(cParams, "token_timestamps=", ruby_whisper_params_set_token_timestamps, 1); + rb_define_method(cParams, "split_on_word", ruby_whisper_params_get_split_on_word, 0); + rb_define_method(cParams, "split_on_word=", ruby_whisper_params_set_split_on_word, 1); + rb_define_method(cParams, "speed_up", ruby_whisper_params_get_speed_up, 0); + rb_define_method(cParams, "speed_up=", ruby_whisper_params_set_speed_up, 1); + rb_define_method(cParams, "diarize", ruby_whisper_params_get_diarize, 0); + rb_define_method(cParams, "diarize=", ruby_whisper_params_set_diarize, 1); + + rb_define_method(cParams, "offset", ruby_whisper_params_get_offset, 0); + rb_define_method(cParams, "offset=", ruby_whisper_params_set_offset, 1); + rb_define_method(cParams, "duration", ruby_whisper_params_get_duration, 0); + rb_define_method(cParams, "duration=", ruby_whisper_params_set_duration, 1); + + rb_define_method(cParams, "max_text_tokens", ruby_whisper_params_get_max_text_tokens, 0); + rb_define_method(cParams, "max_text_tokens=", ruby_whisper_params_set_max_text_tokens, 1); +} +#ifdef __cplusplus +} +#endif diff --git a/sys/whisper.cpp/bindings/ruby/ext/ruby_whisper.h b/sys/whisper.cpp/bindings/ruby/ext/ruby_whisper.h new file mode 100644 index 0000000..8c35b7c --- /dev/null +++ b/sys/whisper.cpp/bindings/ruby/ext/ruby_whisper.h @@ -0,0 +1,15 @@ +#ifndef __RUBY_WHISPER_H +#define __RUBY_WHISPER_H + +#include "whisper.h" + +typedef struct { + struct whisper_context *context; +} ruby_whisper; + +typedef struct { + struct whisper_full_params params; + bool diarize; +} ruby_whisper_params; + +#endif diff --git a/sys/whisper.cpp/bindings/ruby/tests/test_whisper.rb b/sys/whisper.cpp/bindings/ruby/tests/test_whisper.rb new file mode 100644 index 0000000..fa6a3e2 --- /dev/null +++ b/sys/whisper.cpp/bindings/ruby/tests/test_whisper.rb @@ -0,0 +1,138 @@ +TOPDIR = File.expand_path(File.join(File.dirname(__FILE__), '..')) +EXTDIR = File.join(TOPDIR, 'ext') +#$LIBDIR = File.join(TOPDIR, 'lib') +#$:.unshift(LIBDIR) +$:.unshift(EXTDIR) + +require 'whisper' +require 'test/unit' + +class TestWhisper < Test::Unit::TestCase + def setup + @params = Whisper::Params.new + end + + def test_language + @params.language = "en" + assert_equal @params.language, "en" + @params.language = "auto" + assert_equal @params.language, "auto" + end + + def test_offset + @params.offset = 10_000 + assert_equal @params.offset, 10_000 + @params.offset = 0 + assert_equal @params.offset, 0 + end + + def test_duration + @params.duration = 60_000 + assert_equal @params.duration, 60_000 + @params.duration = 0 + assert_equal @params.duration, 0 + end + + def test_max_text_tokens + @params.max_text_tokens = 300 + assert_equal @params.max_text_tokens, 300 + @params.max_text_tokens = 0 + assert_equal @params.max_text_tokens, 0 + end + + def test_translate + @params.translate = true + assert @params.translate + @params.translate = false + assert !@params.translate + end + + def test_no_context + @params.no_context = true + assert @params.no_context + @params.no_context = false + assert !@params.no_context + end + + def test_single_segment + @params.single_segment = true + assert @params.single_segment + @params.single_segment = false + assert !@params.single_segment + end + + def test_print_special + @params.print_special = true + assert @params.print_special + @params.print_special = false + assert !@params.print_special + end + + def test_print_progress + @params.print_progress = true + assert @params.print_progress + @params.print_progress = false + assert !@params.print_progress + end + + def test_print_realtime + @params.print_realtime = true + assert @params.print_realtime + @params.print_realtime = false + assert !@params.print_realtime + end + + def test_print_timestamps + @params.print_timestamps = true + assert @params.print_timestamps + @params.print_timestamps = false + assert !@params.print_timestamps + end + + def test_suppress_blank + @params.suppress_blank = true + assert @params.suppress_blank + @params.suppress_blank = false + assert !@params.suppress_blank + end + + def test_suppress_non_speech_tokens + @params.suppress_non_speech_tokens = true + assert @params.suppress_non_speech_tokens + @params.suppress_non_speech_tokens = false + assert !@params.suppress_non_speech_tokens + end + + def test_token_timestamps + @params.token_timestamps = true + assert @params.token_timestamps + @params.token_timestamps = false + assert !@params.token_timestamps + end + + def test_split_on_word + @params.split_on_word = true + assert @params.split_on_word + @params.split_on_word = false + assert !@params.split_on_word + end + + def test_speed_up + @params.speed_up = true + assert @params.speed_up + @params.speed_up = false + assert !@params.speed_up + end + + def test_whisper + @whisper = Whisper::Context.new(File.join(TOPDIR, '..', '..', 'models', 'ggml-base.en.bin')) + params = Whisper::Params.new + params.print_timestamps = false + + jfk = File.join(TOPDIR, '..', '..', 'samples', 'jfk.wav') + @whisper.transcribe(jfk, params) {|text| + assert_match /ask not what your country can do for you, ask what you can do for your country/, text + } + end + +end diff --git a/sys/whisper.cpp/cmake/BuildTypes.cmake b/sys/whisper.cpp/cmake/BuildTypes.cmake new file mode 100644 index 0000000..a9c7b6c --- /dev/null +++ b/sys/whisper.cpp/cmake/BuildTypes.cmake @@ -0,0 +1,54 @@ +# Add new build types + +# ReleaseGG - Release with enabled asserts + +SET(CMAKE_CXX_FLAGS_RELEASEGG + "-O3" + CACHE STRING "Flags used by the c++ compiler during release builds with enabled asserts." + FORCE ) +SET(CMAKE_C_FLAGS_RELEASEGG + "-O3" + CACHE STRING "Flags used by the compiler during release builds with enabled asserts." + FORCE ) +SET(CMAKE_EXE_LINKER_FLAGS_RELEASEGG + "" + CACHE STRING "Flags used for linking binaries during release builds with enabled asserts." + FORCE ) +SET(CMAKE_SHARED_LINKER_FLAGS_RELEASEGG + "" + CACHE STRING "Flags used by the shared libraries linker during release builds with enabled asserts." + FORCE ) +MARK_AS_ADVANCED( + CMAKE_CXX_FLAGS_RELEASEGG + CMAKE_C_FLAGS_RELEASEGG + CMAKE_EXE_LINKER_FLAGS_RELEASEGG + CMAKE_SHARED_LINKER_FLAGS_RELEASEGG ) + +# RelWithDebInfoGG - RelWithDebInfo with enabled asserts + +SET(CMAKE_CXX_FLAGS_RELWITHDEBINFOGG + "-O2 -g" + CACHE STRING "Flags used by the c++ compiler during release builds with debug symbols and enabled asserts." + FORCE ) +SET(CMAKE_C_FLAGS_RELWITHDEBINFOGG + "-O2 -g" + CACHE STRING "Flags used by the compiler during release builds with debug symbols and enabled asserts." + FORCE ) +SET(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFOGG + "" + CACHE STRING "Flags used for linking binaries during release builds with debug symbols and enabled asserts." + FORCE ) +SET(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFOGG + "" + CACHE STRING "Flags used by the shared libraries linker during release builds with debug symbols and enabled asserts." + FORCE ) +MARK_AS_ADVANCED( + CMAKE_CXX_FLAGS_RELWITHDEBINFOGG + CMAKE_C_FLAGS_RELWITHDEBINFOGG + CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFOGG + CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFOGG ) + +if (NOT XCODE AND NOT MSVC AND NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE) + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo" "ReleaseGG" "RelWithDebInfoGG") +endif() diff --git a/sys/whisper.cpp/cmake/DefaultTargetOptions.cmake b/sys/whisper.cpp/cmake/DefaultTargetOptions.cmake new file mode 100644 index 0000000..b4e93e3 --- /dev/null +++ b/sys/whisper.cpp/cmake/DefaultTargetOptions.cmake @@ -0,0 +1,17 @@ +# Set the default compile features and properties for a target. + +if (NOT TARGET) + message(FATAL_ERROR "TARGET not set before including DefaultTargetOptions") +endif() + +target_compile_features(${TARGET} + PRIVATE + cxx_std_11 + ) + +set_target_properties(${TARGET} + PROPERTIES + EXPORT_COMPILE_COMMANDS ON + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin" + INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib" +) diff --git a/sys/whisper.cpp/cmake/GitVars.cmake b/sys/whisper.cpp/cmake/GitVars.cmake new file mode 100644 index 0000000..1a4c24e --- /dev/null +++ b/sys/whisper.cpp/cmake/GitVars.cmake @@ -0,0 +1,22 @@ +find_package(Git) + +# the commit's SHA1 +execute_process(COMMAND + "${GIT_EXECUTABLE}" describe --match=NeVeRmAtCh --always --abbrev=8 + WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" + OUTPUT_VARIABLE GIT_SHA1 + ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) + +# the date of the commit +execute_process(COMMAND + "${GIT_EXECUTABLE}" log -1 --format=%ad --date=local + WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" + OUTPUT_VARIABLE GIT_DATE + ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) + +# the subject of the commit +execute_process(COMMAND + "${GIT_EXECUTABLE}" log -1 --format=%s + WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" + OUTPUT_VARIABLE GIT_COMMIT_SUBJECT + ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) diff --git a/sys/whisper.cpp/coreml/whisper-decoder-impl.h b/sys/whisper.cpp/coreml/whisper-decoder-impl.h new file mode 100644 index 0000000..c6f2e85 --- /dev/null +++ b/sys/whisper.cpp/coreml/whisper-decoder-impl.h @@ -0,0 +1,146 @@ +// +// whisper-decoder-impl.h +// +// This file was automatically generated and should not be edited. +// + +#import +#import +#include +#include + +NS_ASSUME_NONNULL_BEGIN + + +/// Model Prediction Input Type +API_AVAILABLE(macos(12.0), ios(15.0), watchos(8.0), tvos(15.0)) __attribute__((visibility("hidden"))) +@interface whisper_decoder_implInput : NSObject + +/// token_data as 1 by 1 matrix of 32-bit integers +@property (readwrite, nonatomic, strong) MLMultiArray * token_data; + +/// audio_data as 1 × 384 × 1 × 1500 4-dimensional array of floats +@property (readwrite, nonatomic, strong) MLMultiArray * audio_data; +- (instancetype)init NS_UNAVAILABLE; +- (instancetype)initWithToken_data:(MLMultiArray *)token_data audio_data:(MLMultiArray *)audio_data NS_DESIGNATED_INITIALIZER; + +@end + + +/// Model Prediction Output Type +API_AVAILABLE(macos(12.0), ios(15.0), watchos(8.0), tvos(15.0)) __attribute__((visibility("hidden"))) +@interface whisper_decoder_implOutput : NSObject + +/// var_1346 as multidimensional array of floats +@property (readwrite, nonatomic, strong) MLMultiArray * var_1346; +- (instancetype)init NS_UNAVAILABLE; +- (instancetype)initWithVar_1346:(MLMultiArray *)var_1346 NS_DESIGNATED_INITIALIZER; + +@end + + +/// Class for model loading and prediction +API_AVAILABLE(macos(12.0), ios(15.0), watchos(8.0), tvos(15.0)) __attribute__((visibility("hidden"))) +@interface whisper_decoder_impl : NSObject +@property (readonly, nonatomic, nullable) MLModel * model; + +/** + URL of the underlying .mlmodelc directory. +*/ ++ (nullable NSURL *)URLOfModelInThisBundle; + +/** + Initialize whisper_decoder_impl instance from an existing MLModel object. + + Usually the application does not use this initializer unless it makes a subclass of whisper_decoder_impl. + Such application may want to use `-[MLModel initWithContentsOfURL:configuration:error:]` and `+URLOfModelInThisBundle` to create a MLModel object to pass-in. +*/ +- (instancetype)initWithMLModel:(MLModel *)model NS_DESIGNATED_INITIALIZER; + +/** + Initialize whisper_decoder_impl instance with the model in this bundle. +*/ +- (nullable instancetype)init; + +/** + Initialize whisper_decoder_impl instance with the model in this bundle. + + @param configuration The model configuration object + @param error If an error occurs, upon return contains an NSError object that describes the problem. If you are not interested in possible errors, pass in NULL. +*/ +- (nullable instancetype)initWithConfiguration:(MLModelConfiguration *)configuration error:(NSError * _Nullable __autoreleasing * _Nullable)error; + +/** + Initialize whisper_decoder_impl instance from the model URL. + + @param modelURL URL to the .mlmodelc directory for whisper_decoder_impl. + @param error If an error occurs, upon return contains an NSError object that describes the problem. If you are not interested in possible errors, pass in NULL. +*/ +- (nullable instancetype)initWithContentsOfURL:(NSURL *)modelURL error:(NSError * _Nullable __autoreleasing * _Nullable)error; + +/** + Initialize whisper_decoder_impl instance from the model URL. + + @param modelURL URL to the .mlmodelc directory for whisper_decoder_impl. + @param configuration The model configuration object + @param error If an error occurs, upon return contains an NSError object that describes the problem. If you are not interested in possible errors, pass in NULL. +*/ +- (nullable instancetype)initWithContentsOfURL:(NSURL *)modelURL configuration:(MLModelConfiguration *)configuration error:(NSError * _Nullable __autoreleasing * _Nullable)error; + +/** + Construct whisper_decoder_impl instance asynchronously with configuration. + Model loading may take time when the model content is not immediately available (e.g. encrypted model). Use this factory method especially when the caller is on the main thread. + + @param configuration The model configuration + @param handler When the model load completes successfully or unsuccessfully, the completion handler is invoked with a valid whisper_decoder_impl instance or NSError object. +*/ ++ (void)loadWithConfiguration:(MLModelConfiguration *)configuration completionHandler:(void (^)(whisper_decoder_impl * _Nullable model, NSError * _Nullable error))handler; + +/** + Construct whisper_decoder_impl instance asynchronously with URL of .mlmodelc directory and optional configuration. + + Model loading may take time when the model content is not immediately available (e.g. encrypted model). Use this factory method especially when the caller is on the main thread. + + @param modelURL The model URL. + @param configuration The model configuration + @param handler When the model load completes successfully or unsuccessfully, the completion handler is invoked with a valid whisper_decoder_impl instance or NSError object. +*/ ++ (void)loadContentsOfURL:(NSURL *)modelURL configuration:(MLModelConfiguration *)configuration completionHandler:(void (^)(whisper_decoder_impl * _Nullable model, NSError * _Nullable error))handler; + +/** + Make a prediction using the standard interface + @param input an instance of whisper_decoder_implInput to predict from + @param error If an error occurs, upon return contains an NSError object that describes the problem. If you are not interested in possible errors, pass in NULL. + @return the prediction as whisper_decoder_implOutput +*/ +- (nullable whisper_decoder_implOutput *)predictionFromFeatures:(whisper_decoder_implInput *)input error:(NSError * _Nullable __autoreleasing * _Nullable)error; + +/** + Make a prediction using the standard interface + @param input an instance of whisper_decoder_implInput to predict from + @param options prediction options + @param error If an error occurs, upon return contains an NSError object that describes the problem. If you are not interested in possible errors, pass in NULL. + @return the prediction as whisper_decoder_implOutput +*/ +- (nullable whisper_decoder_implOutput *)predictionFromFeatures:(whisper_decoder_implInput *)input options:(MLPredictionOptions *)options error:(NSError * _Nullable __autoreleasing * _Nullable)error; + +/** + Make a prediction using the convenience interface + @param token_data as 1 by 1 matrix of 32-bit integers: + @param audio_data as 1 × 384 × 1 × 1500 4-dimensional array of floats: + @param error If an error occurs, upon return contains an NSError object that describes the problem. If you are not interested in possible errors, pass in NULL. + @return the prediction as whisper_decoder_implOutput +*/ +- (nullable whisper_decoder_implOutput *)predictionFromToken_data:(MLMultiArray *)token_data audio_data:(MLMultiArray *)audio_data error:(NSError * _Nullable __autoreleasing * _Nullable)error; + +/** + Batch prediction + @param inputArray array of whisper_decoder_implInput instances to obtain predictions from + @param options prediction options + @param error If an error occurs, upon return contains an NSError object that describes the problem. If you are not interested in possible errors, pass in NULL. + @return the predictions as NSArray +*/ +- (nullable NSArray *)predictionsFromInputs:(NSArray *)inputArray options:(MLPredictionOptions *)options error:(NSError * _Nullable __autoreleasing * _Nullable)error; +@end + +NS_ASSUME_NONNULL_END diff --git a/sys/whisper.cpp/coreml/whisper-decoder-impl.m b/sys/whisper.cpp/coreml/whisper-decoder-impl.m new file mode 100644 index 0000000..34060e4 --- /dev/null +++ b/sys/whisper.cpp/coreml/whisper-decoder-impl.m @@ -0,0 +1,201 @@ +// +// whisper-decoder-impl.m +// +// This file was automatically generated and should not be edited. +// + +#if !__has_feature(objc_arc) +#error This file must be compiled with automatic reference counting enabled (-fobjc-arc) +#endif + +#import "whisper-decoder-impl.h" + +@implementation whisper_decoder_implInput + +- (instancetype)initWithToken_data:(MLMultiArray *)token_data audio_data:(MLMultiArray *)audio_data { + self = [super init]; + if (self) { + _token_data = token_data; + _audio_data = audio_data; + } + return self; +} + +- (NSSet *)featureNames { + return [NSSet setWithArray:@[@"token_data", @"audio_data"]]; +} + +- (nullable MLFeatureValue *)featureValueForName:(NSString *)featureName { + if ([featureName isEqualToString:@"token_data"]) { + return [MLFeatureValue featureValueWithMultiArray:self.token_data]; + } + if ([featureName isEqualToString:@"audio_data"]) { + return [MLFeatureValue featureValueWithMultiArray:self.audio_data]; + } + return nil; +} + +@end + +@implementation whisper_decoder_implOutput + +- (instancetype)initWithVar_1346:(MLMultiArray *)var_1346 { + self = [super init]; + if (self) { + _var_1346 = var_1346; + } + return self; +} + +- (NSSet *)featureNames { + return [NSSet setWithArray:@[@"var_1346"]]; +} + +- (nullable MLFeatureValue *)featureValueForName:(NSString *)featureName { + if ([featureName isEqualToString:@"var_1346"]) { + return [MLFeatureValue featureValueWithMultiArray:self.var_1346]; + } + return nil; +} + +@end + +@implementation whisper_decoder_impl + + +/** + URL of the underlying .mlmodelc directory. +*/ ++ (nullable NSURL *)URLOfModelInThisBundle { + NSString *assetPath = [[NSBundle bundleForClass:[self class]] pathForResource:@"whisper_decoder_impl" ofType:@"mlmodelc"]; + if (nil == assetPath) { os_log_error(OS_LOG_DEFAULT, "Could not load whisper-decoder-impl.mlmodelc in the bundle resource"); return nil; } + return [NSURL fileURLWithPath:assetPath]; +} + + +/** + Initialize whisper_decoder_impl instance from an existing MLModel object. + + Usually the application does not use this initializer unless it makes a subclass of whisper_decoder_impl. + Such application may want to use `-[MLModel initWithContentsOfURL:configuration:error:]` and `+URLOfModelInThisBundle` to create a MLModel object to pass-in. +*/ +- (instancetype)initWithMLModel:(MLModel *)model { + self = [super init]; + if (!self) { return nil; } + _model = model; + if (_model == nil) { return nil; } + return self; +} + + +/** + Initialize whisper_decoder_impl instance with the model in this bundle. +*/ +- (nullable instancetype)init { + return [self initWithContentsOfURL:(NSURL * _Nonnull)self.class.URLOfModelInThisBundle error:nil]; +} + + +/** + Initialize whisper_decoder_impl instance with the model in this bundle. + + @param configuration The model configuration object + @param error If an error occurs, upon return contains an NSError object that describes the problem. If you are not interested in possible errors, pass in NULL. +*/ +- (nullable instancetype)initWithConfiguration:(MLModelConfiguration *)configuration error:(NSError * _Nullable __autoreleasing * _Nullable)error { + return [self initWithContentsOfURL:(NSURL * _Nonnull)self.class.URLOfModelInThisBundle configuration:configuration error:error]; +} + + +/** + Initialize whisper_decoder_impl instance from the model URL. + + @param modelURL URL to the .mlmodelc directory for whisper_decoder_impl. + @param error If an error occurs, upon return contains an NSError object that describes the problem. If you are not interested in possible errors, pass in NULL. +*/ +- (nullable instancetype)initWithContentsOfURL:(NSURL *)modelURL error:(NSError * _Nullable __autoreleasing * _Nullable)error { + MLModel *model = [MLModel modelWithContentsOfURL:modelURL error:error]; + if (model == nil) { return nil; } + return [self initWithMLModel:model]; +} + + +/** + Initialize whisper_decoder_impl instance from the model URL. + + @param modelURL URL to the .mlmodelc directory for whisper_decoder_impl. + @param configuration The model configuration object + @param error If an error occurs, upon return contains an NSError object that describes the problem. If you are not interested in possible errors, pass in NULL. +*/ +- (nullable instancetype)initWithContentsOfURL:(NSURL *)modelURL configuration:(MLModelConfiguration *)configuration error:(NSError * _Nullable __autoreleasing * _Nullable)error { + MLModel *model = [MLModel modelWithContentsOfURL:modelURL configuration:configuration error:error]; + if (model == nil) { return nil; } + return [self initWithMLModel:model]; +} + + +/** + Construct whisper_decoder_impl instance asynchronously with configuration. + Model loading may take time when the model content is not immediately available (e.g. encrypted model). Use this factory method especially when the caller is on the main thread. + + @param configuration The model configuration + @param handler When the model load completes successfully or unsuccessfully, the completion handler is invoked with a valid whisper_decoder_impl instance or NSError object. +*/ ++ (void)loadWithConfiguration:(MLModelConfiguration *)configuration completionHandler:(void (^)(whisper_decoder_impl * _Nullable model, NSError * _Nullable error))handler { + [self loadContentsOfURL:(NSURL * _Nonnull)[self URLOfModelInThisBundle] + configuration:configuration + completionHandler:handler]; +} + + +/** + Construct whisper_decoder_impl instance asynchronously with URL of .mlmodelc directory and optional configuration. + + Model loading may take time when the model content is not immediately available (e.g. encrypted model). Use this factory method especially when the caller is on the main thread. + + @param modelURL The model URL. + @param configuration The model configuration + @param handler When the model load completes successfully or unsuccessfully, the completion handler is invoked with a valid whisper_decoder_impl instance or NSError object. +*/ ++ (void)loadContentsOfURL:(NSURL *)modelURL configuration:(MLModelConfiguration *)configuration completionHandler:(void (^)(whisper_decoder_impl * _Nullable model, NSError * _Nullable error))handler { + [MLModel loadContentsOfURL:modelURL + configuration:configuration + completionHandler:^(MLModel *model, NSError *error) { + if (model != nil) { + whisper_decoder_impl *typedModel = [[whisper_decoder_impl alloc] initWithMLModel:model]; + handler(typedModel, nil); + } else { + handler(nil, error); + } + }]; +} + +- (nullable whisper_decoder_implOutput *)predictionFromFeatures:(whisper_decoder_implInput *)input error:(NSError * _Nullable __autoreleasing * _Nullable)error { + return [self predictionFromFeatures:input options:[[MLPredictionOptions alloc] init] error:error]; +} + +- (nullable whisper_decoder_implOutput *)predictionFromFeatures:(whisper_decoder_implInput *)input options:(MLPredictionOptions *)options error:(NSError * _Nullable __autoreleasing * _Nullable)error { + id outFeatures = [self.model predictionFromFeatures:input options:options error:error]; + if (!outFeatures) { return nil; } + return [[whisper_decoder_implOutput alloc] initWithVar_1346:(MLMultiArray *)[outFeatures featureValueForName:@"var_1346"].multiArrayValue]; +} + +- (nullable whisper_decoder_implOutput *)predictionFromToken_data:(MLMultiArray *)token_data audio_data:(MLMultiArray *)audio_data error:(NSError * _Nullable __autoreleasing * _Nullable)error { + whisper_decoder_implInput *input_ = [[whisper_decoder_implInput alloc] initWithToken_data:token_data audio_data:audio_data]; + return [self predictionFromFeatures:input_ error:error]; +} + +- (nullable NSArray *)predictionsFromInputs:(NSArray *)inputArray options:(MLPredictionOptions *)options error:(NSError * _Nullable __autoreleasing * _Nullable)error { + id inBatch = [[MLArrayBatchProvider alloc] initWithFeatureProviderArray:inputArray]; + id outBatch = [self.model predictionsFromBatch:inBatch options:options error:error]; + if (!outBatch) { return nil; } + NSMutableArray *results = [NSMutableArray arrayWithCapacity:(NSUInteger)outBatch.count]; + for (NSInteger i = 0; i < outBatch.count; i++) { + id resultProvider = [outBatch featuresAtIndex:i]; + whisper_decoder_implOutput * result = [[whisper_decoder_implOutput alloc] initWithVar_1346:(MLMultiArray *)[resultProvider featureValueForName:@"var_1346"].multiArrayValue]; + [results addObject:result]; + } + return results; +} + +@end diff --git a/sys/whisper.cpp/coreml/whisper-encoder-impl.h b/sys/whisper.cpp/coreml/whisper-encoder-impl.h new file mode 100644 index 0000000..7b83cd9 --- /dev/null +++ b/sys/whisper.cpp/coreml/whisper-encoder-impl.h @@ -0,0 +1,142 @@ +// +// whisper-encoder-impl.h +// +// This file was automatically generated and should not be edited. +// + +#import +#import +#include +#include + +NS_ASSUME_NONNULL_BEGIN + + +/// Model Prediction Input Type +API_AVAILABLE(macos(12.0), ios(15.0), watchos(8.0), tvos(15.0)) __attribute__((visibility("hidden"))) +@interface whisper_encoder_implInput : NSObject + +/// logmel_data as 1 × 80 × 3000 3-dimensional array of floats +@property (readwrite, nonatomic, strong) MLMultiArray * logmel_data; +- (instancetype)init NS_UNAVAILABLE; +- (instancetype)initWithLogmel_data:(MLMultiArray *)logmel_data NS_DESIGNATED_INITIALIZER; + +@end + + +/// Model Prediction Output Type +API_AVAILABLE(macos(12.0), ios(15.0), watchos(8.0), tvos(15.0)) __attribute__((visibility("hidden"))) +@interface whisper_encoder_implOutput : NSObject + +/// output as multidimensional array of floats +@property (readwrite, nonatomic, strong) MLMultiArray * output; +- (instancetype)init NS_UNAVAILABLE; +- (instancetype)initWithOutput:(MLMultiArray *)output NS_DESIGNATED_INITIALIZER; + +@end + + +/// Class for model loading and prediction +API_AVAILABLE(macos(12.0), ios(15.0), watchos(8.0), tvos(15.0)) __attribute__((visibility("hidden"))) +@interface whisper_encoder_impl : NSObject +@property (readonly, nonatomic, nullable) MLModel * model; + +/** + URL of the underlying .mlmodelc directory. +*/ ++ (nullable NSURL *)URLOfModelInThisBundle; + +/** + Initialize whisper_encoder_impl instance from an existing MLModel object. + + Usually the application does not use this initializer unless it makes a subclass of whisper_encoder_impl. + Such application may want to use `-[MLModel initWithContentsOfURL:configuration:error:]` and `+URLOfModelInThisBundle` to create a MLModel object to pass-in. +*/ +- (instancetype)initWithMLModel:(MLModel *)model NS_DESIGNATED_INITIALIZER; + +/** + Initialize whisper_encoder_impl instance with the model in this bundle. +*/ +- (nullable instancetype)init; + +/** + Initialize whisper_encoder_impl instance with the model in this bundle. + + @param configuration The model configuration object + @param error If an error occurs, upon return contains an NSError object that describes the problem. If you are not interested in possible errors, pass in NULL. +*/ +- (nullable instancetype)initWithConfiguration:(MLModelConfiguration *)configuration error:(NSError * _Nullable __autoreleasing * _Nullable)error; + +/** + Initialize whisper_encoder_impl instance from the model URL. + + @param modelURL URL to the .mlmodelc directory for whisper_encoder_impl. + @param error If an error occurs, upon return contains an NSError object that describes the problem. If you are not interested in possible errors, pass in NULL. +*/ +- (nullable instancetype)initWithContentsOfURL:(NSURL *)modelURL error:(NSError * _Nullable __autoreleasing * _Nullable)error; + +/** + Initialize whisper_encoder_impl instance from the model URL. + + @param modelURL URL to the .mlmodelc directory for whisper_encoder_impl. + @param configuration The model configuration object + @param error If an error occurs, upon return contains an NSError object that describes the problem. If you are not interested in possible errors, pass in NULL. +*/ +- (nullable instancetype)initWithContentsOfURL:(NSURL *)modelURL configuration:(MLModelConfiguration *)configuration error:(NSError * _Nullable __autoreleasing * _Nullable)error; + +/** + Construct whisper_encoder_impl instance asynchronously with configuration. + Model loading may take time when the model content is not immediately available (e.g. encrypted model). Use this factory method especially when the caller is on the main thread. + + @param configuration The model configuration + @param handler When the model load completes successfully or unsuccessfully, the completion handler is invoked with a valid whisper_encoder_impl instance or NSError object. +*/ ++ (void)loadWithConfiguration:(MLModelConfiguration *)configuration completionHandler:(void (^)(whisper_encoder_impl * _Nullable model, NSError * _Nullable error))handler; + +/** + Construct whisper_encoder_impl instance asynchronously with URL of .mlmodelc directory and optional configuration. + + Model loading may take time when the model content is not immediately available (e.g. encrypted model). Use this factory method especially when the caller is on the main thread. + + @param modelURL The model URL. + @param configuration The model configuration + @param handler When the model load completes successfully or unsuccessfully, the completion handler is invoked with a valid whisper_encoder_impl instance or NSError object. +*/ ++ (void)loadContentsOfURL:(NSURL *)modelURL configuration:(MLModelConfiguration *)configuration completionHandler:(void (^)(whisper_encoder_impl * _Nullable model, NSError * _Nullable error))handler; + +/** + Make a prediction using the standard interface + @param input an instance of whisper_encoder_implInput to predict from + @param error If an error occurs, upon return contains an NSError object that describes the problem. If you are not interested in possible errors, pass in NULL. + @return the prediction as whisper_encoder_implOutput +*/ +- (nullable whisper_encoder_implOutput *)predictionFromFeatures:(whisper_encoder_implInput *)input error:(NSError * _Nullable __autoreleasing * _Nullable)error; + +/** + Make a prediction using the standard interface + @param input an instance of whisper_encoder_implInput to predict from + @param options prediction options + @param error If an error occurs, upon return contains an NSError object that describes the problem. If you are not interested in possible errors, pass in NULL. + @return the prediction as whisper_encoder_implOutput +*/ +- (nullable whisper_encoder_implOutput *)predictionFromFeatures:(whisper_encoder_implInput *)input options:(MLPredictionOptions *)options error:(NSError * _Nullable __autoreleasing * _Nullable)error; + +/** + Make a prediction using the convenience interface + @param logmel_data as 1 × n_mel × 3000 3-dimensional array of floats: + @param error If an error occurs, upon return contains an NSError object that describes the problem. If you are not interested in possible errors, pass in NULL. + @return the prediction as whisper_encoder_implOutput +*/ +- (nullable whisper_encoder_implOutput *)predictionFromLogmel_data:(MLMultiArray *)logmel_data error:(NSError * _Nullable __autoreleasing * _Nullable)error; + +/** + Batch prediction + @param inputArray array of whisper_encoder_implInput instances to obtain predictions from + @param options prediction options + @param error If an error occurs, upon return contains an NSError object that describes the problem. If you are not interested in possible errors, pass in NULL. + @return the predictions as NSArray +*/ +- (nullable NSArray *)predictionsFromInputs:(NSArray *)inputArray options:(MLPredictionOptions *)options error:(NSError * _Nullable __autoreleasing * _Nullable)error; +@end + +NS_ASSUME_NONNULL_END diff --git a/sys/whisper.cpp/coreml/whisper-encoder-impl.m b/sys/whisper.cpp/coreml/whisper-encoder-impl.m new file mode 100644 index 0000000..ee8e506 --- /dev/null +++ b/sys/whisper.cpp/coreml/whisper-encoder-impl.m @@ -0,0 +1,197 @@ +// +// whisper-encoder-impl.m +// +// This file was automatically generated and should not be edited. +// + +#if !__has_feature(objc_arc) +#error This file must be compiled with automatic reference counting enabled (-fobjc-arc) +#endif + +#import "whisper-encoder-impl.h" + +@implementation whisper_encoder_implInput + +- (instancetype)initWithLogmel_data:(MLMultiArray *)logmel_data { + self = [super init]; + if (self) { + _logmel_data = logmel_data; + } + return self; +} + +- (NSSet *)featureNames { + return [NSSet setWithArray:@[@"logmel_data"]]; +} + +- (nullable MLFeatureValue *)featureValueForName:(NSString *)featureName { + if ([featureName isEqualToString:@"logmel_data"]) { + return [MLFeatureValue featureValueWithMultiArray:self.logmel_data]; + } + return nil; +} + +@end + +@implementation whisper_encoder_implOutput + +- (instancetype)initWithOutput:(MLMultiArray *)output { + self = [super init]; + if (self) { + _output = output; + } + return self; +} + +- (NSSet *)featureNames { + return [NSSet setWithArray:@[@"output"]]; +} + +- (nullable MLFeatureValue *)featureValueForName:(NSString *)featureName { + if ([featureName isEqualToString:@"output"]) { + return [MLFeatureValue featureValueWithMultiArray:self.output]; + } + return nil; +} + +@end + +@implementation whisper_encoder_impl + + +/** + URL of the underlying .mlmodelc directory. +*/ ++ (nullable NSURL *)URLOfModelInThisBundle { + NSString *assetPath = [[NSBundle bundleForClass:[self class]] pathForResource:@"whisper_encoder_impl" ofType:@"mlmodelc"]; + if (nil == assetPath) { os_log_error(OS_LOG_DEFAULT, "Could not load whisper-encoder-impl.mlmodelc in the bundle resource"); return nil; } + return [NSURL fileURLWithPath:assetPath]; +} + + +/** + Initialize whisper_encoder_impl instance from an existing MLModel object. + + Usually the application does not use this initializer unless it makes a subclass of whisper_encoder_impl. + Such application may want to use `-[MLModel initWithContentsOfURL:configuration:error:]` and `+URLOfModelInThisBundle` to create a MLModel object to pass-in. +*/ +- (instancetype)initWithMLModel:(MLModel *)model { + self = [super init]; + if (!self) { return nil; } + _model = model; + if (_model == nil) { return nil; } + return self; +} + + +/** + Initialize whisper_encoder_impl instance with the model in this bundle. +*/ +- (nullable instancetype)init { + return [self initWithContentsOfURL:(NSURL * _Nonnull)self.class.URLOfModelInThisBundle error:nil]; +} + + +/** + Initialize whisper_encoder_impl instance with the model in this bundle. + + @param configuration The model configuration object + @param error If an error occurs, upon return contains an NSError object that describes the problem. If you are not interested in possible errors, pass in NULL. +*/ +- (nullable instancetype)initWithConfiguration:(MLModelConfiguration *)configuration error:(NSError * _Nullable __autoreleasing * _Nullable)error { + return [self initWithContentsOfURL:(NSURL * _Nonnull)self.class.URLOfModelInThisBundle configuration:configuration error:error]; +} + + +/** + Initialize whisper_encoder_impl instance from the model URL. + + @param modelURL URL to the .mlmodelc directory for whisper_encoder_impl. + @param error If an error occurs, upon return contains an NSError object that describes the problem. If you are not interested in possible errors, pass in NULL. +*/ +- (nullable instancetype)initWithContentsOfURL:(NSURL *)modelURL error:(NSError * _Nullable __autoreleasing * _Nullable)error { + MLModel *model = [MLModel modelWithContentsOfURL:modelURL error:error]; + if (model == nil) { return nil; } + return [self initWithMLModel:model]; +} + + +/** + Initialize whisper_encoder_impl instance from the model URL. + + @param modelURL URL to the .mlmodelc directory for whisper_encoder_impl. + @param configuration The model configuration object + @param error If an error occurs, upon return contains an NSError object that describes the problem. If you are not interested in possible errors, pass in NULL. +*/ +- (nullable instancetype)initWithContentsOfURL:(NSURL *)modelURL configuration:(MLModelConfiguration *)configuration error:(NSError * _Nullable __autoreleasing * _Nullable)error { + MLModel *model = [MLModel modelWithContentsOfURL:modelURL configuration:configuration error:error]; + if (model == nil) { return nil; } + return [self initWithMLModel:model]; +} + + +/** + Construct whisper_encoder_impl instance asynchronously with configuration. + Model loading may take time when the model content is not immediately available (e.g. encrypted model). Use this factory method especially when the caller is on the main thread. + + @param configuration The model configuration + @param handler When the model load completes successfully or unsuccessfully, the completion handler is invoked with a valid whisper_encoder_impl instance or NSError object. +*/ ++ (void)loadWithConfiguration:(MLModelConfiguration *)configuration completionHandler:(void (^)(whisper_encoder_impl * _Nullable model, NSError * _Nullable error))handler { + [self loadContentsOfURL:(NSURL * _Nonnull)[self URLOfModelInThisBundle] + configuration:configuration + completionHandler:handler]; +} + + +/** + Construct whisper_encoder_impl instance asynchronously with URL of .mlmodelc directory and optional configuration. + + Model loading may take time when the model content is not immediately available (e.g. encrypted model). Use this factory method especially when the caller is on the main thread. + + @param modelURL The model URL. + @param configuration The model configuration + @param handler When the model load completes successfully or unsuccessfully, the completion handler is invoked with a valid whisper_encoder_impl instance or NSError object. +*/ ++ (void)loadContentsOfURL:(NSURL *)modelURL configuration:(MLModelConfiguration *)configuration completionHandler:(void (^)(whisper_encoder_impl * _Nullable model, NSError * _Nullable error))handler { + [MLModel loadContentsOfURL:modelURL + configuration:configuration + completionHandler:^(MLModel *model, NSError *error) { + if (model != nil) { + whisper_encoder_impl *typedModel = [[whisper_encoder_impl alloc] initWithMLModel:model]; + handler(typedModel, nil); + } else { + handler(nil, error); + } + }]; +} + +- (nullable whisper_encoder_implOutput *)predictionFromFeatures:(whisper_encoder_implInput *)input error:(NSError * _Nullable __autoreleasing * _Nullable)error { + return [self predictionFromFeatures:input options:[[MLPredictionOptions alloc] init] error:error]; +} + +- (nullable whisper_encoder_implOutput *)predictionFromFeatures:(whisper_encoder_implInput *)input options:(MLPredictionOptions *)options error:(NSError * _Nullable __autoreleasing * _Nullable)error { + id outFeatures = [self.model predictionFromFeatures:input options:options error:error]; + if (!outFeatures) { return nil; } + return [[whisper_encoder_implOutput alloc] initWithOutput:(MLMultiArray *)[outFeatures featureValueForName:@"output"].multiArrayValue]; +} + +- (nullable whisper_encoder_implOutput *)predictionFromLogmel_data:(MLMultiArray *)logmel_data error:(NSError * _Nullable __autoreleasing * _Nullable)error { + whisper_encoder_implInput *input_ = [[whisper_encoder_implInput alloc] initWithLogmel_data:logmel_data]; + return [self predictionFromFeatures:input_ error:error]; +} + +- (nullable NSArray *)predictionsFromInputs:(NSArray *)inputArray options:(MLPredictionOptions *)options error:(NSError * _Nullable __autoreleasing * _Nullable)error { + id inBatch = [[MLArrayBatchProvider alloc] initWithFeatureProviderArray:inputArray]; + id outBatch = [self.model predictionsFromBatch:inBatch options:options error:error]; + if (!outBatch) { return nil; } + NSMutableArray *results = [NSMutableArray arrayWithCapacity:(NSUInteger)outBatch.count]; + for (NSInteger i = 0; i < outBatch.count; i++) { + id resultProvider = [outBatch featuresAtIndex:i]; + whisper_encoder_implOutput * result = [[whisper_encoder_implOutput alloc] initWithOutput:(MLMultiArray *)[resultProvider featureValueForName:@"output"].multiArrayValue]; + [results addObject:result]; + } + return results; +} + +@end diff --git a/sys/whisper.cpp/coreml/whisper-encoder.h b/sys/whisper.cpp/coreml/whisper-encoder.h new file mode 100644 index 0000000..508df7c --- /dev/null +++ b/sys/whisper.cpp/coreml/whisper-encoder.h @@ -0,0 +1,26 @@ +// Wrapper of the Core ML Whisper Encoder model +// +// Code is derived from the work of Github user @wangchou +// ref: https://github.com/wangchou/callCoreMLFromCpp + +#include + +#if __cplusplus +extern "C" { +#endif + +struct whisper_coreml_context; + +struct whisper_coreml_context * whisper_coreml_init(const char * path_model); +void whisper_coreml_free(struct whisper_coreml_context * ctx); + +void whisper_coreml_encode( + const whisper_coreml_context * ctx, + int64_t n_ctx, + int64_t n_mel, + float * mel, + float * out); + +#if __cplusplus +} +#endif diff --git a/sys/whisper.cpp/coreml/whisper-encoder.mm b/sys/whisper.cpp/coreml/whisper-encoder.mm new file mode 100644 index 0000000..8e93f18 --- /dev/null +++ b/sys/whisper.cpp/coreml/whisper-encoder.mm @@ -0,0 +1,73 @@ +#if !__has_feature(objc_arc) +#error This file must be compiled with automatic reference counting enabled (-fobjc-arc) +#endif + +#import "whisper-encoder.h" +#import "whisper-encoder-impl.h" + +#import + +#include + +#if __cplusplus +extern "C" { +#endif + +struct whisper_coreml_context { + const void * data; +}; + +struct whisper_coreml_context * whisper_coreml_init(const char * path_model) { + NSString * path_model_str = [[NSString alloc] initWithUTF8String:path_model]; + + NSURL * url_model = [NSURL fileURLWithPath: path_model_str]; + + // select which device to run the Core ML model on + MLModelConfiguration *config = [[MLModelConfiguration alloc] init]; + config.computeUnits = MLComputeUnitsCPUAndGPU; + //config.computeUnits = MLComputeUnitsCPUAndNeuralEngine; + //config.computeUnits = MLComputeUnitsAll; + + const void * data = CFBridgingRetain([[whisper_encoder_impl alloc] initWithContentsOfURL:url_model configuration:config error:nil]); + + if (data == NULL) { + return NULL; + } + + whisper_coreml_context * ctx = new whisper_coreml_context; + + ctx->data = data; + + return ctx; +} + +void whisper_coreml_free(struct whisper_coreml_context * ctx) { + CFRelease(ctx->data); + delete ctx; +} + +void whisper_coreml_encode( + const whisper_coreml_context * ctx, + int64_t n_ctx, + int64_t n_mel, + float * mel, + float * out) { + MLMultiArray * inMultiArray = [ + [MLMultiArray alloc] initWithDataPointer: mel + shape: @[@1, @(n_mel), @(n_ctx)] + dataType: MLMultiArrayDataTypeFloat32 + strides: @[@(n_ctx*n_mel), @(n_ctx), @1] + deallocator: nil + error: nil + ]; + + @autoreleasepool { + whisper_encoder_implOutput * outCoreML = [(__bridge id) ctx->data predictionFromLogmel_data:inMultiArray error:nil]; + + memcpy(out, outCoreML.output.dataPointer, outCoreML.output.count * sizeof(float)); + } +} + +#if __cplusplus +} +#endif diff --git a/sys/whisper.cpp/extra/bench-all.sh b/sys/whisper.cpp/extra/bench-all.sh new file mode 100755 index 0000000..6939daf --- /dev/null +++ b/sys/whisper.cpp/extra/bench-all.sh @@ -0,0 +1,100 @@ +#!/bin/bash + +# Helper script to run the bench tool on all models and print the results in share-able format + +printf "Usage: ./bench.sh [n_threads] [encoder-only]\n" + +if [ -z "$1" ]; then + n_threads=4 +else + n_threads=$1 +fi + +encoder_only=0 +if [ -z "$2" ]; then + encoder_only=0 +else + encoder_only=$2 +fi + +models=( \ + "tiny" "tiny-q4_0" "tiny-q4_1" "tiny-q5_0" "tiny-q5_1" "tiny-q8_0" \ + "base" "base-q4_0" "base-q4_1" "base-q5_0" "base-q5_1" "base-q8_0" \ + "small" "small-q4_0" "small-q4_1" "small-q5_0" "small-q5_1" "small-q8_0" \ + "medium" "medium-q4_0" "medium-q4_1" "medium-q5_0" "medium-q5_1" "medium-q8_0" "medium-dis" \ + "large-v2" "large-v2-q4_0" "large-v2-q4_1" "large-v2-q5_0" "large-v2-q5_1" "large-v2-q8_0" "large-v2-dis" \ +) + +if [ "$encoder_only" -eq 0 ]; then + printf "\n" + printf "Running memcpy benchmark\n" + printf "\n" + + ./bench -w 1 -t $n_threads 2>&1 + + printf "\n" + printf "Running ggml_mul_mat benchmark with $n_threads threads\n" + printf "\n" + + ./bench -w 2 -t $n_threads 2>&1 + + printf "\n" + printf "Running benchmark for all models\n" + printf "This can take a while!\n" + printf "\n" +fi + +printf "| %6s | %6s | %16s | %13s | %3s | %7s | %7s | %7s | %7s | %7s |\n" "CPU" "OS" "Config" "Model" "Th" "Enc." "Dec." "Bch5" "PP" "Commit" +printf "| %6s | %6s | %16s | %13s | %3s | %7s | %7s | %7s | %7s | %7s |\n" "---" "---" "---" "---" "---" "---" "---" "---" "---" "---" + +for model in "${models[@]}"; do + # actual run + # store stderr output in a variable in order to parse it later + output=$(./bench -m ./models/ggml-$model.bin -t $n_threads 2>&1) + ret=$? + + # parse the output: + encode_time=$(echo "$output" | grep "encode time" | awk '{print $11}') + decode_time=$(echo "$output" | grep "decode time" | awk '{print $11}') + batchd_time=$(echo "$output" | grep "batchd time" | awk '{print $11}') + prompt_time=$(echo "$output" | grep "prompt time" | awk '{print $11}') + system_info=$(echo "$output" | grep "system_info") + n_threads=$(echo "$output" | grep "system_info" | awk '{print $4}') + + # floor to milliseconds + #encode_time=${encode_time%.*} + #decode_time=${decode_time%.*} + #prompt_time=${prompt_time%.*} + + config="" + + if [[ $system_info == *"AVX2 = 1"* ]]; then + config="$config AVX2" + fi + + if [[ $system_info == *"NEON = 1"* ]]; then + config="$config NEON" + fi + + if [[ $system_info == *"BLAS = 1"* ]]; then + config="$config BLAS" + fi + + if [[ $system_info == *"COREML = 1"* ]]; then + config="$config COREML" + fi + + if [[ $system_info == *"CUDA = 1"* ]]; then + config="$config CUDA" + fi + + if [[ $system_info == *"METAL = 1"* ]]; then + config="$config METAL" + fi + + commit=$(git rev-parse --short HEAD) + + if [ $ret -eq 0 ]; then + printf "| | | %16s | %13s | %3s | %7s | %7s | %7s | %7s | %7s |\n" "$config" "$model" "$n_threads" "$encode_time" "$decode_time" "$batchd_time" "$prompt_time" "$commit" + fi +done diff --git a/sys/whisper.cpp/extra/bench-wts.sh b/sys/whisper.cpp/extra/bench-wts.sh new file mode 100755 index 0000000..223d71b --- /dev/null +++ b/sys/whisper.cpp/extra/bench-wts.sh @@ -0,0 +1,70 @@ +# Benchmark word-level timestamps for different models +# +# This script takes two arguments +# - an audio file +# - [optional] path to a font file + +# I'm using "/usr/share/fonts/truetype/freefont/FreeMono.ttf" on Ubuntu + +if [ -z "$1" ]; then + echo "Usage: $0