diff --git a/src/uu/dd/src/dd.rs b/src/uu/dd/src/dd.rs index def82aafb..8d1c7121a 100644 --- a/src/uu/dd/src/dd.rs +++ b/src/uu/dd/src/dd.rs @@ -66,6 +66,17 @@ struct ReadStat reads_partial: u64, records_truncated: u32, } +impl std::ops::AddAssign for ReadStat +{ + fn add_assign(&mut self, other: Self) + { + *self = Self { + reads_complete: self.reads_complete + other.reads_complete, + reads_partial: self.reads_partial + other.reads_partial, + records_truncated: self.records_truncated + other.records_truncated, + } + } +} struct WriteStat { @@ -73,6 +84,17 @@ struct WriteStat writes_partial: u64, bytes_total: u128, } +impl std::ops::AddAssign for WriteStat +{ + fn add_assign(&mut self, other: Self) + { + *self = Self { + writes_complete: self.writes_complete + other.writes_complete, + writes_partial: self.writes_partial + other.writes_partial, + bytes_total: self.bytes_total + other.bytes_total, + } + } +} type Cbs = usize; @@ -150,6 +172,16 @@ pub enum StatusLevel None, } +/// The value of count=N +/// Defaults to Reads(N) +/// if iflag=count_bytes +/// then becomes Bytes(N) +pub enum CountType +{ + Reads(usize), + Bytes(usize), +} + #[derive(Debug)] enum InternalError { @@ -180,6 +212,7 @@ struct Input non_ascii: bool, ibs: usize, xfer_stats: Option, + count: Option, cflags: IConvFlags, iflags: IFlags, } @@ -194,12 +227,14 @@ impl Input let cflags = parseargs::parse_conv_flag_input(matches)?; let iflags = parseargs::parse_iflags(matches)?; let skip = parseargs::parse_skip_amt(&ibs, &iflags, matches)?; + let count = parseargs::parse_count(&iflags, matches)?; let mut i = Input { src: io::stdin(), non_ascii, ibs, xfer_stats, + count, cflags, iflags, }; @@ -225,6 +260,7 @@ impl Input let cflags = parseargs::parse_conv_flag_input(matches)?; let iflags = parseargs::parse_iflags(matches)?; let skip = parseargs::parse_skip_amt(&ibs, &iflags, matches)?; + let count = parseargs::parse_count(&iflags, matches)?; if let Some(fname) = matches.opt_str("if") { @@ -241,6 +277,7 @@ impl Input non_ascii, ibs, xfer_stats, + count, cflags, iflags, }; @@ -279,7 +316,7 @@ impl Read for Input impl Input { - /// Fills a given obs-sized buffer. + /// Fills a given buffer. /// Reads in increments of 'self.ibs'. /// The start of each ibs-sized read follows the previous one. fn fill_consecutive(&mut self, buf: &mut Vec) -> Result> @@ -317,7 +354,7 @@ impl Input }) } - /// Fills a given obs-sized buffer. + /// Fills a given buffer. /// Reads in increments of 'self.ibs'. /// The start of each ibs-sized read is aligned to multiples of ibs; remaing space is filled with the 'pad' byte. fn fill_blocks(&mut self, buf: &mut Vec, obs: usize, pad: u8) -> Result> @@ -375,23 +412,19 @@ impl Input } /// Force-fills a buffer, ignoring zero-length reads which would otherwise be - /// interpreted as EOF. Does not continue after errors. - /// Note: This may never return. - fn force_fill(&mut self, mut buf: &mut [u8], target_len: usize) -> Result<(), Box> + /// interpreted as EOF. + /// Note: This will not return unless the source (eventually) produces + /// enough bytes to meet target_len. + fn force_fill(&mut self, mut buf: &mut [u8], target_len: usize) -> Result> { - let mut total_len = 0; - - loop + let mut base_idx = 0; + while base_idx < target_len { - total_len += self.read(&mut buf)?; - - if total_len == target_len - { - return Ok(()); - } + base_idx += self.read(&mut buf[base_idx..target_len])?; } - } + Ok(base_idx) + } } struct Output @@ -602,7 +635,7 @@ impl Output /// Splits the content of buf into cbs-length blocks /// Appends padding as specified by conv=block and cbs=N -fn block(buf: Vec, cbs: usize, rstats: &mut ReadStat) -> Vec> +fn block(buf: Vec, cbs: usize, rstat: &mut ReadStat) -> Vec> { let mut blocks = buf.split(| &e | e == '\n' as u8) .fold(Vec::new(), | mut blocks, split | @@ -610,7 +643,7 @@ fn block(buf: Vec, cbs: usize, rstats: &mut ReadStat) -> Vec> let mut split = split.to_vec(); if split.len() > cbs { - rstats.records_truncated += 1; + rstat.records_truncated += 1; } split.resize(cbs, ' ' as u8); blocks.push(split); @@ -683,7 +716,7 @@ fn unblock(buf: Vec, cbs: usize) -> Vec .collect() } -fn conv_block_unblock_helper(mut buf: Vec, i: &mut Input, o: &Output, rstats: &mut ReadStat) -> Result, Box> +fn conv_block_unblock_helper(mut buf: Vec, i: &mut Input, o: &Output, rstat: &mut ReadStat) -> Result, Box> { // Local Predicate Fns ------------------------------------------------- #[inline] @@ -737,7 +770,7 @@ fn conv_block_unblock_helper(mut buf: Vec, i: &mut Input< { // ascii input so perform the block first let cbs = i.cflags.block.unwrap(); - let mut blocks = block(buf, cbs, rstats); + let mut blocks = block(buf, cbs, rstat); if let Some(ct) = i.cflags.ctable { @@ -762,7 +795,7 @@ fn conv_block_unblock_helper(mut buf: Vec, i: &mut Input< apply_ct(&mut buf, &ct); } - let blocks = block(buf, cbs, rstats) + let blocks = block(buf, cbs, rstat) .into_iter() .flatten() .collect(); @@ -860,7 +893,7 @@ fn read_helper(i: &mut Input, o: &mut Output, bsize: us { // Read let mut buf = vec![BUF_INIT_BYTE; bsize]; - let mut rstats = match i.cflags.sync + let mut rstat = match i.cflags.sync { Some(ch) => i.fill_blocks(&mut buf, o.obs, ch)?, @@ -868,9 +901,9 @@ fn read_helper(i: &mut Input, o: &mut Output, bsize: us i.fill_consecutive(&mut buf)?, }; // Return early if no data - if rstats.reads_complete == 0 && rstats.reads_partial == 0 + if rstat.reads_complete == 0 && rstat.reads_partial == 0 { - return Ok((rstats,buf)); + return Ok((rstat,buf)); } // Perform any conv=x[,x...] options @@ -880,12 +913,12 @@ fn read_helper(i: &mut Input, o: &mut Output, bsize: us } if is_conv(&i) || is_block(&i) || is_unblock(&i) { - let buf = conv_block_unblock_helper(buf, i, o, &mut rstats)?; - Ok((rstats, buf)) + let buf = conv_block_unblock_helper(buf, i, o, &mut rstat)?; + Ok((rstat, buf)) } else { - Ok((rstats, buf)) + Ok((rstat, buf)) } } } @@ -935,13 +968,13 @@ fn print_xfer_stats(update: &ProgUpdate) } -/// Generate a progress updater that tracks progress, receives updates, and TODO: responds to signals. +/// Generate a progress updater that tracks progress, receives updates, and responds to signals. fn gen_prog_updater(rx: mpsc::Receiver, xfer_stats: Option) -> impl Fn() -> () { // -------------------------------------------------------------- fn posixly_correct() -> bool { - !env::var("POSIXLY_CORRECT").is_err() + env::var("POSIXLY_CORRECT").is_ok() } // -------------------------------------------------------------- move || { @@ -951,7 +984,7 @@ fn gen_prog_updater(rx: mpsc::Receiver, xfer_stats: Option https://unix.stackexchange.com/questions/179481/siginfo-on-gnu-linux-arch-linux-missing // if let Err(e) = signal_hook::flag::register_usize(signal::SIGINFO, sigval.clone(), signal::SIGINFO as usize) // { @@ -980,12 +1013,9 @@ fn gen_prog_updater(rx: mpsc::Receiver, xfer_stats: Option - { - debug_println!("Internal dd Warning: Error in progress update thread\n\t{}", e); - - continue; - }, + (Err(_), _) => + // recv only fails permenantly + break, }; // Handle signals match sigval.load(Ordering::Relaxed) @@ -1014,17 +1044,64 @@ fn calc_bsize(ibs: usize, obs: usize) -> usize lcm } +/// Calculate the buffer size appropriate for this loop iteration, respecting +/// a count=N if present. +fn calc_loop_bsize(count: &Option, rstat: &ReadStat, wstat: &WriteStat, ibs: usize, ideal_bsize: usize) -> usize +{ + match count + { + Some(CountType::Reads(rmax)) => + { + let rmax: u64 = (*rmax).try_into().unwrap(); + let rsofar = rstat.reads_complete + rstat.reads_partial; + let rremain: usize = (rmax - rsofar).try_into().unwrap(); + cmp::min(ideal_bsize, rremain*ibs) + }, + Some(CountType::Bytes(bmax)) => + { + let bmax: u128 = (*bmax).try_into().unwrap(); + let bremain: usize = (bmax - wstat.bytes_total).try_into().unwrap(); + cmp::min(ideal_bsize, bremain) + }, + None => + ideal_bsize, + } +} + +/// Decide if the current progress is below a count=N limit or return +/// true if no such limit is set. +fn below_count_limit(count: &Option, rstat: &ReadStat, wstat: &WriteStat) -> bool +{ + match count + { + Some(CountType::Reads(n)) => + { + let n = (*n).try_into().unwrap(); + // debug_assert!(rstat.reads_complete + rstat.reads_partial >= n); + rstat.reads_complete + rstat.reads_partial <= n + }, + Some(CountType::Bytes(n)) => + { + let n = (*n).try_into().unwrap(); + // debug_assert!(wstat.bytes_total >= n); + wstat.bytes_total <= n + }, + None => + true, + } +} + /// Perform the copy/convert opertaions. Stdout version // Note: Some of dd's functionality depends on whether the output is actually a file. This breaks the Output abstraction, // and should be fixed in the future. fn dd_stdout(mut i: Input, mut o: Output) -> Result<(), Box> { - let mut rstats = ReadStat { + let mut rstat = ReadStat { reads_complete: 0, reads_partial: 0, records_truncated: 0, }; - let mut wstats = WriteStat { + let mut wstat = WriteStat { writes_complete: 0, writes_partial: 0, bytes_total: 0, @@ -1038,37 +1115,30 @@ fn dd_stdout(mut i: Input, mut o: Output) -> Result<(), tx }; - loop + while below_count_limit(&i.count, &rstat, &wstat) { // Read/Write - match read_helper(&mut i, &mut o, bsize)? + let loop_bsize = calc_loop_bsize(&i.count, &rstat, &wstat, i.ibs, bsize); + match read_helper(&mut i, &mut o, loop_bsize)? { (ReadStat { reads_complete: 0, reads_partial: 0, .. }, _) => break, (rstat_update, buf) => { - let wstats_update = o.write_blocks(buf)?; + let wstat_update = o.write_blocks(buf)?; - rstats = ReadStat { - reads_complete: rstats.reads_complete + rstat_update.reads_complete, - reads_partial: rstats.reads_partial + rstat_update.reads_partial, - records_truncated: rstats.records_truncated + rstat_update.records_truncated, - }; - wstats = WriteStat { - writes_complete: wstats.writes_complete + wstats_update.writes_complete, - writes_partial: wstats.writes_partial + wstats_update.writes_partial, - bytes_total: wstats.bytes_total + wstats_update.bytes_total, - }; - }, + rstat += rstat_update; + wstat += wstat_update; + }, }; // Update Prog prog_tx.send(ProgUpdate { - reads_complete: rstats.reads_complete, - reads_partial: rstats.reads_partial, - writes_complete: wstats.writes_complete, - writes_partial: wstats.writes_partial, - bytes_total: wstats.bytes_total, - records_truncated: rstats.records_truncated, + reads_complete: rstat.reads_complete, + reads_partial: rstat.reads_partial, + writes_complete: wstat.writes_complete, + writes_partial: wstat.writes_partial, + bytes_total: wstat.bytes_total, + records_truncated: rstat.records_truncated, duration: start.elapsed(), })?; } @@ -1088,12 +1158,12 @@ fn dd_stdout(mut i: Input, mut o: Output) -> Result<(), Some(StatusLevel::None) => {}, _ => print_xfer_stats(&ProgUpdate { - reads_complete: rstats.reads_complete, - reads_partial: rstats.reads_partial, - writes_complete: wstats.writes_complete, - writes_partial: wstats.writes_partial, - bytes_total: wstats.bytes_total, - records_truncated: rstats.records_truncated, + reads_complete: rstat.reads_complete, + reads_partial: rstat.reads_partial, + writes_complete: wstat.writes_complete, + writes_partial: wstat.writes_partial, + bytes_total: wstat.bytes_total, + records_truncated: rstat.records_truncated, duration: start.elapsed(), }), } @@ -1105,12 +1175,12 @@ fn dd_stdout(mut i: Input, mut o: Output) -> Result<(), // and should be fixed in the future. fn dd_fileout(mut i: Input, mut o: Output) -> Result<(), Box> { - let mut rstats = ReadStat { + let mut rstat = ReadStat { reads_complete: 0, reads_partial: 0, records_truncated: 0, }; - let mut wstats = WriteStat { + let mut wstat = WriteStat { writes_complete: 0, writes_partial: 0, bytes_total: 0, @@ -1124,37 +1194,30 @@ fn dd_fileout(mut i: Input, mut o: Output) -> Result<(), Box break, (rstat_update, buf) => { - let wstats_update = o.write_blocks(buf)?; + let wstat_update = o.write_blocks(buf)?; - rstats = ReadStat { - reads_complete: rstats.reads_complete + rstat_update.reads_complete, - reads_partial: rstats.reads_partial + rstat_update.reads_partial, - records_truncated: rstats.records_truncated + rstat_update.records_truncated, - }; - wstats = WriteStat { - writes_complete: wstats.writes_complete + wstats_update.writes_complete, - writes_partial: wstats.writes_partial + wstats_update.writes_partial, - bytes_total: wstats.bytes_total + wstats_update.bytes_total, - }; + rstat += rstat_update; + wstat += wstat_update; }, }; // Update Prog prog_tx.send(ProgUpdate { - reads_complete: rstats.reads_complete, - reads_partial: rstats.reads_partial, - writes_complete: wstats.writes_complete, - writes_partial: wstats.writes_partial, - bytes_total: wstats.bytes_total, - records_truncated: rstats.records_truncated, + reads_complete: rstat.reads_complete, + reads_partial: rstat.reads_partial, + writes_complete: wstat.writes_complete, + writes_partial: wstat.writes_partial, + bytes_total: wstat.bytes_total, + records_truncated: rstat.records_truncated, duration: start.elapsed(), })?; } @@ -1174,12 +1237,12 @@ fn dd_fileout(mut i: Input, mut o: Output) -> Result<(), Box {}, _ => print_xfer_stats(&ProgUpdate { - reads_complete: rstats.reads_complete, - reads_partial: rstats.reads_partial, - writes_complete: wstats.writes_complete, - writes_partial: wstats.writes_partial, - bytes_total: wstats.bytes_total, - records_truncated: rstats.records_truncated, + reads_complete: rstat.reads_complete, + reads_partial: rstat.reads_partial, + writes_complete: wstat.writes_complete, + writes_partial: wstat.writes_partial, + bytes_total: wstat.bytes_total, + records_truncated: rstat.records_truncated, duration: start.elapsed(), }), } diff --git a/src/uu/dd/src/dd_unit_tests/block_unblock_tests.rs b/src/uu/dd/src/dd_unit_tests/block_unblock_tests.rs index b0a1ba6fc..eba49f9d0 100644 --- a/src/uu/dd/src/dd_unit_tests/block_unblock_tests.rs +++ b/src/uu/dd/src/dd_unit_tests/block_unblock_tests.rs @@ -24,6 +24,7 @@ macro_rules! make_block_test ( non_ascii: false, ibs: 512, xfer_stats: None, + count: None, cflags: IConvFlags { ctable: None, block: $block, @@ -56,6 +57,7 @@ macro_rules! make_unblock_test ( non_ascii: false, ibs: 512, xfer_stats: None, + count: None, cflags: IConvFlags { ctable: None, block: None, diff --git a/src/uu/dd/src/dd_unit_tests/conv_sync_tests.rs b/src/uu/dd/src/dd_unit_tests/conv_sync_tests.rs index 070fdb217..959cb53fd 100644 --- a/src/uu/dd/src/dd_unit_tests/conv_sync_tests.rs +++ b/src/uu/dd/src/dd_unit_tests/conv_sync_tests.rs @@ -24,6 +24,7 @@ macro_rules! make_sync_test ( non_ascii: false, ibs: $ibs, xfer_stats: None, + count: None, cflags: IConvFlags { ctable: None, block: None, diff --git a/src/uu/dd/src/dd_unit_tests/conversion_tests.rs b/src/uu/dd/src/dd_unit_tests/conversion_tests.rs index b7d7ccb9b..f7ee7f92c 100644 --- a/src/uu/dd/src/dd_unit_tests/conversion_tests.rs +++ b/src/uu/dd/src/dd_unit_tests/conversion_tests.rs @@ -10,6 +10,7 @@ macro_rules! make_conv_test ( non_ascii: false, ibs: 512, xfer_stats: None, + count: None, cflags: icf!($ctable), iflags: DEFAULT_IFLAGS, }, @@ -35,6 +36,7 @@ macro_rules! make_icf_test ( non_ascii: false, ibs: 512, xfer_stats: None, + count: None, cflags: $icf, iflags: DEFAULT_IFLAGS, }, @@ -138,6 +140,7 @@ fn all_valid_ascii_ebcdic_ascii_roundtrip_conv_test() non_ascii: false, ibs: 128, xfer_stats: None, + count: None, cflags: icf!(Some(&ASCII_TO_EBCDIC)), iflags: DEFAULT_IFLAGS, }; @@ -160,6 +163,7 @@ fn all_valid_ascii_ebcdic_ascii_roundtrip_conv_test() non_ascii: false, ibs: 256, xfer_stats: None, + count: None, cflags: icf!(Some(&EBCDIC_TO_ASCII)), iflags: DEFAULT_IFLAGS, }; diff --git a/src/uu/dd/src/dd_unit_tests/mod.rs b/src/uu/dd/src/dd_unit_tests/mod.rs index 8904a2372..eb8af60df 100644 --- a/src/uu/dd/src/dd_unit_tests/mod.rs +++ b/src/uu/dd/src/dd_unit_tests/mod.rs @@ -95,6 +95,7 @@ macro_rules! make_spec_test ( non_ascii: false, ibs: 512, xfer_stats: None, + count: None, cflags: icf!(), iflags: DEFAULT_IFLAGS, }, @@ -116,11 +117,13 @@ macro_rules! make_spec_test ( dd_fileout($i,$o).unwrap(); let res = File::open($tmp_fname).unwrap(); + // Check test file isn't empty (unless spec file is too) assert_eq!(res.metadata().unwrap().len(), $spec.metadata().unwrap().len()); let spec = BufReader::new($spec); let res = BufReader::new(res); + // Check all bytes match for (b_res, b_spec) in res.bytes().zip(spec.bytes()) { assert_eq!(b_res.unwrap(), diff --git a/src/uu/dd/src/dd_unit_tests/sanity_tests.rs b/src/uu/dd/src/dd_unit_tests/sanity_tests.rs index 8724474a0..e9923b4b1 100644 --- a/src/uu/dd/src/dd_unit_tests/sanity_tests.rs +++ b/src/uu/dd/src/dd_unit_tests/sanity_tests.rs @@ -1,5 +1,25 @@ use super::*; +const DST_PLACEHOLDER: Vec = Vec::new(); + +macro_rules! make_io_test ( + ( $test_id:ident, $test_name:expr, $i:expr, $o:expr, $spec:expr ) => + { + make_spec_test!($test_id, + $test_name, + $i, + Output { + dst: File::create(format!("./test-resources/FAILED-{}.test", $test_name)).unwrap(), + obs: $o.obs, + cflags: $o.cflags, + oflags: $o.oflags, + }, + $spec, + format!("./test-resources/FAILED-{}.test", $test_name) + ); + }; +); + make_spec_test!( zeros_4k_test, "zeros-4k", @@ -24,7 +44,7 @@ make_spec_test!( File::open("./test-resources/random-5828891cb1230748e146f34223bbd3b5.test").unwrap() ); -make_spec_test!( +make_io_test!( random_73k_test_not_a_multiple_obs_gt_ibs, "random-73k-not-a-multiple-obs-gt-ibs", Input { @@ -32,20 +52,20 @@ make_spec_test!( non_ascii: false, ibs: 521, xfer_stats: None, + count: None, cflags: icf!(), iflags: DEFAULT_IFLAGS, }, Output { - dst: File::create(format!("./test-resources/FAILED-{}.test", "random-73k-not-a-multiple-obs-gt-ibs")).unwrap(), + dst: DST_PLACEHOLDER, obs: 1031, cflags: DEFAULT_CFO, oflags: DEFAULT_OFLAGS, }, - File::open("./test-resources/random-5828891cb1230748e146f34223bbd3b5.test").unwrap(), - format!("./test-resources/FAILED-{}.test", "random-73k-not-a-multiple-obs-gt-ibs") + File::open("./test-resources/random-5828891cb1230748e146f34223bbd3b5.test").unwrap() ); -make_spec_test!( +make_io_test!( random_73k_test_obs_lt_not_a_multiple_ibs, "random-73k-obs-lt-not-a-multiple-ibs", Input { @@ -53,17 +73,143 @@ make_spec_test!( non_ascii: false, ibs: 1031, xfer_stats: None, + count: None, cflags: icf!(), iflags: DEFAULT_IFLAGS, }, Output { - dst: File::create(format!("./test-resources/FAILED-{}.test", "random-73k-obs-lt-not-a-multiple-ibs")).unwrap(), + dst: DST_PLACEHOLDER, obs: 521, cflags: DEFAULT_CFO, oflags: DEFAULT_OFLAGS, }, - File::open("./test-resources/random-5828891cb1230748e146f34223bbd3b5.test").unwrap(), - format!("./test-resources/FAILED-{}.test", "random-73k-obs-lt-not-a-multiple-ibs") + File::open("./test-resources/random-5828891cb1230748e146f34223bbd3b5.test").unwrap() +); + +make_io_test!( + deadbeef_all_32k_test_count_reads, + "deadbeef_all_32k_test_count_reads", + Input { + src: File::open("./test-resources/deadbeef-18d99661a1de1fc9af21b0ec2cd67ba3.test").unwrap(), + non_ascii: false, + ibs: 1024, + xfer_stats: None, + count: Some(CountType::Reads(32)), + cflags: icf!(), + iflags: DEFAULT_IFLAGS, + }, + Output { + dst: DST_PLACEHOLDER, + obs: 1024, + cflags: DEFAULT_CFO, + oflags: DEFAULT_OFLAGS, + }, + File::open("./test-resources/deadbeef-18d99661a1de1fc9af21b0ec2cd67ba3.test").unwrap() +); + +make_io_test!( + deadbeef_all_32k_test_count_bytes, + "deadbeef_all_32k_test_count_bytes", + Input { + src: File::open("./test-resources/deadbeef-18d99661a1de1fc9af21b0ec2cd67ba3.test").unwrap(), + non_ascii: false, + ibs: 531, + xfer_stats: None, + count: Some(CountType::Bytes(32*1024)), + cflags: icf!(), + iflags: DEFAULT_IFLAGS, + }, + Output { + dst: DST_PLACEHOLDER, + obs: 1031, + cflags: DEFAULT_CFO, + oflags: DEFAULT_OFLAGS, + }, + File::open("./test-resources/deadbeef-18d99661a1de1fc9af21b0ec2cd67ba3.test").unwrap() +); + +make_io_test!( + deadbeef_32k_to_16k_test_count_reads, + "deadbeef_32k_test_count_reads", + Input { + src: File::open("./test-resources/deadbeef-18d99661a1de1fc9af21b0ec2cd67ba3.test").unwrap(), + non_ascii: false, + ibs: 1024, + xfer_stats: None, + count: Some(CountType::Reads(16)), + cflags: icf!(), + iflags: DEFAULT_IFLAGS, + }, + Output { + dst: DST_PLACEHOLDER, + obs: 1031, + cflags: DEFAULT_CFO, + oflags: DEFAULT_OFLAGS, + }, + File::open("./test-resources/gnudd-deadbeef-first-16k.spec").unwrap() +); + +make_io_test!( + deadbeef_32k_to_12345_test_count_bytes, + "deadbeef_32k_to_12345_test_count_bytes", + Input { + src: File::open("./test-resources/deadbeef-18d99661a1de1fc9af21b0ec2cd67ba3.test").unwrap(), + non_ascii: false, + ibs: 531, + xfer_stats: None, + count: Some(CountType::Bytes(12345)), + cflags: icf!(), + iflags: DEFAULT_IFLAGS, + }, + Output { + dst: DST_PLACEHOLDER, + obs: 1031, + cflags: DEFAULT_CFO, + oflags: DEFAULT_OFLAGS, + }, + File::open("./test-resources/gnudd-deadbeef-first-12345.spec").unwrap() +); + +make_io_test!( + random_73k_test_count_reads, + "random-73k-test-count-reads", + Input { + src: File::open("./test-resources/random-5828891cb1230748e146f34223bbd3b5.test").unwrap(), + non_ascii: false, + ibs: 1024, + xfer_stats: None, + count: Some(CountType::Reads(32)), + cflags: icf!(), + iflags: DEFAULT_IFLAGS, + }, + Output { + dst: DST_PLACEHOLDER, + obs: 1024, + cflags: DEFAULT_CFO, + oflags: DEFAULT_OFLAGS, + }, + File::open("./test-resources/gnudd-random-first-32k.spec").unwrap() +); + +make_io_test!( + random_73k_test_count_bytes, + "random-73k-test-count-bytes", + Input { + src: File::open("./test-resources/random-5828891cb1230748e146f34223bbd3b5.test").unwrap(), + non_ascii: false, + ibs: 521, + xfer_stats: None, + count: Some(CountType::Bytes(32*1024)), + cflags: icf!(), + iflags: DEFAULT_IFLAGS, + }, + Output { + dst: DST_PLACEHOLDER, + obs: 1031, + cflags: DEFAULT_CFO, + oflags: DEFAULT_OFLAGS, + }, + File::open("./test-resources/gnudd-random-first-32k.spec").unwrap() ); // Test internal buffer size fn diff --git a/src/uu/dd/src/parseargs.rs b/src/uu/dd/src/parseargs.rs index 96e58ffa2..620f18250 100644 --- a/src/uu/dd/src/parseargs.rs +++ b/src/uu/dd/src/parseargs.rs @@ -3,6 +3,7 @@ mod unit_tests; use crate::conversion_tables::*; use crate::{ + CountType, IConvFlags, OConvFlags, StatusLevel, }; @@ -759,6 +760,27 @@ pub fn parse_seek_amt(obs: &usize, oflags: &OFlags, matches: &getopts::Matches) } } +/// Parse the value of count=N and the type of N implied by iflags +pub fn parse_count(iflags: &IFlags, matches: &getopts::Matches) -> Result, ParseError> +{ + if let Some(amt) = matches.opt_str("count") + { + let n = parse_bytes_with_opt_multiplier(amt)?; + if iflags.count_bytes + { + Ok(Some(CountType::Bytes(n))) + } + else + { + Ok(Some(CountType::Reads(n))) + } + } + else + { + Ok(None) + } +} + /// Parse whether the args indicate the input is not ascii pub fn parse_input_non_ascii(matches: &getopts::Matches) -> Result { diff --git a/src/uu/dd/test-resources/gnudd-deadbeef-first-12345.spec b/src/uu/dd/test-resources/gnudd-deadbeef-first-12345.spec new file mode 100644 index 000000000..c36c9ec7a --- /dev/null +++ b/src/uu/dd/test-resources/gnudd-deadbeef-first-12345.spec @@ -0,0 +1 @@ +­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­ \ No newline at end of file diff --git a/src/uu/dd/test-resources/gnudd-deadbeef-first-16k.spec b/src/uu/dd/test-resources/gnudd-deadbeef-first-16k.spec new file mode 100644 index 000000000..dbd247457 --- /dev/null +++ b/src/uu/dd/test-resources/gnudd-deadbeef-first-16k.spec @@ -0,0 +1 @@ +­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾­Þï¾ \ No newline at end of file diff --git a/src/uu/dd/test-resources/gnudd-random-first-32k.spec b/src/uu/dd/test-resources/gnudd-random-first-32k.spec new file mode 100644 index 000000000..8f42c0a64 Binary files /dev/null and b/src/uu/dd/test-resources/gnudd-random-first-32k.spec differ