commit 62fbd6fd1ae26c792fcf8ccacdf68a928bd4276c Author: bendn Date: Tue Sep 5 06:45:23 2023 +0700 init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..96ef6c0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/target +Cargo.lock diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..1c85e52 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "fimg" +version = "0.1.0" +authors = ["bend-n "] +license = "MIT" +edition = "2021" +description = "fast image operations" +repository = "https://github.com/bend-n/fimg" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +png = { version = "0.17", features = ["unstable"], optional = true } + +[features] +save = ["png"] +default = ["save"] + +[profile.release] +debug = 2 +opt-level = 3 +lto = "thin" +incremental = true diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..1fafc15 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 bendn + +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/README.md b/README.md new file mode 100644 index 0000000..f77c5cc --- /dev/null +++ b/README.md @@ -0,0 +1,9 @@ +# fimg + +quick simple image operations + +## supported operations + +- [x] overlay +- [x] rotation +- [x] flipping \ No newline at end of file diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 0000000..5d56faf --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "nightly" diff --git a/src/affine.rs b/src/affine.rs new file mode 100644 index 0000000..18f19ee --- /dev/null +++ b/src/affine.rs @@ -0,0 +1,255 @@ +use crate::{FromRefMut, Image}; + +pub trait Rotations { + /// Rotate a image 180 degrees clockwise. + fn rot_180(&mut self); + /// Rotate a image 90 degrees clockwise. + /// # Safety + /// + /// UB if the image is not square + unsafe fn rot_90(&mut self); + /// Rotate a image 270 degrees clockwise, or 90 degrees anti clockwise. + /// # Safety + /// + /// UB if the image is not square + unsafe fn rot_270(&mut self); +} + +pub trait Flips { + /// Flip a image vertically. + fn flip_v(&mut self); + + /// Flip a image horizontally. + fn flip_h(&mut self); +} + +impl Flips for Image, CHANNELS> { + fn flip_h(&mut self) { + self.as_mut().flip_h(); + } + fn flip_v(&mut self) { + self.as_mut().flip_v(); + } +} + +impl Flips for Image<&mut [u8], CHANNELS> { + fn flip_v(&mut self) { + for y in 0..self.height() / 2 { + for x in 0..self.width() { + let y2 = self.height() - y - 1; + // SAFETY: within bounds + let p2 = unsafe { self.pixel(x, y2) }; + let p = unsafe { self.pixel(x, y) }; + unsafe { self.set_pixel(x, y2, p) }; + unsafe { self.set_pixel(x, y, p2) }; + } + } + } + + fn flip_h(&mut self) { + for y in 0..self.height() { + for x in 0..self.width() / 2 { + let x2 = self.width() - x - 1; + let p2 = unsafe { self.pixel(x2, y) }; + let p = unsafe { self.pixel(x, y) }; + unsafe { self.set_pixel(x2, y, p) }; + unsafe { self.set_pixel(x, y, p2) }; + } + } + } +} + +impl Rotations for Image, CHANNELS> { + fn rot_180(&mut self) { + self.as_mut().rot_180(); + } + + unsafe fn rot_90(&mut self) { + unsafe { self.as_mut().rot_90() } + } + + unsafe fn rot_270(&mut self) { + unsafe { self.as_mut().rot_270() } + } +} + +impl Rotations for Image<&mut [u8], CHANNELS> { + fn rot_180(&mut self) { + for y in 0..self.height() / 2 { + for x in 0..self.width() { + let p = unsafe { self.pixel(x, y) }; + let x2 = self.width() - x - 1; + let y2 = self.height() - y - 1; + let p2 = unsafe { self.pixel(x2, y2) }; + unsafe { self.set_pixel(x, y, p2) }; + unsafe { self.set_pixel(x2, y2, p) }; + } + } + + if self.height() % 2 != 0 { + let middle = self.height() / 2; + + for x in 0..self.width() / 2 { + let p = unsafe { self.pixel(x, middle) }; + let x2 = self.width() - x - 1; + let p2 = unsafe { self.pixel(x2, middle) }; + unsafe { self.set_pixel(x, middle, p2) }; + unsafe { self.set_pixel(x2, middle, p) }; + } + } + } + + #[inline] + unsafe fn rot_90(&mut self) { + // This is done by first flipping + self.flip_v(); + // Then transposing the image, to save allocations. + // SAFETY: caller ensures rectangularity + unsafe { transpose(self) }; + } + + #[inline] + unsafe fn rot_270(&mut self) { + self.flip_h(); + // SAFETY: caller ensures rectangularity + unsafe { transpose(self) }; + } +} + +/// # Safety +/// +/// UB if supplied image rectangular +unsafe fn transpose(img: &mut Image<&mut [u8], CHANNELS>) { + debug_assert_eq!(img.width(), img.height()); + let size = img.width(); + for i in 0..size { + for j in i..size { + for c in 0..CHANNELS { + // SAFETY: caller gurantees rectangularity + unsafe { + img.buffer.swap_unchecked( + (i * size + j) as usize * CHANNELS + c, + (j * size + i) as usize * CHANNELS + c, + ); + }; + } + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::img; + + #[test] + fn rotate_90() { + let mut from = img![ + [00, 01] + [02, 10] + ]; + unsafe { from.rot_90() }; + assert_eq!( + from, + img![ + [02, 00] + [10, 01] + ] + ); + } + + #[test] + fn rotate_180() { + let mut from = img![ + [00, 01] + [02, 10] + ]; + from.rot_180(); + assert_eq!( + from, + img![ + [10, 02] + [01, 00] + ] + ); + } + + #[test] + fn rotate_270() { + let mut from = img![ + [00, 01] + [20, 10] + ]; + unsafe { from.rot_270() }; + assert_eq!( + from, + img![ + [01, 10] + [00, 20] + ] + ); + } + + #[test] + fn flip_vertical() { + let mut from = img![ + [90, 01] + [21, 42] + ]; + from.flip_v(); + assert_eq!( + from, + img![ + [21, 42] + [90, 01] + ] + ); + } + #[test] + fn flip_horizontal() { + let mut from = img![ + [90, 01] + [21, 42] + ]; + from.flip_h(); + assert_eq!( + from, + img![ + [01, 90] + [42, 21] + ] + ); + } +} + +#[cfg(test)] +mod bench { + use super::*; + extern crate test; + use crate::Image; + use test::Bencher; + + macro_rules! bench { + (fn $name: ident() { run $fn: ident() }) => { + #[bench] + fn $name(b: &mut Bencher) { + let mut img: Image<_, 4> = Image::new( + 64.try_into().unwrap(), + 64.try_into().unwrap(), + include_bytes!("../test_data/4_180x180.imgbuf").to_vec(), + ); + b.iter(|| { + for _ in 0..256 { + img.flip_h(); + } + }); + } + }; + } + + bench!(fn flip_h() { run flip_h() }); + bench!(fn flip_v() { run flip_v() }); + bench!(fn rotate_90() { run rot_90() }); + bench!(fn rotate_180() { run rot_180() }); + bench!(fn rotate_270() { run rot_270() }); +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..70b91eb --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,287 @@ +#![feature( + slice_swap_unchecked, + unchecked_math, + portable_simd, + array_chunks, + test +)] +#![warn( + clippy::multiple_unsafe_ops_per_block, + clippy::missing_const_for_fn, + clippy::missing_safety_doc, + unsafe_op_in_unsafe_fn, + clippy::dbg_macro, + clippy::perf +)] +#![allow(clippy::zero_prefixed_literal)] + +use std::{num::NonZeroU32, slice::SliceIndex}; + +mod affine; +mod overlay; +pub use affine::{Flips, Rotations}; +pub use overlay::{Overlay, OverlayAt}; + +pub trait RepeatNew { + type Output; + /// Repeat self till it fills a new image of size x, y + /// # Safety + /// + /// UB if self's width is not a multiple of x, or self's height is not a multiple of y + unsafe fn repeated(&self, x: u32, y: u32) -> Self::Output; +} + +macro_rules! assert_unchecked { + ($cond:expr) => {{ + if !$cond { + #[cfg(debug_assertions)] + let _ = ::core::ptr::NonNull::<()>::dangling().as_ref(); // force unsafe wrapping block + #[cfg(debug_assertions)] + panic!("assertion failed: {} returned false", stringify!($cond)); + #[cfg(not(debug_assertions))] + std::hint::unreachable_unchecked() + } + }}; +} +use assert_unchecked; + +impl RepeatNew for Image<&[u8], 3> { + type Output = Image, 3>; + unsafe fn repeated(&self, x: u32, y: u32) -> Self::Output { + let mut img = Image::alloc(x, y); // could probably optimize this a ton but eh + for x in 0..(x / self.width()) { + for y in 0..(y / self.height()) { + let a: &mut Image<&mut [u8], 3> = &mut img.as_mut(); + // SAFETY: caller upholds + unsafe { a.overlay_at(self, x * self.width(), y * self.height()) }; + } + } + img + } +} + +#[inline] +unsafe fn really_unsafe_index(x: u32, y: u32, w: u32) -> usize { + // y * w + x + let tmp = unsafe { (y as usize).unchecked_mul(w as usize) }; + unsafe { tmp.unchecked_add(x as usize) } +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Image { + pub buffer: T, + pub width: NonZeroU32, + pub height: NonZeroU32, +} + +impl Default for Image<&'static [u8], CHANNELS> { + fn default() -> Self { + Self { + buffer: &[0; CHANNELS], + width: NonZeroU32::new(1).unwrap(), + height: NonZeroU32::new(1).unwrap(), + } + } +} + +impl Image { + #[inline] + pub fn height(&self) -> u32 { + self.height.into() + } + + #[inline] + pub fn width(&self) -> u32 { + self.width.into() + } + + #[inline] + pub const fn new(width: NonZeroU32, height: NonZeroU32, buffer: T) -> Self { + Image { + buffer, + width, + height, + } + } +} + +impl Image<&[u8], CHANNELS> { + #[inline] + #[must_use] + pub const fn copy(&self) -> Self { + Self { + width: self.width, + height: self.height, + buffer: self.buffer, + } + } +} + +impl, const CHANNELS: usize> Image { + /// # Safety + /// + /// - UB if x, y is out of bounds + /// - UB if buffer is too small + #[inline] + unsafe fn slice(&self, x: u32, y: u32) -> impl SliceIndex<[u8], Output = [u8]> { + debug_assert!(x < self.width(), "x out of bounds"); + debug_assert!(y < self.height(), "y out of bounds"); + let index = unsafe { really_unsafe_index(x, y, self.width()) }; + let index = unsafe { index.unchecked_mul(CHANNELS) }; + debug_assert!(self.buffer.len() > index); + index..unsafe { index.unchecked_add(CHANNELS) } + } + + #[inline] + /// Returns a iterator over every pixel + pub fn chunked(&self) -> impl Iterator { + // SAFETY: 0 sized images illegal + unsafe { assert_unchecked!(self.buffer.len() > CHANNELS) }; + // SAFETY: no half pixels! + unsafe { assert_unchecked!(self.buffer.len() % CHANNELS == 0) }; + self.buffer.array_chunks::() + } + + /// Return a pixel at (x, y). + /// # Safety + /// + /// - UB if x, y is out of bounds + /// - UB if buffer is too small + #[inline] + pub unsafe fn pixel(&self, x: u32, y: u32) -> [u8; CHANNELS] { + let idx = unsafe { self.slice(x, y) }; + let ptr = unsafe { self.buffer.get_unchecked(idx).as_ptr().cast() }; + unsafe { *ptr } + } +} + +impl, const CHANNELS: usize> Image { + /// Return a mutable reference to a pixel at (x, y). + /// # Safety + /// + /// - UB if x, y is out of bounds + /// - UB if buffer is too small + #[inline] + pub unsafe fn pixel_mut(&mut self, x: u32, y: u32) -> &mut [u8] { + let idx = unsafe { self.slice(x, y) }; + unsafe { self.buffer.get_unchecked_mut(idx) } + } + + #[inline] + /// Returns a iterator over every pixel, mutably + pub fn chunked_mut(&mut self) -> impl Iterator { + // SAFETY: 0 sized images are not allowed + unsafe { assert_unchecked!(self.buffer.len() > CHANNELS) }; + // SAFETY: buffer cannot have half pixels + unsafe { assert_unchecked!(self.buffer.len() % CHANNELS == 0) }; + self.buffer.array_chunks_mut::() + } + + /// Set the pixel at x, y + /// + /// # Safety + /// + /// UB if x, y is out of bounds. + #[inline] + pub unsafe fn set_pixel(&mut self, x: u32, y: u32, px: [u8; CHANNELS]) { + // SAFETY: Caller says that x, y is in bounds + let out = unsafe { self.pixel_mut(x, y) }; + // SAFETY: px must be CHANNELS long + unsafe { std::ptr::copy_nonoverlapping(px.as_ptr(), out.as_mut_ptr(), CHANNELS) }; + } +} + +pub trait FromRef { + /// Reference the buffer + fn as_ref(&self) -> Image<&[u8], CHANNELS>; +} + +pub trait FromRefMut { + /// Reference the buffer, mutably + fn as_mut(&mut self) -> Image<&mut [u8], CHANNELS>; +} + +impl FromRef for Image<&mut [u8], CHANNELS> { + fn as_ref(&self) -> Image<&[u8], CHANNELS> { + Image::new(self.width, self.height, self.buffer) + } +} + +impl FromRefMut for Image<&mut [u8], CHANNELS> { + fn as_mut(&mut self) -> Image<&mut [u8], CHANNELS> { + Image::new(self.width, self.height, self.buffer) + } +} + +impl FromRef for Image, CHANNELS> { + fn as_ref(&self) -> Image<&[u8], CHANNELS> { + Image::new(self.width, self.height, &self.buffer) + } +} + +impl FromRefMut for Image, CHANNELS> { + fn as_mut(&mut self) -> Image<&mut [u8], CHANNELS> { + Image::new(self.width, self.height, &mut self.buffer) + } +} + +impl Image, CHANNELS> { + /// Allocates a new image + /// + /// # Panics + /// + /// if width || height == 0 + #[must_use] + pub fn alloc(width: u32, height: u32) -> Self { + Image { + width: width.try_into().unwrap(), + height: height.try_into().unwrap(), + buffer: vec![0; CHANNELS * width as usize * height as usize], + } + } +} +macro_rules! save { + ($channels:literal == $clr:ident ($clrhuman:literal)) => { + impl Image<&[u8], $channels> { + #[cfg(feature = "save")] + #[doc = "Save this "] + #[doc = $clrhuman] + #[doc = " image."] + pub fn save(&self, f: impl AsRef) { + let p = std::fs::File::create(f).unwrap(); + let w = &mut std::io::BufWriter::new(p); + let mut enc = png::Encoder::new(w, self.width(), self.height()); + enc.set_color(png::ColorType::$clr); + enc.set_depth(png::BitDepth::Eight); + enc.set_source_gamma(png::ScaledFloat::new(1.0 / 2.2)); + enc.set_source_chromaticities(png::SourceChromaticities::new( + (0.31270, 0.32900), + (0.64000, 0.33000), + (0.30000, 0.60000), + (0.15000, 0.06000), + )); + let mut writer = enc.write_header().unwrap(); + writer.write_image_data(self.buffer).unwrap(); + } + } + }; +} + +save!(3 == Rgb("RGB")); +save!(4 == Rgba("RGBA")); +save!(2 == GrayscaleAlpha("YA")); +save!(1 == Grayscale("Y")); + +#[cfg(test)] +macro_rules! img { + [[$($v:literal),+] [$($v2:literal),+]] => {{ + let from: Image, 1> = Image::new( + 2.try_into().unwrap(), + 2.try_into().unwrap(), + vec![$($v,)+ $($v2,)+] + ); + from + }} +} +#[cfg(test)] +use img; diff --git a/src/overlay.rs b/src/overlay.rs new file mode 100644 index 0000000..c1cac44 --- /dev/null +++ b/src/overlay.rs @@ -0,0 +1,250 @@ +use super::{assert_unchecked, really_unsafe_index, Image}; +use std::simd::SimdInt; +use std::simd::SimdPartialOrd; +use std::simd::{simd_swizzle, Simd}; + +pub trait OverlayAt { + /// Overlay with => self at coordinates x, y, without blending + /// # Safety + /// + /// UB if x, y is out of bounds + unsafe fn overlay_at(&mut self, with: &W, x: u32, y: u32) -> &mut Self; +} + +pub trait Overlay { + /// Overlay with => self (does not blend) + /// # Safety + /// + /// UB if a.width != b.width || a.height != b.height + unsafe fn overlay(&mut self, with: &W) -> &mut Self; +} + +#[inline] +unsafe fn blit(rgb: &mut [u8], rgba: &[u8]) { + const LAST4: Simd = Simd::from_array([ + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, + ]); + + let mut srci = 0; + let mut dsti = 0; + while dsti + 16 <= rgb.len() { + let old: Simd = Simd::from_slice(unsafe { rgb.get_unchecked(dsti..dsti + 16) }); + let new: Simd = Simd::from_slice(unsafe { rgba.get_unchecked(srci..srci + 16) }); + + let threshold = new.simd_ge(Simd::splat(128)).to_int().cast::(); + let mut mask = simd_swizzle!( + threshold, + [3, 3, 3, 7, 7, 7, 11, 11, 11, 15, 15, 15, 0, 0, 0, 0] + ); + mask &= LAST4; + + let new_rgb = simd_swizzle!(new, [0, 1, 2, 4, 5, 6, 8, 9, 10, 12, 13, 14, 0, 0, 0, 0]); + let blended = (new_rgb & mask) | (old & !mask); + blended.copy_to_slice(unsafe { rgb.get_unchecked_mut(dsti..dsti + 16) }); + + srci += 16; + dsti += 12; + } + + while dsti + 3 <= rgb.len() { + if unsafe { *rgba.get_unchecked(srci + 3) } >= 128 { + let src = unsafe { rgba.get_unchecked(srci..srci + 3) }; + let end = unsafe { rgb.get_unchecked_mut(dsti..dsti + 3) }; + unsafe { std::ptr::copy_nonoverlapping(src.as_ptr(), end.as_mut_ptr(), 3) }; + } + + srci += 4; + dsti += 3; + } +} + +impl Overlay> for Image<&mut [u8], 4> { + #[inline] + unsafe fn overlay(&mut self, with: &Image<&[u8], 4>) -> &mut Self { + debug_assert!(self.width() == with.width()); + debug_assert!(self.height() == with.height()); + for (i, other_pixels) in with.chunked().enumerate() { + if other_pixels[3] >= 128 { + let idx_begin = unsafe { i.unchecked_mul(4) }; + let idx_end = unsafe { idx_begin.unchecked_add(4) }; + let own_pixels = unsafe { self.buffer.get_unchecked_mut(idx_begin..idx_end) }; + unsafe { + std::ptr::copy_nonoverlapping( + other_pixels.as_ptr(), + own_pixels.as_mut_ptr(), + 4, + ); + }; + } + } + self + } +} + +impl OverlayAt> for Image<&mut [u8], 3> { + #[inline] + unsafe fn overlay_at(&mut self, with: &Image<&[u8], 4>, x: u32, y: u32) -> &mut Self { + // SAFETY: caller upholds these + unsafe { assert_unchecked!(x + with.width() <= self.width()) }; + unsafe { assert_unchecked!(y + with.height() <= self.height()) }; + for j in 0..with.height() { + let i_x = j as usize * with.width() as usize * 4 + ..(j as usize + 1) * with.width() as usize * 4; + let o_x = ((j as usize + y as usize) * self.width() as usize + x as usize) * 3 + ..((j as usize + y as usize) * self.width() as usize + + x as usize + + with.width() as usize) + * 3; + let rgb = unsafe { self.buffer.get_unchecked_mut(o_x) }; + let rgba = unsafe { with.buffer.get_unchecked(i_x) }; + unsafe { blit(rgb, rgba) } + } + self + } +} + +impl OverlayAt> for Image<&mut [u8], 3> { + #[inline] + unsafe fn overlay_at(&mut self, with: &Image<&[u8], 3>, x: u32, y: u32) -> &mut Self { + macro_rules! o3x3 { + ($n:expr) => {{ + for j in 0..($n as usize) { + let i_x = j * ($n as usize) * 3..(j + 1) * ($n as usize) * 3; + let o_x = ((j + y as usize) * self.width() as usize + x as usize) * 3 + ..((j + y as usize) * self.width() as usize + x as usize + ($n as usize)) + * 3; + let a = unsafe { self.buffer.get_unchecked_mut(o_x) }; + let b = unsafe { with.buffer.get_unchecked(i_x) }; + a.copy_from_slice(b); + } + }}; + } + // let it unroll + match with.width() { + 8 => o3x3!(8), + 16 => o3x3!(16), // this branch makes 8x8 0.16 times slower; but 16x16 0.2 times faster. + _ => o3x3!(with.width()), + } + self + } +} + +impl Overlay> for Image<&mut [u8], 3> { + #[inline] + unsafe fn overlay(&mut self, with: &Image<&[u8], 4>) -> &mut Self { + debug_assert!(self.width() == with.width()); + debug_assert!(self.height() == with.height()); + for (i, chunk) in with + .buffer + .chunks_exact(with.width() as usize * 4) + .enumerate() + { + let rgb = unsafe { + self.buffer.get_unchecked_mut( + i * with.width() as usize * 3..(i + 1) * with.width() as usize * 3, + ) + }; + unsafe { blit(rgb, chunk) }; + } + self + } +} + +impl OverlayAt> for Image<&mut [u8], 4> { + #[inline] + unsafe fn overlay_at(&mut self, with: &Image<&[u8], 4>, x: u32, y: u32) -> &mut Self { + for j in 0..with.height() { + for i in 0..with.width() { + let index = unsafe { really_unsafe_index(i, j, with.width()) }; + let their_px = unsafe { with.buffer.get_unchecked(index * 4..index * 4 + 4) }; + if unsafe { *their_px.get_unchecked(3) } >= 128 { + let x = unsafe { i.unchecked_add(x) }; + let y = unsafe { j.unchecked_add(y) }; + let index = unsafe { really_unsafe_index(x, y, self.width()) }; + let our_px = unsafe { self.buffer.get_unchecked_mut(index * 4..index * 4 + 4) }; + our_px.copy_from_slice(their_px); + } + } + } + + self + } +} + +#[cfg(test)] +mod bench { + extern crate test; + + use test::Bencher; + + use super::*; + use crate::{FromRef, FromRefMut}; + + #[bench] + fn overlay_3on3at(bench: &mut Bencher) { + let mut v = vec![0u8; 3 * 64 * 64]; + let mut a: Image<_, 3> = Image::new( + 64.try_into().unwrap(), + 64.try_into().unwrap(), + v.as_mut_slice(), + ); + let b = Image::<&[u8], 3>::new( + 4.try_into().unwrap(), + 4.try_into().unwrap(), + *&include_bytes!("../test_data/3_4x4.imgbuf"), + ); + bench.iter(|| unsafe { + for x in 0..16 { + for y in 0..16 { + a.overlay_at(&b, x * 4, y * 4); + } + } + }); + assert_eq!( + a.as_ref().buffer, + include_bytes!("../test_results/3x3_at_out.buf") + ); + } + + #[bench] + fn overlay_4on3at(bench: &mut Bencher) { + let mut a: Image<_, 3> = Image::alloc(64, 64); + let b = Image::<&[u8], 4>::new( + 4.try_into().unwrap(), + 4.try_into().unwrap(), + *&include_bytes!("../test_data/4_4x4.imgbuf"), + ); + bench.iter(|| unsafe { + for x in 0..16 { + for y in 0..16 { + a.as_mut().overlay_at(&b, x * 4, y * 4); + } + } + }); + assert_eq!( + a.as_ref().buffer, + include_bytes!("../test_results/4x3_at_out.buf") + ); + } + + #[bench] + fn overlay_4on4at(bench: &mut Bencher) { + let mut a: Image<_, 4> = Image::alloc(64, 64); + let b = Image::<&[u8], 4>::new( + 4.try_into().unwrap(), + 4.try_into().unwrap(), + *&include_bytes!("../test_data/4_4x4.imgbuf"), + ); + bench.iter(|| unsafe { + for x in 0..16 { + for y in 0..16 { + a.as_mut().overlay_at(&b, x * 4, y * 4); + } + } + }); + assert_eq!( + a.as_ref().buffer, + include_bytes!("../test_results/4x4_at_out.buf") + ); + } +} diff --git a/test_data/3_4x4.imgbuf b/test_data/3_4x4.imgbuf new file mode 100644 index 0000000..f3a8624 --- /dev/null +++ b/test_data/3_4x4.imgbuf @@ -0,0 +1 @@ +гЎгЎгЎгЎгЎгЎгЎгЎгЎгЎїЫЄїЫЄгЎгЎгЎгЎгЎгЎгЎїЫЄїЫЄїЫЄгЎгЎгЎгЎгЎгЎгЎїЫЄїЫЄгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎїЫЄїЫЄгЎгЎгЎгЎгЎгЎгЎїЫЄїЫЄгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎ \ No newline at end of file diff --git a/test_data/4_180x180.imgbuf b/test_data/4_180x180.imgbuf new file mode 100644 index 0000000..58aabd0 Binary files /dev/null and b/test_data/4_180x180.imgbuf differ diff --git a/test_data/4_4x4.imgbuf b/test_data/4_4x4.imgbuf new file mode 100644 index 0000000..bc6cdf8 --- /dev/null +++ b/test_data/4_4x4.imgbuf @@ -0,0 +1 @@ +жлчџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЎДФџжлчџџџџџџџџџжлчџжлчџџџџџџџџџЎДФџЎДФџжлчџџџџџџџџџжлчџџџџџџџџџЎДФџжлчџжлчџџџџџџџџџџџџџжлчџџџџџЎДФџжлчџџџџџџџџџџџџџџџџџџџџџџџџџЎДФџжлчџџџџџџџџџџџџџжлчџжлчџџџџџЎДФџЎДФџжлчџжлчџжлчџЎДФџжлчџџџџџЎДФџЎДФџЎДФџжлчџЎДФџЎДФџЎДФџжлчџ \ No newline at end of file diff --git a/test_results/3x3_at_out.buf b/test_results/3x3_at_out.buf new file mode 100644 index 0000000..21d0141 --- /dev/null +++ b/test_results/3x3_at_out.buf @@ -0,0 +1 @@ +гЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎїЫЄїЫЄгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎгЎ \ No newline at end of file diff --git a/test_results/4x3_at_out.buf b/test_results/4x3_at_out.buf new file mode 100644 index 0000000..d5d8851 --- /dev/null +++ b/test_results/4x3_at_out.buf @@ -0,0 +1 @@ +жлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџжлчџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџЎДФжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџжлчжлчџџџџџџ \ No newline at end of file diff --git a/test_results/4x4_at_out.buf b/test_results/4x4_at_out.buf new file mode 100644 index 0000000..4dedb62 --- /dev/null +++ b/test_results/4x4_at_out.buf @@ -0,0 +1 @@ +жлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџжлчџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџЎДФџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџжлчџжлчџџџџџџџџџ \ No newline at end of file