ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccllllllccclllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccclllllllllclllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccclccllccccclllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccclllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccllcccclllclllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccllcclllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccllccllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccllccclllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccllllllllcclclllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccclllllllllcllllllllllllllclllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccclllllllllclllllllllclllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccllllcllllllllllllcllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccclccllllllcllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccllcclllllllllllllllllllcclllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccllllllllllllccllllllllllllllllllllllllllllllllllllllllllllllllllllllcccccccccc:cclccclcccllllllllllllllllllllllllllllllllllllllllllllllllllll
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccclllllllllllllclllllllllllllllllllllllllllllllllllllllllllllllllcc::;:..,;;ccccllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccclcllllllllllllllllllllllllllllllllllllllllllllllllllllllllc,..';::::,;''',,,,;:clllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccclcccclllllcclllllllllllllllllllllllllllllllllllllllllllllllllll::c:,,,;;;;':::;.':,;:;;,,,;:cllllllllllllllllllllllllllllllllllllllllllllllllllllll
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccllcclcclcllllllllllllllllllllllllllllllllllllllllllllllllllllc:clllll::clc,;,,,,;'..:::::c;':;;::::clllllllllllllllllllllllllllllllllllllllllllllll
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccllccclllclllcllllllllllclllllllllllllllllllllllllllllllllllc:clllllllllc::,:;;,,,,.'....,:,,::;''.. .,:;:clllllllllllllllllllllllllllllllllllllllll
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccclcccclccclcccllclllllllllllllllllllllllllllllllllllllllllllllllccllllllllllllll;;clllll,lll;'.'..',;',,;.,.;,:;'..;::cllllllllllllllllllllllllllllllllll
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccllllllllcccllllllllllllllllllllllllllllllllllllllllllclllllllllllllllllllc::lll;lllc:;,...,;;',' ....;,..',,:;;;;,;cllllllllllllllllllllllllllll
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccclcccclcccccccccccccccllllllllllllllllllllllllllllllllllllllllllccllllllllllllllllllllllc::c,:;;::::''. ';:,,.,,;...,''::,:cc,';,,;;;;:clllllllllllllllllllll
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccclccccccccccccccclccclllllllllllllllllllllllllllllllllllllllllcclllllllllllllllllllllllllllc',:lllll,cc;...cl.c;.,;.c:.,;;,,;,,ccc;;:.;:;;;,,,;cllllllcclllll
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccllllllllllllllllllllllllllllllllllllllllllllccllllllllllllllllllllllllllllllll::clll;l;''.'';.,;c;;:.;;lcccl;'.,;;;;,.,;:;;;:ccllllllllllllll
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccclccllllllllllllllllllllllllllllllllllllllllllllccllllllllllllllllllllllllllllllllllllc::l';.::c.,, .;,::::.'lllc;;'.,','',:lllllllllllllllllllllll
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccllllllllllllllllllllllllllllllllllllllllllllllcclllllllllllllllllllllllllllllllllllllllll; ..,,::...,.;:;,.. ',,,;::cllclllllllllllllllllllllllllll
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccclllllllllllllllllllllllllllllllllllllllllllllcllllllllllllllllllllllllllllllllllllllllllll'',,,;,:' ':.'::'.'clllllllllllllllllllllllllllllllllllll
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccclcllllllllllllllllllllllllllllllllllllllllllllcllllllllllllllllllllllllllllllllllllllllllllll;c.,;:c:,.;:c'.,;c:clllllllllllllllllllllllllllllllllllll
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccclccccccclclclclllllllllllllllllllllllllllllllllllllllcllllllllllllllllllllllllllllllllllllllllllllllll,c:..,,:l.cc,';.;c;:lllllllllllllllllllllllllllllllllllll
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccclcccclccllccclclllllllllllllllllllllllllllllllllllllllllclllllllllllllllllllllllllllllllllllllllllllllllllc:l,'..;;c.;,cc;:';c:lllllllllllllllllllllllllllllllllllll
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccllcccccllccccccccllllllllllllllllllllllllllllllllllllllccllllllllllllllllllllllllllllllllllllllllllllllllllc:'.':,.c: .cccllc'';lllllllllllllllllllllllllllllllllllll
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccllccccccccccccclcllllllllllllllllllllllllllllllllllccllllllllllllllllllllllllllllllllllllllllllllllllllll;.:cl:lc.;.:.;lllll.'lllllllllllllllllllllllllllllllllllll
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccllllccccccccccccccllllllllllllllllllllllllllllllllllccllllllllllllllllllllllllllllllllllllllllllllllllllllll:,':lcl:c' ;l,;llc,,;lllloolllllllllllllllllllllllllllllll
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccllllllllllllllllllllllllllllllllllccllllllllllllllllllllllllllllllllllllllllllllllllllllllll:l:.;::c:' ;:c;,;;:o;looolllllllllllllllllllllllllllllllll
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccllccccccccccccccclllllllllllllllllllllllllllllllllccllllllllllllllllllllllllllllllllllllllllllllllllllllllllll;cc,...,cl.cc:,,.,c:,looooooolllllllllllllllllllllllllllll
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccllccccccccccccclllllllllllllllllllllllllllllllllllcllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll;cc,'.';:o.:;,:,,',c;looooolooolooooollollllllllllllllllll
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccllccccccccccccccclllllllllllllllllllllllllllllllllcclllllllllllllllllllllllllllllllllllllllllllllllllllllllllllooo;l,':c;;c, .cl:llc,;;looooooooooooooollollllllllllllllllll
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccllclccllllllllllllllllllllllllllllllllllcllllllllllllllllllllllllllllllllllllllllllllllllllllllloooloooll.',;,',,.' .',;:::;' coooooooooooooooooooolloolooooolooool
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccllllllllllllllllllllllllllllllllllllclllllllllllllllllllllllllllllllllllllllllllllllllllllllolollllcc:. .,.,;lo;' ,',llllc' .:loooooooooooooooooooooooooooooooooo
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccclllclllllllllllllllllllllllllllllllllllcclllllllllllllllllllllllllllllllllllllllllllllllllllllllool:;,,,;::l''';';,,:. .c;.loo,.'colcclooooooooooooooooooooooooooooooo
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccllllllllllllllllllllllllllllllllllllllcclllllllllllllllllllllllllllllllllllllllllllllllll:,',::,,,',,.;:::loo'l'.c';l;, ',;'.:,;l;:oooolcccoooooooooooooooooooooooooooo
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccclllllllllllllllllllllllllllllllllllllllllcclllllllllllllllllllllllllllllllllllllllllllc;,',',;, . ...',,,;',;,,;'c;..',.cl :l:c..'::'.;ccccc::..:lllllllllllllllllllllllll
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccllccccccllllllllllllllllllllllllllllllllllllllllccllllllllllllllllllllllllllllllllllllllllll,.'',.'''. ......,,...'.....'..'....... ........'. .oooool;.,:c::ooooooooooooooooooolll
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccclllllccccllllllllllllllllllllllllllllllllllllllccllllllllllllllllllllllllllllllllllllllllllll;:lc:';;;'...,';;;,,;.',::;''.. ......c;, ,,cl:cc'',.'';cc,.;..,;;.,::cllllllllllllllllll
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccllllccccllllllllllllllllllllllllllllllllllllllllccllllllllllllllllllllllllllllllllllllllllllllll,.';..looool'cc:;,;;'.,:llll:c;.,.';.. . ;:;oooc,''lc,...,;cloocccoolcclooooooooooooooo
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccllcllllllllllllllllllllllllllllllllllllllllllllllcclllllllllllllllllllllllllllllllllllllllllllllll;..,..clooool,cllooooocc:;''''...;;'...... . .,...'.. ,cc'':';:lococ:oddool::loddooodooooo
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccclllllllllllllllllllllllllllllllllllllllllllllcclllllllllllllllllllllllllllllllllllllllllllllll:.....;looooool,coooooooooooooooc. ''''.;;.. . ''.,''. ,;,.',':c:',ll:ddolllo:lccloodddddoo
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccclcccccccclcclclcclllllllllllllllllllllllllllllllllllllllllllllclllllllllllllllllllllllllllllllllollllllllllllc:'.''..coooooooll;coooooooooooooooo,;.,;:c';;. '. ... . ,,..,'. .'....;cloooo:odlc:cloooooo
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccclcllcllllllcllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllolllollllll,'.....:,looooolooo:;oooooooooooooooo,ol. ',l:., ';cc. ..,'. ..'.',.cc:c.:;..';;,.::,,,;;',,;;;
ccccccccccccccccccccccccccccccccccccccccccccccccccclccccccccccccccccccccccccccllllllllllllllllllllllllllllllllllllllllllllllllllllllllcllllllllllllllllllllllllllllllllllllloooooooooc:'. ..',cl,loolloooooc,oooooooooooooood'llc. ..,oo :d;..; .c:.;:'..;;;;::,;.::::',,::';:::::,lolcl
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccclcclllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllloooooooooo:c;..;,;ccol,clloooooool,oooooooooooddodd'ol'...';;: .',o;,:'.;,,odccdddolcc;';:;;c:c,,';cccc:'...',
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccclllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllloololoooooooooooooooolll::.,':ooool::oooooooooo;looooooooooodddo.:..:cc..o; :o;ldl'. :dd:cdddddddo:dddlccccc'......,;;,c:
cccccccccccccccccccccccccccccccccccccccccccccccccccccccclllccclllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllooooooooloooooooooooooooooooooollllcl:;::loollol;oooooooooo;loooooodoooodddl 'lloldd;.. '..ooc..:: ,dd::dddddddl;dddddddddooo;'':oddood
ccccccccccccccccccccccccccccccccccccccccccccccccccclcclllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllloooloooooooooooooooooooooooooooooooolllllollocolclooool,ooolllccc:';loooooddddddddl..cloldo;c. .c;.;:oo;..;ddc:dddddddo;dddddddddoccoo:ddooodd
cccccccccccccccccccccccccccccccccccclcllclcccclclccllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllolloooooooooooooooooooooooooooooooooooooolllllollooolcocoooooo,;c:cllloooolllllododddddddc'o..clc:o:. .,cc.,:''cc,ddc:dddddddo;ddddddo:.,oddo;ooodddd
ccccccccccccccccccccccccccccccclllllllllcllllcllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllollollollloloooooooooooooooooooooooooooooooooooooooooooolllllolloooooolocoooolc;,cooooooooooooodollllodddd:,dd'..,;.,; 'l:c:..;odl'ddl:oooooooolododo:.;odoooo;odddddd
ccccccccccccccccccccccccclccccccllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllooooooooollooooooooooooooooooooooooooooooooooooooooooooooolllllolloooooooolocooolclcoooooooooooooooodddddollcc''cc,. .,:oc ,d:',,,.cdo.dooodddddddddddoocodddodddo;ddddddd
ccccccccccccccccccccclllclllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllloloooooooooooooooooollooooooooooooooooooooooooooooooooooooooooooooooolllllollooooooooooollooococooooooooooooooooodddddddddd,;o,..;.'l;; .,cd:c:c''o.oddddddddddddoldddodddddddd:ddddddo
ccccccccccccccccccclllllllllllllllllllllllllllllllllllllllllllllllolloooollllolllllooolollooooolooooooooooooooooooollooooooooooooooooooooooooooooooooooooooooooooooollllloloooooooooooooololococooooooooooooodddoddddddddddd,;.';l:l;.o: :o;odddc'..ddddddddddooldddddodddddddd;ooooood
llllllllllllllllllllllllllllllllllllllllllllllllllllllloolooloolooooooooolooooooooooolooooooooooooooooooooooooooollooooooooooooooooooooooooooooooooooooooooooooooollllloloooooooooooooooooll:llloooooddodddodddddddddddddddd..lololddl.. '..odddddd' oddddddoodddddddddoodddddoooddddddd
llllllllllllllllllllllllllllllllllllllllllllllllllllloooooooooooooooooooooooooooooooooooooooooooooooooooooooooollooooooooooooooooooooooooooooooooooooooooooooooololllolooooooooooooooooooooloooodddddddddddddddddddddddddddo..'oloodo:l. .l:.cdddl'..oddddooddddddddddddooddoodddddddddd
llllllllllllllllllllllllllllllllllllllllllllllllllllooooooooooooooooooooooooooooooooooooooooooooooooooooooooollooooooooooooooooooooooooooooooooooooooooooooooololloolooooooooooooddoddoddddddddddddddddddddddddddddddddddood.o;.,loc:o;. .ldo.,o,.'o'ldooddddddddddddddddddddddddddddddd
lllllllllllllllllllllllllllllllllllllllllllllllllooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooollooloooooooooooddddddddddddddddddddddddddddddddddddddddoodddd.ddc .'c;'cl ,l:lo. ':dd,cddddddxxdddddddddddddddddddddddddd
lllllllllllllllllllllllllllllllllllllllllllolloooolooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooollooooooodododddddddddddddddddddddddddddddddddddddddddddoodddddd.dxo;...'dxo ,xd,.,,.;dd;:xxxxxxxxxxdddddddddddddddddddddddd
lllllllllllllllllllllllllllllllllllllllllllooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooolloooooooddddddddddddddddddddddddddddddddddddddddddddddoodddddxxxo.xd;..,.c::l ,;.co,;:..d::xxxxxxxxxxxxxddddddddddddddddddddd
lllllllllllllllllllllllllllllllllllllllllloooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooodooooooooooooooooooooolloooooooddddddddddddddddddddddddddddddddddddddddddddddoodddddxxxxxl'o..,cl:.:o, :dc:dxoc'.';xxxxxxxxxxxxdddddddddddddddddddddd
lllllllllllllllllllllllllllllllllllllllolooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooodddddddooooooodoooooloooooodddddddddddddddddddddddddddddddddddddddddddddddooddddddxxxxxxxc..cooldxd.', ..,lxxxxxo; .dxxxxxxxxxxxxddddddddddddddddddddd
llllllllllllllllllllllllllllllllllllooolooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooodddoddoodddddddddddddddddddooooloooooddddddddddddddddddddddddddddddddddddddddddddddddodddddddddxxxxxxx; :xoolxxxc'. .;.;xxxxxxc..dxxxxxxxxxdddddddddddddddddddddddd
llllllllllllllllllllllllllllllooloooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooddddddddddddddddddddddddddddddddooollooooddddddddddddddddddddddddddddddddddddddddddddddddooddddddddddddxxxxxd;;,':olxo:ld' 'xx;'oxxl'.c.xxxxxxxxdddddddddddddddddddddddddd
lllllllllllllllllllllllollolloooloooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooodoooddoooddddddddddddddddddddddddddddddooolloooodddddddddddddddddddddddddddddddddddddddddddddddoooddddddddddddddxddxxx,cdc.'cc:o;., .;ldl.;,,;dd.dxxxxxxddxdddddddddddddddddddddddd
llllllllllllllllllllloollooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooddddoddddddddddddddddddddddddddddooolloooddddddddddddddddddddddddddddddddddddddddddddddddoodddddddddddddddxxxxxxxx':lo:...''ldl ,xo;;...,lll.dxxxxxxxxxxxdddddddddddddddddddddd
lllllllllllllllllllllllooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooododoooddddddddddddddddddddddddddoooloooodddddddddddddddddddddddddddddddddddddddddddddddooddddddddddddddddxxxxxxxxxd.:oo:,. ,:dxl ,xo'',.'.;lc.oxxxxxxxxxxxxxxxdddddddddddddddddd
lllllllllllllllllloolooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooddoddddddddddddddddddddddddoooloooodddddddddddddddddddddddddddddddddddddddddddddddoodddddddddddddddxxdxxxxxxdddd.cx:...,.:c,: .';ol:':c',d lxxxxxxxxxxxxxxxxxdddddxxxddddddxx
llllllllllllllllllooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooddoooooooodddddodddddddddddddddddddoooolooodddddddddddddddddddddddddddddddddddddddddddddddooddddddddddddddddddxxdxxxddddxxd c''cd,lo.,c. :l:cx,do:'. cxxxxxxxxxxxxxxxxxxxdxxxxxxxxdxxxx
lllllllllllllloooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooddooooooooddooddddddddddddddddddddddooccloooddddddddddddddddddddddddddddddddddddddddddddddooddddddddddddddddddddxxxxxddddxxxxc .:l:c,:;;,.. ..,llc;ccc:. ,dxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
llllllollllloolloooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooddddddddddddddddddddddddooolccloddddddddddddddddddddddddddddddddddddddddddddddooddddddddddddddddddddxxxxddddxxxolll' .c;''.;ll:;. .:.,locoool' .:loxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
llllllloollloooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooddddddddddddddddddddddoooloooodddddddddddddddddddddddddddddddddddddddddddddooddddddddddddddddddddxxxxddddxdlllloxxo:.;.cl::,o:ll. .;oc.oxxd:.';;xxdllldxxxxxxxxxxxxxxxxxxxxxxxxxx
llloooooooollloooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooodddddddddddddddddddoooloooddddddddddddddddddddddddddddddddddddddddddddddodddddddddddddddddddddxxxddddolllc,:l:;c;;:'xd..;l:'l;,: .,,:;.;:,,cxc,xxxxxxolloxxxxxxxxxxxxxxxxxxxxxxx
oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooodddddddddddddddddddooooooodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddxdocc,..':cc:,c:oxxlx;'oxx;..:;':xo ,xo:;....cooc'xxxxxxxxxdllldxxxxxxxxxxxxxxxxxxx
ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooddddddddddddddddddoooloooodddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddolccc,:,',,;: .. ...',':,';..',;,...;llcl ,xx:,;,;..';;.oododc,clccc:..codddddddddddddddd
ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooddddddddddddddddddddddoooooooodddddddddddddddddddddddddddddddddddddddddddoddddddddddddddddddd;.;,;'' ...... ',,.';c,cc:,..;.... .... ....''..'. c .'::;.':lccl:l;dolccodddddddddddd
ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooodddddddddddddddddddddddoooooooddddddddddddddddddddddddddddddddddddddddddddoddddddddddddddddddddd::lc;.lddolc::,.',;:;;c,ccccc.'.,;..,:',' .. 'c:;odo;. ...:;.,,..'coo:ld;ddddoccccddddddddd
oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooodooddddddddddddddddddddoooooooodddddddddddddddddddddddddddddddddddddddddddooddddddddddddddddddddddo' .;.'dddxxxxxd::dddoc:,;,.',, .;lc,, .. .,,....',. ,:;'oc;,ll;oxx:xxxxdooccllldxxxxx
oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooddoodddoddddddddddddddddddooooooooddddddddddddddddddddddddddddddddddddddddddoodddddddddddddddddddddddo,.....cddddxxxxxxl;dxxxxxxxxxxxd; ,,'.'.:;,'. ....,:',,,,. .,,:,,,...';lo:xdoodxxolxxxolloxx
oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooodddodddddoddddddddddddddddddlooodooddddddddddddddddddddddddddddddddddddddddddoodddddddddddddddddddddddcc. '. ,ddddxxxxxxxxo;dxxxxxxxxxxxxx...xxccc,o:.. c; ...;co;. .;:,. ... .:dxxxxdcxxxxdl;,o
Fallow TypeScript analysis cover Fallow is a codebase analyzer written in Rust for TypeScript and JavaScript projects, created by Bart Waardenburg . I’m an open source contributor to the project. It finds unused files, dead exports, unlisted dependencies, code duplication, circular dependencies, and complexity hotspots. It’s a Rust alternative to Knip .
On real-world projects, it runs 6-46x faster than Knip with 4-11x less memory. It analyzes Next.js (20,000+ files) in 1.5 seconds, where Knip doesn’t even finish. Here’s how the internals work.
No TypeScript Compiler# The biggest performance decision was avoiding the TypeScript compiler entirely. Knip runs through tsc to build a type-checked AST. This is thorough but expensive — you’re paying for type checking, declaration merging, and module resolution that a dead-code detector doesn’t need.
Fallow uses Oxc , a Rust-native parser for JavaScript and TypeScript. Oxc parses syntax into an AST and provides scope-aware binding analysis through oxc_semantic, but it doesn’t do type checking. For dead code detection, you need to know “what does this file export?” and “what does this file import?” — both are syntactic questions. You don’t need to resolve types to answer them.
The tradeoff: Fallow can’t detect unused type-narrowing exports or exports that are only used via type inference. In practice, these are rare enough that the 10-40x speedup is worth it. This was an intentional design decision by the project’s creator.
Cache-Friendly Edge Storage# The module graph is the core data structure. Each file is a ModuleNode, and edges represent imports between files. The naive approach is storing edges as Vec<Edge> per node (adjacency list). This scatters edge data across the heap, killing cache performance during traversal.
Fallow stores all edges in a single contiguous Vec<Edge>, with each module node holding a Range<usize> into that array:
pub struct ModuleNode {
pub file_id: FileId ,
pub path: PathBuf ,
pub edge_range: Range < usize > , // range into flat edges array
pub exports: Vec< ExportSymbol> ,
pub re_exports: Vec< ReExportEdge> ,
pub is_entry_point: bool ,
pub is_reachable: bool ,
// ...
}
When you traverse a module’s imports, you’re iterating over a contiguous slice of memory. The CPU prefetcher loves this. It’s the same pattern game engines use for entity-component systems — structure of arrays instead of array of structures.
The project also enforces compile-time size assertions to prevent accidental bloat:
#[cfg(target_pointer_width = "64" )]
const _: () = assert! (std::mem::size_of::< ModuleNode> () == 104 );
const _: () = assert! (std::mem::size_of::< SymbolReference> () == 16 );
If someone adds a field that bumps the size, the build fails. This catches memory regressions before they become performance regressions.
Suffix Array Clone Detection# Code duplication detection usually involves pairwise comparison — compare every pair of code blocks for similarity. That’s O(n^2) and falls apart on large codebases.
Fallow uses suffix arrays instead. The approach:
Tokenize each source file into a sequence of abstract tokens (identifiers normalized, literals replaced with type markers)Concatenate all token sequences with sentinel separators between filesBuild a suffix array over the concatenated sequence using O(N log N) prefix-doubling with radix sortCompute the LCP array (Longest Common Prefix) to find maximal repeated subsequencesExtract clone families from LCP runs that span different filesThis finds all duplicated code blocks across the entire codebase in a single pass. No pairwise comparison. The suffix array construction is the expensive part, but it’s O(N log N) where N is the total token count, not O(files^2).
On Next.js with 20,000 files, duplication detection completes in about 3 seconds. jscpd (the standard JavaScript duplicate detector) takes 24 seconds on the same codebase.
Rayon Parallelism with Incremental Caching# Parsing is embarrassingly parallel — each file is independent. Fallow uses Rayon to parse files across all available CPU cores. On my M-series Mac with 10 cores, this alone cuts parsing time by ~6x.
But cold parsing is still the bottleneck for large projects. Fallow’s caching layer stores parsed results keyed by file content hash. On subsequent runs, only modified files get re-parsed. This turns a 1.5-second cold analysis into a ~200ms warm analysis, because most files don’t change between runs.
The cache key is a content hash, not a timestamp. This means renaming a file without changing its content doesn’t invalidate the cache, and two files with identical content share a cache entry.
84 Framework Plugins, Zero Config# Fallow ships with 84 plugins that detect framework-specific patterns (Next.js page routes, Storybook stories, Vitest test files, Tailwind configs, etc.) and mark the relevant files as entry points. Without this, a dead-code detector would flag your pages/index.tsx as unused because nothing explicitly imports it.
The plugins are auto-detected from package.json dependencies — no configuration required. If you have next in your dependencies, Fallow knows that files matching app/**/page.tsx are entry points. This is what makes zero-config work on real projects.
Real Numbers# Benchmarked on Apple M5, 32GB RAM, median of 5 runs:
Project Files Fallow Knip v5 Speedup Fallow RSS Knip RSS zod 174 19ms 639ms 34x 21 MB 250 MB fastify 286 24ms 1.13s 46x 27 MB 289 MB vue/core 522 63ms 702ms 11x 34 MB 271 MB svelte 3,337 325ms 1.93s 6x 67 MB 460 MB next.js 20,416 1.48s (crashes) – 194 MB –
Knip v5 can’t analyze Next.js at all (exits with errors). Fallow handles it in under 2 seconds using less memory than Knip uses on a project 1/10th the size.
The performance comes from the combination of all these decisions: no type checker, cache-friendly data structures, suffix arrays for duplication, parallel parsing, and incremental caching. No single trick — just consistently choosing the faster approach at every layer of the pipeline. Contributing to a codebase with this level of performance engineering has been one of the best learning experiences for writing fast Rust.