From 3c26eeb00a5b97488c511e65605ccf82740b151a Mon Sep 17 00:00:00 2001 From: Dan Davison Date: Thu, 16 Dec 2021 07:13:10 -0500 Subject: Add example diff reproducing #677 --- etc/examples/677-diff-with-binary-data.diff | 236 ++++++++++++++++++++++++++++ 1 file changed, 236 insertions(+) create mode 100644 etc/examples/677-diff-with-binary-data.diff diff --git a/etc/examples/677-diff-with-binary-data.diff b/etc/examples/677-diff-with-binary-data.diff new file mode 100644 index 00000000..2d10bb91 --- /dev/null +++ b/etc/examples/677-diff-with-binary-data.diff @@ -0,0 +1,236 @@ +diff --git a/src/binary.rs b/src/binary.rs +new file mode 100644 +index 0000000..e6627bb +--- /dev/null ++++ b/src/binary.rs +@@ -0,0 +1,230 @@ ++use std::borrow::Cow; ++use std::collections::HashMap; ++use std::io::BufRead; ++use std::io::Write; ++ ++use bytelines::ByteLines; ++ ++use crate::ansi; ++use crate::config::delta_unreachable; ++use crate::config::Config; ++use crate::features; ++use crate::handlers::hunk_header::ParsedHunkHeader; ++use crate::handlers::{self, merge_conflict}; ++use crate::paint::Painter; ++use crate::style::DecorationStyle; ++ ++#[derive(Clone, Debug, PartialEq)] ++pub enum State { ++ CommitMeta, // In commit metadata section ++ DiffHeader(DiffType), // In diff metadata section, between (possible) commit metadata and first hunk ++ HunkHeader(DiffType, ParsedHunkHeader, String, String), // In hunk metadata line (diff_type, parsed, line, raw_line) ++ HunkZero(DiffType, Option), // In hunk; unchanged line (prefix, raw_line) ++ HunkMinus(DiffType, Option), // In hunk; removed line (diff_type, raw_line) ++ HunkPlus(DiffType, Option), // In hunk; added line (diff_type, raw_line) ++ MergeConflict(MergeParents, merge_conflict::MergeConflictCommit), ++ SubmoduleLog, // In a submodule section, with gitconfig diff.submodule = log ++ SubmoduleShort(String), // In a submodule section, with gitconfig diff.submodule = short ++ Blame(String, Option), // In a line of `git blame` output (commit, repeat_blame_line). ++ GitShowFile, // In a line of `git show $revision:./path/to/file.ext` output ++ Grep, // In a line of `git grep` output ++ Unknown, ++ // The following elements are created when a line is wrapped to display it: ++ HunkZeroWrapped, // Wrapped unchanged line ++ HunkMinusWrapped, // Wrapped removed line ++ HunkPlusWrapped, // Wrapped added line ++} ++ ++#[derive(Clone, Debug, PartialEq)] ++pub enum DiffType { ++ Unified, ++ // https://git-scm.com/docs/git-diff#_combined_diff_format ++ Combined(MergeParents, InMergeConflict), ++} ++ ++#[derive(Clone, Debug, PartialEq)] ++pub enum MergeParents { ++ Number(usize), // Number of parent commits == (number of @s in hunk header) - 1 ++ Prefix(String), // Hunk line prefix, length == number of parent commits ++ Unknown, ++} ++ ++#[derive(Clone, Debug, PartialEq)] ++pub enum InMergeConflict { ++ Yes, ++ No, ++} ++ ++impl DiffType { ++ pub fn n_parents(&self) -> usize { ++ use DiffType::*; ++ use MergeParents::*; ++ match self { ++ Combined(Prefix(prefix), _) => prefix.len(), ++ Combined(Number(n_parents), _) => *n_parents, ++ Unified => 1, ++ Combined(Unknown, _) => delta_unreachable("Number of merge parents must be known."), ++ } ++ } ++} ++ ++#[derive(Debug, PartialEq)] ++pub enum Source { ++ GitDiff, // Coming from a `git diff` command ++ DiffUnified, // Coming from a `diff -u` command ++ Unknown, ++} ++ ++// Possible transitions, with actions on entry: ++// ++// ++// | from \ to | CommitMeta | DiffHeader | HunkHeader | HunkZero | HunkMinus | HunkPlus | ++// |-------------+-------------+-------------+-------------+-------------+-------------+----------| ++// | CommitMeta | emit | emit | | | | | ++// | DiffHeader | | emit | emit | | | | ++// | HunkHeader | | | | emit | push | push | ++// | HunkZero | emit | emit | emit | emit | push | push | ++// | HunkMinus | flush, emit | flush, emit | flush, emit | flush, emit | push | push | ++// | HunkPlus | flush, emit | flush, emit | flush, emit | flush, emit | flush, push | push | ++ ++pub struct StateMachine<'a> { ++ pub line: String, ++ pub raw_line: String, ++ pub state: State, ++ pub source: Source, ++ pub minus_file: String, ++ pub plus_file: String, ++ pub minus_file_event: handlers::diff_header::FileEvent, ++ pub plus_file_event: handlers::diff_header::FileEvent, ++ pub diff_line: String, ++ pub painter: Painter<'a>, ++ pub config: &'a Config, ++ ++ // When a file is modified, we use lines starting with '---' or '+++' to obtain the file name. ++ // When a file is renamed without changes, we use lines starting with 'rename' to obtain the ++ // file name (there is no diff hunk and hence no lines starting with '---' or '+++'). But when ++ // a file is renamed with changes, both are present, and we rely on the following variables to ++ // avoid emitting the file meta header line twice (#245). ++ pub current_file_pair: Option<(String, String)>, ++ pub handled_diff_header_header_line_file_pair: Option<(String, String)>, ++ pub blame_commit_colors: HashMap, ++} ++ ++pub fn delta(lines: ByteLines, writer: &mut dyn Write, config: &Config) -> std::io::Result<()> ++where ++ I: BufRead, ++{ ++ StateMachine::new(writer, config).consume(lines) ++} ++ ++impl<'a> StateMachine<'a> { ++ pub fn new(writer: &'a mut dyn Write, config: &'a Config) -> Self { ++ Self { ++ line: "".to_string(), ++ raw_line: "".to_string(), ++ state: State::Unknown, ++ source: Source::Unknown, ++ minus_file: "".to_string(), ++ plus_file: "".to_string(), ++ minus_file_event: handlers::diff_header::FileEvent::NoEvent, ++ plus_file_event: handlers::diff_header::FileEvent::NoEvent, ++ diff_line: "".to_string(), ++ current_file_pair: None, ++ handled_diff_header_header_line_file_pair: None, ++ painter: Painter::new(writer, config), ++ config, ++ blame_commit_colors: HashMap::new(), ++ } ++ } ++ ++ fn consume(&mut self, mut lines: ByteLines) -> std::io::Result<()> ++ where ++ I: BufRead, ++ { ++ while let Some(Ok(raw_line_bytes)) = lines.next() { ++ self.ingest_line(raw_line_bytes); ++ ++ if self.source == Source::Unknown { ++ self.source = detect_source(&self.line); ++ } ++ ++ // Every method named handle_* must return std::io::Result. ++ // The bool indicates whether the line has been handled by that ++ // method (in which case no subsequent handlers are permitted to ++ // handle it). ++ let _ = self.handle_commit_meta_header_line()? ++ || self.handle_diff_stat_line()? ++ || self.handle_diff_header_diff_line()? ++ || self.handle_diff_header_minus_line()? ++ || self.handle_diff_header_plus_line()? ++ || self.handle_hunk_header_line()? ++ || self.handle_diff_header_misc_line()? ++ || self.handle_submodule_log_line()? ++ || self.handle_submodule_short_line()? ++ || self.handle_merge_conflict_line()? ++ || self.handle_hunk_line()? ++ || self.handle_git_show_file_line()? ++ || self.handle_blame_line()? ++ || self.handle_grep_line()? ++ || self.should_skip_line() ++ || self.emit_line_unchanged()?; ++ } ++ ++ self.painter.paint_buffered_minus_and_plus_lines(); ++ self.painter.emit()?; ++ Ok(()) ++ } ++ ++ fn ingest_line(&mut self, raw_line_bytes: &[u8]) { ++ // TODO: retain raw_line as Cow ++ self.raw_line = String::from_utf8_lossy(raw_line_bytes).to_string(); ++ // When a file has \r\n line endings, git sometimes adds ANSI escape sequences between the ++ // \r and \n, in which case byte_lines does not remove the \r. Remove it now. ++ if let Some(cr_index) = self.raw_line.rfind('\r') { ++ if ansi::strip_ansi_codes(&self.raw_line[cr_index + 1..]).is_empty() { ++ self.raw_line = format!( ++ "{}{}", ++ &self.raw_line[..cr_index], ++ &self.raw_line[cr_index + 1..] ++ ); ++ } ++ } ++ if self.config.max_line_length > 0 ++ && self.raw_line.len() > self.config.max_line_length ++ // Do not truncate long hunk headers ++ && !self.raw_line.starts_with("@@") ++ // Do not truncate ripgrep --json output ++ && !self.raw_line.starts_with('{') ++ { ++ self.raw_line = ansi::truncate_str( ++ &self.raw_line, ++ H__PAGEZERO__TEXT@E@E __text__TEXT!,!__stubs__TEXT,,__stub_helper__TEXTX,X,__gcc_except_tab__TEXT`,'`,__const__TEXT !.f !.__cstring__TEXTD AD__ustring__TEXTDD__unwind_info__TEXT Du D__eh_frame__TEXT?E?E__DATA_CONST@E@@E@__got__DATA_CONST@E@E__const__DATA_CONST@EP@Ex__DATAHH__la_symbol_ptr__DATAH`H__data__DATA`H|`H__thread_vars__DATAhIhI__thread_data__DATA@I(@I__thread_bss__DATAhI__common__DATAI__bss__DATA I H__LINKEDIT@I@I"0@I KILI8]I(Ju?Nh P99>XN /usr/lib/dyld#/O8?|Q02   *(@ 8/usr/lib/libiconv.2.dylib `</System/Library/Frameworks/Security.framework/Versions/A/Security hi@/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation 0 /usr/lib/libz.1.dylib h/System/Library/Frameworks/DiskArbitration.framework/Versions/A/DiskArbitration X/System/Library/Frameworks/IOKit.framework/Versions/A/IOKit `i@,/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation 8/usr/lib/libSystem.B.dylib 8/usr/lib/libresolv.9.dylib&|J$)ءJ0 UHAWAVSPIIHt&HH9Ht(HqHtHL\Hu5"Mw1/MtLHHuMwE1HIG1LI_IH[A^A_]UHAWAVAUATSPL7M>IIIH0f.DMLuINIŸIDHHt:IF|uIH!DDMfKt,HtK|,غWIHQHHH)HHB1I+FIFH[A\A]A^A_]f.fUHSPHHwHt H;Hs(HtH{ H[]ԾH[]f.UHAWAVATSIHwHt I>蜾IF(HtOMfHL<@1 H0I9t3ItHtI<_It HtI|FIF Ht#HH4@HtI~[A\A^A_][A\A^A_]f.DUHHwHt5HHOHVHHTHHH!HHtHH)H]龽]f.fUHAVSHHwHt H;落H{HC HC HpHtH{HP[A^]h[A^]IH{Hs L,f.UHSPHHwHt H;!H(HH[]f.DUHHHHHHH)HHBH+WHW]@UHAWAVATSL?M7IIHIfIOIIDHHt9IG|uIH!DDIGJ4 HtJ| SIHQHHH)HHB1I+GIG[A\A^A_]f.@UHAWAVATSL?M7IIIHfIOIIDHHtAIG|uIH!DDIGB| tJ4 HtJ| 苻IHQHHH)HHB1I+GIG[A\A^A_]fDUHAWAVATSL?M7IIIHfIOIIDHHt9IG|uIH!DDIGJ4 HtJ| ӺIHQHHH)HHB1I+GIG[A\A^A_]f.@UHAWAVAUATSPL?M7IIHI%f.DIOIIDHHtSIG|uIH!DDMoKt%HtK|%Kt%HtK|%IHQHHH)HHB1I+GIGH[A\A]A^A_]f.@UHAWAVATSL?M7IIIHfIOIIDHHt9IG|uIH!DDIGJ4 HtJ| #IHQHHH)HHB1I+GIG[A\A^A_]f.@UHAWAVAUATSPL?M7IIHI%f.DIOIIDHHtSIG|uIH!DDMoKt%HtK|%غRKt%HtK|%9IHQHHH)HHB1I+GIGH[A\A]A^A_]f.@UHAWAVAUATSHH7HH2E1HuHMfHuHNHMIEI9IHFB<(uIMH#B(DHFLHH IHL$HtHtI|$кYID$Ht_I\$HL4@E1f.I0M9t7Jt;HtJ<;Jt; HtJ|;@ID$H"HH4@HI|$¶HHQHHH)HHB1H+FHFH[A\A]A^A_]@UHHwHtH?]e]UHtHw HtH]>]f.fUHSPHHwHt H;Hs HtH{H[]H[]f.UHAWAVAUATSPL?M7IIIH%f.DIOIIDHHtbIG|uIH!DDMoKt%HtK|%RK|%KD%KD%HpHtK|%HP*IHQHHH)HHB1I+GIGH[A\A]A^A_]IK|%Kt% L},DUHHHvHt ++HP]鶴]@UHAWAVAUATSHH7HHH}H_HFHEHuL|3fofLsf.DIL ++Dft D`A!1M9sUfAofHÀIft)AA!fHHL,HtHtI}سHuH}HEHFHHHHHHtHH)ǺH[A\A]A^A_]錳H[A\A]A^A_]f.UHAWAVAUATSHL'MHH}H_ID$HENl#fofL{@ft DpA!0fM9sWfAofHIft)AA!fHHHt DHtH< 蹲DH}HEID$@HIIt"HH)ǺLH[A\A]A^A_]rH[A\A]A^A_]UHAWAVAUATSHH7H ++HH}H_HFHEHuLl3fofL{ft DpA!0fM9sxfAofHÀIft)AA!fHHk8L$HtHtI|$Ⱥ觱It$DHtI|$英DsHuH}HEHF8HHHHHtHH)ǺH[A\A]A^A_]9H[A\A]A^A_]f.UHAWAVAUATSHH7HHH}H_HFHEHuLl3fofL{ft DpA!0fM9s|fAofHIft)AA!fHH@HL$HtHtI|$кcIt$DHtI|$GDoHuH}HEHF0HHHtHH)ǺH[A\A]A^A_]H[A\A]A^A_]f.@UHAWAVAUATSH8H7HHhH}H_HFHEHuHD3HEfofL{f.ft P!D@HMf.fI9fAofHÀIftݹ)Љ!ʉUfHHL4HtHtHHtI~кLuIFHtMHMLqHL,@E1IM9t'Kt&HtK<&诮f.HUHJDuDHHH4IDHHzfDHuH}HEHFHHHHHHtHH)ǺH8[A\A]A^A_]H8[A\A]A^A_]DUHAWAVAUATSH8H7HHAH}LoHFHEHuID5HEfAoEfM}f.ft P!D@HMf.fI9fAofIŀIftݹ)Љ!ʉUfHHiI\IHtHH]HHtIHMLHH@E1 ++IL9t'Kt&HtK<&Ϭf.H]HHtHH4@HtH蒬H(HtH uHHHtIHML8HL4@1 fHI9t'ItHtI</f.H]H@HtHH4@HtH8HXHDutHPѫHpDHHh譫DHuH}HEHFHHHHHtHH)ǺH8[A\A]A^A_][H8[A\A]A^A_]f.fUHAWAVAUATSHL'MHH}H_ID$HENl#fofL{@ft DpA!0fM9sWfAofHIft)AA!fHHHt DHtH< 艪DH}HEID$ HIIt"HH)ǺLH[A\A]A^A_]BH[A\A]A^A_]UHAWAVAUATSHH7H!HH}H_HFHEHuLl3fofL{ft DpA!4fM9fAofHÀIftݹ)AA!fHHL$HtHtI|$غsI|$ID$IL$HqDHrI|$HQDD\HuH}HEHF(HHHHHtHH)ǺH[A\A]A^A_]H[A\A]A^A_]HI|$It$Hq,fUHAWAVAUATSH8H7HHxH}H_HFHEHuHD3HEfofL{f.ft P!D@HMf.fI9 fAofHIftݹ)Љ!ʉUfHH@HL4HtHtI~кߧLuIFHtbHMLqHL,@E1f.I0M9t7Kt&HtK<&菧Kt& HtK|&v@HUHJDuDHHH4IDHHz6DHuH}HEHF0HHHtHH)ǺH8[A\A]A^A_]H8[A\A]A^A_]f.UHAWAVAUATSHL'MHH}H_ID$HENl#fofL{@ft DpA!0fM9sWfAofHIft)AA!fHHHt DHtH< DH}HEID$HIIt"HH)ǺLH[A\A]A^A_]ҥH[A\A]A^A_]UHAWAVAUATSPH7HIHMfN|&fAo$fI\$f.@ft DhA!2fL9sTfofIĀHft)AA!fHH @IHDuIfoff*f.@UHAWAVATSH IIIHHGHH!o8fu%fHH!o8fHtfHH!֊0xfoff0I|$uqtmH}ȺL+I$ID$HL!ofufHH!ofHtfHH!ր<0xfoffHIL$I9HNH!D<0D|ID$IL$HHvHIvHtI6I~H|HtH [A\A^A_]HLH,fUHAWAVATSH IIIHHWHH!o:fu%fHH!o:fHtfHH!Ɗ2xfoff2I|$uuVHIL$I9HNH!D<2D|ID$HH vHIvHtI6I~H|HtH [A\A^A_]H}ȺL}+I$IT$HL!o ++fu(f.fHH!o ++fHtfHH!ƀ<2>foff*f.@UHAWAVATSH IIIHHGHH!o8fu%fHH!o8fHtfHH!֊0xfoff0I|$uqtmH}ȺL+I$ID$HL!ofufHH!ofHtfHH!ր<0xfoffHIL$I9HNH!D<0D|ID$IL$HHvHHIv(HtIv HtIvHtIvHtI6I~H|HtH [A\A^A_]HLH,f.UHAWAVAUATSHIAIIHHOHL!o1fЅu @HH!o1fHtfHH!ŠxfoffҊI}uuGHIuI9HrH!D$DdIEHHH)HD|LpH[A\A]A^A_]H}LL+IEIMHL!o1fЅu+f.DHH!o1fHtfHH!€<Mfoff9f.@UHAWAVATSH IIIHHGHH!o8fu%fHH!o8fHtfHH!֊0xfoff0I|$uqtmH}ȺL3+I$ID$HL!ofufHH!ofHtfHH!ր<0xfoffHIL$I9HNH!D<0D|ID$IL$HHHIv HtIvHtIvHtI6I~H|HtH [A\A^A_]HLH,UHAWAVATSH IIIHHGHH!o8fu%fHH!o8fHtfHH!֊0xfoff0I|$uqtmH}ȺLx+I$ID$HL!ofufHH!ofHtfHH!ր<0xfoffHIL$I9HNH!D<0D|ID$IL$HHHH|Ѹ LHH [A\A^A_]HLH軛,UHAWAVATSH IIIHHGHH!o8fu%fHH!o8fHtfHH!֊0xfoff0I|$uqtmH}ȺL#+I$ID$HL!ofufHH!ofHtfHH!ր<0xfoffHIL$I9HNH!D<0D|ID$IL$HHvHHIv(HtIv HtIvHtIvHtI6I~H|HtH [A\A^A_]HLbH2,f.UHAWAVATSH IIIHHGHH!o8fu%fHH!o8fHtfHH!֊0xfoff0I|$uqtmH}LH|+I$ID$HL!ofu @HH!ofHtfHH!ր<0xfoffHIL$I9HNH!D<0D|ID$IL$HHH)HIVHT1INHHIIVHPHHH [A\A^A_]HLH蹘,UHAWAVATSH IIIHHGHH!o8fu%fHH!o8fHtfHH!֊0xfoff0I|$uqtmH}LHջ+I$ID$HL!ofu @HH!ofHtfHH!ր<0xfoffHIL$I9HNH!D<0D|ID$IL$HHk8HIv0HtIv(HtIv HtIvHtIvHtI6I~H|HtH [A\A^A_]HL}H-,DUHAWAVATSH IIIHHWHH!o:fu%fHH!o:fHtfHH!Ɗ2xfoff2I|$uuCHIL$I9HNH!D<2D|ID$HHH)HLt2H [A\A^A_]H}ȺL+I$IT$HL!o ++fu+f.DHH!o ++fHtfHH!ƀ<2Nfoff:f.@UHAWAVATSH IIIHHWHH!o:fu%fHH!o:fHtfHH!Ɗ2xfoff2I~uuHINI9HNH!D<2D|IFHHk7H ++It$/Ht ++It$(Ht ++It$ Ht ++It$Ht ++It$Ht ++I4$I|$H| ++Ht ++H [A\A^A_]H}LH+IIVHL!o ++fu$HH!o ++fHtfHH!ƀ<2foff f.@UHAWAVAUATSPHHt'IHsF1HL$HIqv螂*HCHC HCHC1HHp}HH$I$I$HH)HHHHHɃ?IIIHIpAIIFIr5LHI!IT$MIrMtMt>LLHU藇HU,藁*HCHSHH[A\A]A^A_]LHtGLMt$IN<M)IMBHǾI跔,LsLcL{HC 1럿LLI*뀐UHAWAVATSHPIHFHt%HHFHH}H2}uL}ID$I$LuHEHEHEHEMHEHMHMHELuH;HEHu@$<u-HEHMHH@ID$IT$Mt$IL$ I$1HH!IHuHt LM|$I$LHP[A\A^A_]H'DHu1+IHH}[H{,UHAWAVATSHPIHFHt%HHFHH}H2}uL}ID$I$LuHEHEHEHEMHEHMHMHELuH;HEHu !<u-HEHMHH@ID$IT$Mt$IL$ I$1HHԖ!IHuHt LۄM|$I$LHP[A\A^A_]HDHu1+IHH}H;,UHAWAVSHHHHFHtnHHFL6I>HEHu$"<uSL}I>HEHuغ"<u?H}!Hu?H}L,}uRHE/HC1/HHҕ!HHŕ!HHEHUHHCHHHH[A^A_]HEHMHMHMHMHtHMHUHS HKL{HC1HDHuc+뚐UHAWAVSHHHHFHtnHHFL6I>HEHu$<uSL}I>HEHuغ<u?H}֔!Hu?H}LE$}uRHE/HC1/HH貔!HH襔!HHEHUHHCHHHH[A^A_]HEHMHMHMHMHtHMHUHS HKL{HC1HqDHuC+뚐UHH]"fUH]8fDUHH]fUHAWAVATSL'MtkILMt;I1fH I9t!ItHtHtI|ȁIvHtHtI>[A\A^A_]颁[A\A^A_]fUH]f.UHHwHtH?]e]UHHwHtH?]E]UHSPHHwHt H;!H{tH HH[]H[]ÐUHAVSHH?HtHsHt ++ۀH{HtHs Ht ++迀H{0HtHs8Ht ++裀H{HHtHsPHt ++臀LLHHHtHH4HtI>[A^]N[A^]HL>Hދ,fDUHAWAVATSIHGHtBM&HL<@1f.HI9t ItHtHtI<IFHtHH4@Ht I>Iv HtHtI~[A\A^A_][A\A^A_]fDUHSPHH?HtHsHt ++\H{HtHs HtH[]:H[]UHAWAVATSIHGHt[A\A^A_]~[A\A^A_]fUHAWAVATSIH?IGHHHtLgHHøNLIGHt"HH4HtI?[A\A^A_]>~[A\A^A_]IHt$f.LIHHøuILL衉,fUHHH?HtHpHt ]}]f.UHAWAVAUATSHHH2HOHGHHMH}LwINHMLk81L%MI8H8I9IHwIcLHEHHpHu}f.I|tIGHpHu\fItHtI||I| {IG HpHuifIGHpHOH8|=HOHGHHMH}LIOHMLk8E1L%"LDH8I8M9K7HwIcLHELHpHu}f.K|7tHCHpHu\fKt7HtK|7{K|7 {HC HpHuifHCHpHOH8{=H}HMHGHt$Hk8HtH9H[A\A]A^A_]h{H[A\A]A^A_]Ð8X (HUHHwHtHtH?]{]f.UHAVSHѾHCHtHkpHtH;[A^]z[A^]IHL^,fDUHAWAVATSIH?IGHH@HtLH@8LIGHt"HH4@HtI?[A\A^A_]Hz[A\A^A_]IHt$LIH@uILkL諅,UHHGHtHH4HtH?]y]fDUHHGHtHkpHtH?]y]f.UHHGHtHH4@HtH?]xy]fDUHHGHtHH4HtH?]Hy]fDUHAWAVATSIHGHtBM&HL<@1f.HI9t ItHtHtI<xIFHt"HH4@HtI>[A\A^A_]x[A\A^A_]UHAWAVAUATSHIIH>HEHum<u6H}@!HHu3HALBH=XH8u4H?HH!HI^ILHĘ[A\A]A^A_]H=HHofPfH~HHHh LDpHEHEHEHE(P)M)EHLxf.@HhL$hLpIEIMHEHMMtzLhHEHMIMIEI?HEHu<HUHEHMH@HHLhIMIEH}HhHNHEIF0HEIF(HEIF HEIFHEHMINIFIxLpH]+HHj!IHpHH]t LjvM~IH(HHhHH}Hс,fUHAWAVAUATSHIIH>HDž`H`<u9H`觇!HHu3HALBH=H8u4H?HH!HI^ILH[A\A]A^A_]H=}HH{of fH~HHH}0LEHEHEHEHE( )`)pH!LmfDH H}LK"}>LeIEIMHEHMMLHHEHMHPHJHH}L!}HEIMIUH8H@HMHUHHLHHPHVHHEH8H@IMIEH}H`HHHM觴HH}HHuHsHEIF0HEIF(HxIF HpIFH`HhINIFIH]H]HPHt LsHpI^IIHHHHH`H~,f.UHAWAVAUATSHIIH>HEHu<u6H}!HHu3HALBH=ؓH8u4H?HH蘄!HI^ILHĘ[A\A]A^A_]H=HH蔑ofPfH~HHHh LpHEHEHEHE(P)M)EHLxf.@HhL1hLpIEIMHEHMMtzLhHEHMIMIEI?HEHux<HUHEHMH@HHLhIMIEH}Hh藟HNHEIF0HEIF(HEIF HEIFHEHMINIFIxLpH]+HH!IHpHH]t LpM~IH(HHh?HH}HQ|,fUHAWAVAUATSHxIIH>HDžpHp7<Hp#!HHL}HEHEHLpLhLufDH]HLuLL$pLxHHHIHEHMMJLhHEHMHpHJHALL&p=H]LLx LHHDHH|,HEHMHEHMALmHEHMHUHJHLp HxLHDHHG|,HhHuHUIHHhHHz!HI_ILHx[A\A]A^A_]HEL}IGHEHMIOIGILx LxHpHt L)nL}MwIH}a$HHhHH}Hy,UHAWAVAUATSHIIH>HDž`H`w <u9H`g!HHu3HALBH=H8u4H?HH?!HI^ILH[A\A]A^A_]H==HH;of fH~HHH}0LnEHEHEHEHE( )`)pH!LmfDH H}L}>LeIEIMHEHMMLHHEHMHPHJHH}L}HEIMIUH8H@HMHUHHLHHPHVHHEH8H@IMIEH}H`HHHMgHH}HHuHkHEIF0HEIF(HxIF HpIFH`HhINIFIH]H]HPHt L@kHpI^I HHHHH`Hv,f.UHAWAVAUATSHxIIH>HDžpHp<Hps|!HHL}HEHEHLpLhLufDH]HLuLLpLxHHHIHEHMMJLhHEHMHpHJHALLkp=H]LLx LHHDHHw,HEHMHEHMALmHEHMHUHJHLp HxLHDHHv,HhHuHUIHHhHHz!HI_ILHx[A\A]A^A_]HEL}IGHEHMIOIGILx LxHpHt LyhL}MwIH}HHhHH}Hs,UHAWAVAUATSH(IIL&EHuL<u]HE1tMoHHy!IuHHto<u|HEHuкLt<H}cy!HH}Ln}HEHHIOHH@IGIO1I@IGI/ "gHt\I8AHHIGILH([A\A]A^A_]HHx!HHEHUHEHIGI뿿 g,fUHAWAVATSH IL>EHuȻL<u]HE1tMfHHIx!IuHHt8<u@EHuȺL*<u}EHtFYIF1m eHI8AHH:HEHuȺL<uHM1IFIN1HHw!IFILH [A\A^A_]HEEH5DH DH}+ÿ Bf,fUHAWAVSHL?EHuлL&<u]HE1t1HHv!IuHHt.u3EHuкL<uBEHsd1EE1> dHtcI8AHHIHHmv!IƱHH LH[A^A_]HEEH5EHEH}γ+뿿 e,f.UHAWAVATSH@IIH>EHu<u]HE1tM|$HHu!IuHHt*<u4H}LXa }ucHEID$I$?(-A$1 qcHtwI8AHHID$I$LH@[A\A^A_]HEHH0IL$8HH(IL$0HH IL$(HHIL$ HHIL$HH@ID$IL$1I$릿 c,fDUHAWAVATSH IL>EHuȻL<u]HE1tMfHHyt!IuHHt8<u@EHuȺL:<u}EHtFYIF1m #bHI8AHH:HEHuȺL<uHM1IFIN1HHs!IFILH [A\A^A_]HEEH53DH `HtcI8AHHIHHr!IƱHH LH[A^A_]HEEH5EHEH}+뿿 Ma,f.UHAWAVSPIH?EHu)<u]HE1t1HHq!IuHHt(u*ALEI֨u@H%H141E1: _Ht>I8AHHIHH!HH LH[A^A_]ÿ N`,f.@UHAWAVATSHIL6EHu߻L!<u]HE1tMgHHp!IuHHt8<uEHEHuкL<ugHEIGIG1I@IGI/ ^HtDI8AHHIGILH[A\A^A_]HHCp!IGI׿ &_,fDUHAWAVATSHL?EHu߻L<u]HE1tA1HHo!IuIIEt;Auo!IAuLHAHHHAH LH[A\A^A_]ÿ ],DUHAWAVAUATSH(IIL&EHuL<u]HE1tMoHHn!IuHHto<u|HEHuкLt<H}Cn!HH}L"}HEHHIOHH@IGIO1I@IGI/ \Ht\I8AHHIGILH([A\A]A^A_]HHm!HHEHUHEHIGI뿿 \,fUHAWAVATSHIL6EHu߻LA<u]HE1tMgHH)m!IuHHt8<uEHEHuкL<ugHEIGIG1I@IGI/ ZHtDI8AHHIGILH[A\A^A_]HHl!IGI׿ f[,fDUHAWAVATSH@IIH>EHu!<u]HE1tM|$HH l!IuHHt*<u4H}LU }ucHEID$I$?(W-A$1 YHtwI8AHHID$I$LH@[A\A^A_]HEHH0IL$8HH(IL$0HH IL$(HHIL$ HHIL$HH@ID$IL$1I$릿 &Z,fDUHAWAVATSH IIH>EHu<u]HE1tM|$HHj!IuHHt*<u9H}L}uhHEID$I$DID$I$1 yXHtSI8AHHID$I$LH [A\A^A_]HEHHIL$HH@ID$IL$1I$ʿ Y,fUHAWAVATSH IIH>EHu<u]HE1tM|$HHi!IuHHt*<u9H}L}uhHEID$I$DID$I$1 YWHtSI8AHHID$I$LH [A\A^A_]HEHHIL$HH@ID$IL$1I$ʿ W,fUHAWAVSPIH?EHu<u]HE1t1HHh!IuHHt(u*ALI֨u@H%H141E1: PVHt>I8AHHIHH!HH LH[A^A_]ÿ V,f.@UHAWAVATSHL?EHu߻L<u]HE1tA1HHg!IuIIEt;AuHEHup<rH}_f!HHkMgI9sgL)IGL)H9r%MoK|%Hr8Hs`,MdML*ILHW0+MgMoK|%HsHLt ILI_I?IwH<H)9I_IOIWHUHMIGIGIGH]HEHUHEHUH}H)*}HEHMHMHxH]HUHuHUHuHEHMH}`*IIԿ BSHtkHLxL`HuHtH}(SHHd!HI^ILHh[A\A]A^A_]HEHMINIFI^1ӿ S,HH}GHg^,HH}SHS^,f.UHAWAVAUATSHhIIH>HEHu`<rH}/d!HHkMgI9sgL)IGL)H9r%MoK|%Hr8Hs],MdML*ILH'.+MgMoK|%HsHLt ILI_I?IwH<H9I_IOIWHUHMIGIGIGH]HEHUHEHUH}H*}HEHMHMHxH]HUHuHUHuHEHMH}]*IIԿ QHtkHLxL`HuHtH}PHHb!HI^ILHh[A\A]A^A_]HEHMINIFI^1ӿ Q,HH}H7\,HH}#H#\,f.UHAWAVAUATSPM@LIH?EHu׺<uDmI1At#HHa!HAAH6I>EHuA<uD}I1AtFHHa!HA.HI>EHuAZ<uDeI1AtHHEa!HAHI>EHu׻<u)]H1Lt-H5DHkD1~HH`!HLupAAAA E A 1GH5?DHD(H5*DHDH5DHDt+H°DHH H[A\A]A^A_]UHAWAVAUATSHIMLIH>HEHu<u&H}_!Hu&H}LS}uAHEHH_!HHEHUHID$I$LHĨ[A\A]A^A_]LuHEHpHEHxMtCHpHxHhH`LXHu4H5DHƬDL+wH5sDHD15+bI}HEHu<u&H}^!Hu&H}LX}uXHEHH^!HHEHUHID$I$H`HHLLHUHEHEHEHEHIHEHMHMHxHPHpItNI}EHu=<uNEtTE<tT LHMԈHH5.DHgD+jHH]!]EHtH}L}u HE8H5DHD衜+HuUH5«DHD聜+ID$I$HxHHHPYK~E)0H}L}dHuH5FDHD+E)@I}EHu<u/]t8t5 JHmX.HH\!1IuH5DHD+I}HEHu`<u,H}3\!Hu,H}L}u*HEHHH\!HHEHUHLEHMHMHMHMM^HMHUIT$hIL$`LhLMHXH`HuHUHpHxH}HEHMHMIL$0ID$(I|$ ML$It$IT$(0AD$8(@AD$HMD$XEAD$pA\$qI$ .J,HHpHHXHT,f.UHSH(HMtEH}V}uHEHCHEHMHUHSHKHC1HHH([]H5DH D1蕙+UHAWAVAUATSHIMqMHHx.xuHIEIELHHEHHELuIuH5DHxD+HxHxuCHIEIEMtHuHt LGLHĸ[A\A]A^A_]LHHEHHEL}IuH5DHܦDb+-L}HxA HxuYHL}IEIEMMHuH@LG.H5DHaD1+HHEHHhHHpHHxHHEHHEDHH(S,D}AL}HEHHEHHxHHhHpHHHH(S,HEHE׈IuH5DHYDߖ+Le|H;HDžhHhLe<u6HhW!Hu3HxHxHHHaW!HHHHIEIEMtHHt LCEHHHHEHHH(HH0HMuH(H0IIHEHHEHMHHxHEHMHHHEHHHQ,HxLQ,IIEHHHH}5HH}%HO,f.UHAWAVAUATSPMLIIIALH<HLIAukLH<tzHHLDuGM8LH]ЉMHL!MH(H IA%HL 1IM@IEH5DHD1(H5آDHqDH5âDH\D+I@H@H LH[A\A]A^A_]f.DUHAWAVAUATSHXIMMHH>ƅHO<u6DEt:At7 JBH;D` HHT!E1IHHIu HHHHHHHxHMHUHHxLHHEHHEHHEHHEHHEM(HEHHEHHEHHEHMHHLIuH5]DHD +H;HDžxHx<uHHxR!HuEHHH.H5DHD1oHHR!HHHHIEIEHHt Lh@Ht2H$H5yDHD(+IEIELHX[A\A]A^A_]HHHEHHEHHEHMHHHUHIuH5DHD袐+HHquCHLeIEIEHHHLZ?HHHHHHpHIuH5GDHpD+#HH9 HLeIEIEHpBLMt@I1 H I9t/HpHtHtHtHpH|y>HHHHpL>HHHEHHEHHEHHEHEHEHMHMHEHUHxIuH5DH>DĎ+#HHCHHMIEIEHHLeHEHEHEHHMHQHhHk8E1II8I8L9fJ9HwHHcHHhLDJ|9tID$5Jt9HtHEJ|8<HMJ|9 tID$ ID$HpHxH8<HMbHEHEHEHHMHQHHk8HhE1L%HH8I8L9hJ9HwLIcLHLAJ|9tHC3Jt9HtHEJ|8<HMJ|9 tHC HCHpH{H8;HMeHEHLeHk8HH};HHHMHHMHHMHHMHHMH HMHqI}HMIHMIHMIHMIHMHUIIHHHHHHHHHHHHHHHH HH(HH@HHH8H0HMH`HMHXHxHUHPHHHHIEIE :,HHx6HH÷HH蠾HH}H]E,S_m@UHAWAVAUATSHHMMIHIAMIAILeHHHIHL-HHHoIHLbHHHUIlHL*HHH>IHLHHHuIHLuQHHIMHHHLHHCHSHHH[A\A]A^A_]H5nDHD1耈+HCH5SDHܖDb+HCH55DHDD+HCH5DHD&+HClH5DHD+HCKHHHH HHMHIu;H5DH*D谇+@H5DHD薇+HCHLnubHLuHCHMHHLI6H5 DHD+HCbHHHH HHMHItL6HHuEH5DH%D 諆+HLu ++H5xDHD臆+HCH(H Iu H5CDH̔D ++R+HLHH0<tIu H5DHD +HlLH88PH8HH8<tIu H5DH/D 赅+HLUH@@H@HH@<tIu H5NDHדD ]+HLHHH<tIu H5 DHD+HwLHHH[HHHHP<tIu H5DH:D+HL`HHX<tIu H5lDHD{+HLHPPHPHH`<tIu H5DHD#+HLHXXfHXHHh<tI u H5DHED˃+H*LkH``H`HHp<tI ++u H5dDHDs+HLHhhHhHHx<tI uH5 DHD+H}LHppueHpHH<tI t.LHxxu1HxHH<uVH5DHD蜂+HLuH}HSHHHHs1I t%LHEEuHEHH<u H5 DHD+HzIu H5DHoD+HTLHEE>HEHH<tIt)LfHEEHEHH<u H5nDHD}+HIt)LHEEHEHH<u H5DHD.+HIt)LHEEqHEHH<u H5ЏDHYD߀+H>It)LyHEE"HEHH<u H5DH ++D萀+HIt)L*HEEHEHH<u H52DHDA+HIt)LHEEHEHH<u H5DHlD+HQIt)LHEE5HEHH<u H5DHD+HItL=IIAu H5QDHڍD`+HHHHHHHHH0HK0HH(HK(HH HK HSHsH{Dk8IDc9HK=HHK>HKBHHKCHKGHHKHHKLHHKMHKQHHKRHKVHHKWH(K[H HK\H0K`H8KaH8HKbH@KfH@HKgHHKkHPKlHHHKmHXKqH`KrHPHKsHhKwHXHKxHpK|H`HK}HxHhHHHpHHHxHHHMHHHMHHHMHHHMHHHMHHHMHHHMHHHMHHHMHDHHv,*(&$"  -- cgit v1.2.3