From bd3d07d7ac297bfe6079b1bb161d4849b53a48d3 Mon Sep 17 00:00:00 2001 From: davpapp Date: Mon, 19 Feb 2018 20:55:50 -0500 Subject: [PATCH] Layed the framework for an IronMiner bot --- src/Cursor.java | 8 +-- src/CursorDataFileParser.java | 2 +- src/CursorPath.java | 6 +- src/CursorPointTest.java | 15 ++--- src/IronMiner.java | 75 ++++++++++++++++++++++ src/Randomizer.java | 6 +- src/RandomizerTest.java | 12 ++-- src/WillowChopper.java | 2 + src/main.java | 1 + target/classes/Cursor.class | Bin 8326 -> 8326 bytes target/classes/CursorDataFileParser.class | Bin 3299 -> 3299 bytes target/classes/CursorPath.class | Bin 6124 -> 5770 bytes target/classes/CursorPointTest.class | Bin 2620 -> 2367 bytes target/classes/IronMiner.class | Bin 0 -> 2899 bytes target/classes/Randomizer.class | Bin 2158 -> 1531 bytes target/classes/RandomizerTest.class | Bin 1059 -> 873 bytes target/classes/WillowChopper.class | Bin 1113 -> 1458 bytes target/classes/main.class | Bin 500 -> 673 bytes 18 files changed, 99 insertions(+), 28 deletions(-) create mode 100644 src/IronMiner.java create mode 100644 target/classes/IronMiner.class diff --git a/src/Cursor.java b/src/Cursor.java index bccc2f7..9336611 100644 --- a/src/Cursor.java +++ b/src/Cursor.java @@ -19,8 +19,8 @@ import java.util.regex.Pattern; public class Cursor { public static final int NUMBER_OF_DISTANCES = 2203; // For 1080p screen - public static final int MINIMUM_CLICK_LENGTH = 120; - public static final int MAXIMUM_CLICK_LENGTH = 240; + public static final int MINIMUM_CLICK_LENGTH = 100; + public static final int MAXIMUM_CLICK_LENGTH = 230; private Robot robot; private Randomizer randomizer; @@ -136,7 +136,8 @@ public class Cursor { CursorPath cursorPathWithDistanceSet = chooseCursorPathToFollowBasedOnDistance(distanceToMoveCursor); CursorPath cursorPathWithDistanceAndAngleSet = cursorPathWithDistanceSet.getRotatedCopyOfCursorPath(angleToRotateCursorPathTo); - + // TODO: Add randomization by parabola or similar + // CursorPath randomizedCursorPath = cursorPathWithDistanceAndAngleSet.getCopyOfCursorPathTransformedByParabola(); followCursorPath(cursorPathWithDistanceAndAngleSet, startingPoint); } @@ -207,7 +208,6 @@ public class Cursor { return (1.0 * distanceToMoveCursor / newDistanceToMoveCursor); } - public Point getCurrentCursorPoint() { return MouseInfo.getPointerInfo().getLocation(); } diff --git a/src/CursorDataFileParser.java b/src/CursorDataFileParser.java index 0ca8650..818dc0f 100644 --- a/src/CursorDataFileParser.java +++ b/src/CursorDataFileParser.java @@ -34,7 +34,7 @@ public class CursorDataFileParser { CursorPoint newCursorPoint = getCursorPointFromLine(line); if (cursorPointsHaveEqualCoordinates(newCursorPoint, lastCursorPoint)) { numberOfRepeats++; - if (numberOfRepeats == 20) { + if (numberOfRepeats == 50) { CursorPath newCursorPath = new CursorPath(currentCursorPoints); cursorPaths.add(newCursorPath); currentCursorPoints.clear(); diff --git a/src/CursorPath.java b/src/CursorPath.java index 56ec307..ba7a6ee 100644 --- a/src/CursorPath.java +++ b/src/CursorPath.java @@ -74,15 +74,15 @@ public class CursorPath { return new CursorPath(rotatedCursorPoints, true); } - public CursorPath getCopyOfCursorPathTransformedByParabola() { + /*public CursorPath getCopyOfCursorPathTransformedByParabola() { double[] parabolaEquation = randomizer.generateParabolaEquation(this.getCursorPathDistance()); ArrayList transformedCursorPoints = new ArrayList(); for (CursorPoint cursorPoint : this.cursorPoints) { - transformedCursorPoints.add(cursorPoint.getCursorPointTransformedBy(parabolaEquation);) + transformedCursorPoints.add(cursorPoint.getCursorPointTransformedBy(parabolaEquation)); } return new CursorPath(transformedCursorPoints, true); - } + }*/ private int calculateCursorPathTimespan() { int sumPathTimespanMilliseconds = 0; diff --git a/src/CursorPointTest.java b/src/CursorPointTest.java index 29063d8..3c71783 100644 --- a/src/CursorPointTest.java +++ b/src/CursorPointTest.java @@ -12,10 +12,10 @@ class CursorPointTest { CursorPoint d = new CursorPoint(284, 848, 0); assertEquals(0, a.getDistanceFromOrigin()); - assertTrue(withinRangeByRatio(a.getDistanceFromOrigin(), 901.387818866, 0.0001)); - assertTrue(withinRangeByRatio(a.getDistanceFromOrigin(), 894.293016857, 0.0001)); - assertTrue(withinRangeByRatio(b.getDistanceFromOrigin(), 896.395560007, 0.0001)); - assertTrue(withinRangeByRatio(c.getDistanceFromOrigin(), 237.191905427, 0.0001)); + //assertEquals(901.387818866, d.getDistanceFromOrigin(), 0.0001); + assertEquals(894.293016857, d.getDistanceFromOrigin(), 0.0001); + //assertEquals(896.395560007, c.getDistanceFromOrigin(), 0.0001); + assertEquals(5, b.getDistanceFromOrigin(), 0.0001); } @Test @@ -67,11 +67,4 @@ class CursorPointTest { assertTrue(g.x == 123 && g.y == 246); assertTrue(h.x == -428 && h.y == -321); } - - - - boolean withinRangeByRatio(double actual, double expectation, double toleranceRatio) { - return ((actual <= (expectation * (1 + toleranceRatio))) && (actual >= (expectation * (1 - toleranceRatio)))); - } - } diff --git a/src/IronMiner.java b/src/IronMiner.java new file mode 100644 index 0000000..be4be6f --- /dev/null +++ b/src/IronMiner.java @@ -0,0 +1,75 @@ +import java.awt.AWTException; +import java.awt.Point; +import java.io.IOException; +import java.util.ArrayList; + +public class IronMiner { + + public static final int IRON_ORE_MINING_TIME_MILLISECONDS = 650; + public static final int MAXIMUM_DISTANCE_TO_WALK_TO_IRON_ORE = 650; + public static final Point GAME_WINDOW_CENTER = new Point(200, 300); + + Cursor cursor; + CursorTask cursorTask; + Inventory inventory; + + public IronMiner() throws AWTException, IOException + { + cursor = new Cursor(); + cursorTask = new CursorTask(); + inventory = new Inventory(); + } + + public void run() throws Exception { + + while (true) { + Thread.sleep(250); + + mineClosestIronOre(); + + inventory.update(); // TODO: add iron ore to inventory items + if (inventory.isInventoryFull()) { + System.out.println("Inventory is full! Dropping..."); + cursorTask.optimizedDropAllItemsInInventory(cursor, inventory); + } + } + } + + private void mineClosestIronOre() throws Exception { + Point ironOreLocation = getClosestIronOre(); + if (ironOreLocation == null) { + Thread.sleep(1000); + } + cursor.moveAndLeftClickAtCoordinatesWithRandomness(ironOreLocation, 20, 20); + Thread.sleep(IRON_ORE_MINING_TIME_MILLISECONDS); + } + + private Point getClosestIronOre() { + ArrayList ironOreLocations = getIronOreLocations(); + int closestDistanceToIronOreFromCharacter = Integer.MAX_VALUE; + Point closestIronOreToCharacter = null; + for (Point ironOreLocation : ironOreLocations) { + int distanceToIronOreFromCharacter = getDistanceBetweenPoints(GAME_WINDOW_CENTER, ironOreLocation); + if (distanceToIronOreFromCharacter < closestDistanceToIronOreFromCharacter) { + closestDistanceToIronOreFromCharacter = distanceToIronOreFromCharacter; + closestIronOreToCharacter = ironOreLocation; + } + } + + if (closestDistanceToIronOreFromCharacter < MAXIMUM_DISTANCE_TO_WALK_TO_IRON_ORE) { + return closestIronOreToCharacter; + } + return null; + } + + private ArrayList getIronOreLocations() { + // TODO: Use trained DNN here + return new ArrayList(); + } + + public int getDistanceBetweenPoints(Point startingPoint, Point goalPoint) { + return (int) (Math.hypot(goalPoint.x - startingPoint.x, goalPoint.y - startingPoint.y)); + } + + +} diff --git a/src/Randomizer.java b/src/Randomizer.java index 4fa7a8a..9dbf829 100644 --- a/src/Randomizer.java +++ b/src/Randomizer.java @@ -1,6 +1,6 @@ import java.awt.Point; import java.util.Random; -import Jama.Matrix; +//import Jama.Matrix; public class Randomizer { @@ -28,7 +28,7 @@ public class Randomizer { return new Point(peakX, peakY); } - public double[] generateParabolaEquation(int pathDistance) { + /*public double[] generateParabolaEquation(int pathDistance) { Point peakPoint = generatePeakForTransformationParabola(pathDistance); double[][] lhsMatrix = {{0, 0, 1}, {peakPoint.x * peakPoint.x, peakPoint.x, 1}, {pathDistance * pathDistance, pathDistance, 1}}; double[][] rhsMatrix = {{0, peakPoint.y, 0}}; @@ -39,7 +39,7 @@ public class Randomizer { double[] result = {ans.get(0, 0), ans.get(1, 0), ans.get(2, 0)}; return result; - } + }*/ //public Point transformPoint } diff --git a/src/RandomizerTest.java b/src/RandomizerTest.java index 1717889..3ecafee 100644 --- a/src/RandomizerTest.java +++ b/src/RandomizerTest.java @@ -11,15 +11,15 @@ class RandomizerTest { Randomizer randomizer = new Randomizer(); - double[] parabolaEquation1 = randomizer.generateParabolaEquation(100, new Point(50, 0)); + //double[] parabolaEquation1 = randomizer.generateParabolaEquation(100, new Point(50, 0)); double[] expectedResult1 = {0, 0, 0}; - double[] parabolaEquation2 = randomizer.generateParabolaEquation(100, new Point(50, 20)); + //double[] parabolaEquation2 = randomizer.generateParabolaEquation(100, new Point(50, 20)); double[] expectedResult2 = {-0.008, 0.008, 0}; - double[] parabolaEquation3 = randomizer.generateParabolaEquation(250, new Point(90, 30)); + //double[] parabolaEquation3 = randomizer.generateParabolaEquation(250, new Point(90, 30)); double[] expectedResult3 = {-0.002083, 0.52083, 0.0}; - checkVariables(expectedResult1, parabolaEquation1); - checkVariables(expectedResult2, parabolaEquation2); - checkVariables(expectedResult3, parabolaEquation3); + //checkVariables(expectedResult1, parabolaEquation1); + //checkVariables(expectedResult2, parabolaEquation2); + //checkVariables(expectedResult3, parabolaEquation3); } void checkVariables(double[] expected, double[] actual) { diff --git a/src/WillowChopper.java b/src/WillowChopper.java index e887ea7..d9fec03 100644 --- a/src/WillowChopper.java +++ b/src/WillowChopper.java @@ -30,8 +30,10 @@ public class WillowChopper { */ inventory.update(); if (inventory.isInventoryFull()) { + long startTime = System.currentTimeMillis(); System.out.println("Inventory is full! Dropping..."); cursorTask.optimizedDropAllItemsInInventory(cursor, inventory); + System.out.println("Dropping took " + (System.currentTimeMillis() - startTime) / 1000.0 + " seconds."); //cursorTask.dropAllItemsInInventory(cursor, inventory); } } diff --git a/src/main.java b/src/main.java index a1d43fc..e219074 100644 --- a/src/main.java +++ b/src/main.java @@ -7,6 +7,7 @@ import java.net.URL; public class main { public static void main(String[] args) throws Exception { + System.out.println("Starting Willow Chopper."); WillowChopper willowChopper = new WillowChopper(); willowChopper.run(); /*Cursor cursor = new Cursor(); diff --git a/target/classes/Cursor.class b/target/classes/Cursor.class index eedc53bcab8672775101396995d5c961d25522dc..5323db5cd621f64518ec31b730ac8e9bc585a4d0 100644 GIT binary patch delta 230 zcmXZSy-Nad9DwoX7kU>6Mxn%INf5LI5+c&p-I7>3H1)DYwM8@~Zs8yV8QB*HO`?({ zlL9>}=mjbYg_iyb@z3yxp6vrq*2-EZ`}&r`m$X*%8-CSoNKNys@t0=qyh}`9_N<%# z-o>uym0@>|S&n7ND672mj7?RL#Mp(u$S5VkoH0iklOl_piwYdMFB#%WP6LO=H5ye$ zxM7+aGu#s5jwttbWIUweO_Q*)F(v!+VjEKKpzpUJo*3t delta 230 zcmXZSJxfAi96<5&gx(tng^|S7iXdFv^9LLdVu61}(;D z6Q;u)T_Rkw$c>IpMpUwghg*ixjBv*c_ssI(uG-xmiSk68K1l{-Trcy?CNJ#p${ueV U@XjG09PuevQ=-0fY&tRY3&IRMegFUf diff --git a/target/classes/CursorDataFileParser.class b/target/classes/CursorDataFileParser.class index 4b5ec1dda2f423faf50625363cfbe0bd10b6120f..8449d71213c472aef1519c99aed2d4efb7cbc4b8 100644 GIT binary patch delta 14 VcmaDX`B-wpaZW~~%_lgenE@}s1x^3} delta 14 VcmaDX`B-wpaZW~&%_lgenE@{i1uy^r diff --git a/target/classes/CursorPath.class b/target/classes/CursorPath.class index d872513944ed6cbd740253083afd5d7d44698ec3..1c05474cc29e1763d1348a000410273fc5f6ea66 100644 GIT binary patch delta 574 zcmXAl+fNfg6vn@SwcBk6gWX;%CS*wvV$-HZV`3VJmlzXG^g$7$#)nlZ*0iNziwW_; zXRG4npwgoCe!)w%fLj4AR#6mhp#Mf6eKS#K;bp$xoH^f|ldl@igdB5!C(8gf;8)Qx zEt5^rY-c&n;XDPEkaU6LA{|y5rOO;dr%se z%OH2fj8t6jS1^JnG9EM3pU_Y0;kcgc4)5(Z($NIRQ#_*vrzSmT@R7!S&2|(SR_yLe z9EtX7J;$_EPb`@>A`TQV#!-)P1`k!7ZfB=eGC4|kMW>tr|0IJmsCC2=Q6r@%7Y(ni z*Edvlu3IzBz=PVhn32|#N23wVjtYY!`j1D`dPKASdT({lke@f%3;4(}i%+zbH{0g$ zRmK;J^Ofp1YrLH56)VM)cKl%2Nfq8eMLxjXW1H)W%V@pY$Ij4*x=G5I7@(@!ZowrA zxm#)nMVy`PEwxsxIrom$SI`XxRpj0wlnM0*O1PSZDkPf)7jm8Ko_01w+dcc)Fy%e_ zSe|}+4%XeoE!033o*LYyL*9+-4h?$S*j-u>=RI2P3+%ZcoIn>t?q78jkET#K;CfNQ zXkZ+xOc*9!x+Y9aiEGf}@)9>${C0_3O}sPl!Nh0bcYPO18DATlr&(X4ys$X>=YRjN BudV<9 delta 959 zcmZuvNlX+$6n!NlJ=4=J%z%m-QxcbfjDg@10~q5LqX9()4SH&33K;3>o^&_FIe8X$ z%MEuF!CeuYQBZKfeczYFn->!kFJ8Q;)q~NPc&Y#XumAsh^?x-@`I0X`_|e@9U^+f@ z$bHiKKrOT98L{}%nt2VTWtiovT~}eMx>aMCQ5K#XFIP>q+R#*jp@H1eze&XsHW3V4 zt2V0nnyT04FECBRbYlxaf2D3R%g`EGn1+mKETXA)#L#KXG^#ZgwTh_hacBkMdckN! zbo(Dl8d7!LuxT};fBG0Ejabx)sX9c2zL742=Kp6LNAH%OxqE2gQT z6uoZQW<$sp@&8o>L3 zi+gYpT@pG8hX0-7inwL7sDevK@Q)r!F7qFru@kxpGL|$%tC@Ic4UIVyvx;OSvCTQI zDdGSiuuKCf>}!V6yN9p!)Jj7Ex?LXM`p@rGbA zZ}E=i+r3*zRwq?D2G1ebfF=<5#h;soG=TuQ2OFz=o0HhuC%i$JD$exO%`%Y#C<9sI zkIn%2vy4WvgD>>WcJT!E@Fw3Z2kheyeUs7-iamVu%}I0iG1I?j;vv-j=Bg0Z;mXcS z;&3zk!W?aeBFu5#=AT7c_$U7=(#lIRD@i-wk-2)v37iyKq?Dpl{Cnn1a+()rm5?*s z5a(HbCM$3Gx!@Iq3HJT`auFRpNLKl-B+--Cg)s?O30(DEPvE9-gATqufX6%d?f{;g u!2JXsCGbqt`(6vn10zZ%y+xT2TQ8_HFz6?|NRxywVHGe$fOjcP?|%Uh5F@bw diff --git a/target/classes/CursorPointTest.class b/target/classes/CursorPointTest.class index c9a74ab0bbda8fb03922ff7ac8313682e9c05084..306f493f9a2b5dc80ea993bc2aa10c0d1e022bbe 100644 GIT binary patch delta 901 zcmYk4&ui0Q7{|X!^Q&E^ZH*h5A~HH{wQ*K!8QG6+YezTheyFu}b?BzdgNTRC%0zH@ zQP7L<-Uebp!E<4hB4UrqE`tAoUOk8&JW26+)3hd#8S?`h~WeT^dWTZ$XVaF8tnGaMAEIG~!+E^<5A&+qvisM0$~z6KUdnd({%HC>Z7$Q9h`9GnHq~dqnx(;9pP35^5pSHtNSK*C>LQu91aju2Bk)U86KAuF)*+ z;u5*3xXeDQXN7{ZxFKz7`$`>GZJCV9929a~;XrBzu5;2H87|3PypoQ|jVdMF#G5!C zkE#fp+#`fP9uHF^$xy4nQ*D?2l~AkciP<-;G~dyzbvN!!cjK6=If3V{W)4qW%_VHP Xnq}O>DhX>O{M4WH3s|FV6>;+)SUsb| delta 1210 zcmYk6OH5Ni6o&uHeYNERZLNhC7RG=;0U`1bi%6jrK@kuu)@mh9Q=mKwmR3L$8{C-q zNKEcRgOXrObb|{LLI^RkG;!n7xOJ%uq6_1~pl5C`rHjt|J^z_G=bM>!$NJu8`n0$G z0YEdR)=js$^y3<*=c8p;>TtGv`%&htGl4^ef@7%UV4aU8$7AuKaC|J5j>3-(Lzd~%#-RX;Z{>C0oc$+4Q5n3b(T>b4q;z*I>d}DbVwxBZt;5CevwqR z$Y{36uwJAKz3@^w5d%04A1R3npQXZw)t_QRx_c8nZh_9Jj|s8PhJGd_ifBT12pbq& zMiHC+%aDb)5O_Lahe&b5DlAO+&7=-2i7c~~d8GViCD)Ugr>!I9FEIbjG1YgH- z>|?HHFYk5s@>Cu33?Ay3=dh$>4q`#a3?hyw0UHpYE3Jp&9|er+fLx+h7%geAe*=1i zGMST<#Aat@by0~JnS8zivnIzTpS^%6tnq8)^4hzXXbtEG%^tQ(d!|nPVbgkyVodX$ Y7$?QEJrN@%YEAIqO30pIo8@8hKec4x^#A|> diff --git a/target/classes/IronMiner.class b/target/classes/IronMiner.class new file mode 100644 index 0000000000000000000000000000000000000000..afd6be8f9988e134d4bfaf9442eb286039f85025 GIT binary patch literal 2899 zcmai0TX!2*75cG`a*^wVQHrC(^{8MxGI) zQDT=%3k5>c3zS}<F^Ypo3REpJw#lm!@Ha$x$B?ZR3=}%mCZO5M!NYp!C z+w}yJrGgr9EfuWQ%=UEwJzSSF+WKtghUNIKw%dbMt~e4AWpI3$qn1NrbEY04JSxTV3I_nkPFNcI(A{VhKFU{yJVzrDzHAHqaOog!e6%Aim$FT$XC?s zI2yj%MWqzdLlvi>vPORSSxqNHfGl)I( zFvQuzh$-8^J*2M;;BN!s#9i$D1NMK+(yErm-567Xvmu;stG!G)A}^MZk^8vTm{EkE z944a0Qtq$l8$w+IWc*zJQ2)?6tc4-iT#{r2C}e!#I4Q}nu2~Y2Bc2na_@qKG9JmY- z#JP5z)fSLgk`Vuvmu{NhurYI$6&6GEEVXipFq);o)_GCMt>ZiA;veAHNc@kuDexDh z&&9?*!TyohI==sCBAqz!KKjy$^CPi}{N#rM?`{0^z(C~o`-q?XNPI+hF-6*GRtUU2 z;}lYoG^KEcv^|0`0zAcXRLz`!6~vg}ML$ literal 0 HcmV?d00001 diff --git a/target/classes/Randomizer.class b/target/classes/Randomizer.class index cfba3b35626ace184b7f8db813b23678eb7fc30b..38609109deabf2934255d847566637714e554dd8 100644 GIT binary patch delta 36 scmaDS@SB_K)W2Q(7#J8#8DckbU0|O4oyCBWd9w!VYerTE1}26W00CwTU;qFB delta 666 zcmY+A%W6|m6o$W@bIave>t)~}3MyI>Q38UKbQ-~EDm8_ckXE}}k4f6}q)kqf)LRA) zoH+9}1g}K!_5h9?`VN9GAc*UnIA{iY?SK9MTK`&m|H=HGO@IIU=^Jp3(cAP7V|1$F z2Yy$F{-W;cjZRx%-`m$=s}m@!TsdDarBU2|DKG$}dOMj!QsCF|vA{cHdW=&Q%U|&F81GsAJEi zOHW}m{4n0FoG&R-yT0CD?6d;mW-D8|uM2t*7Gh>z#AOuKnT9FI)R zl0qqwsDs|ipT<>XzR#Gy)M!=yAqDCN$>`?YrR;o;jyXY==U6c+CcWevSv$coiRa}Ja2A_$R3!_zz>tePV~!W(cuk(; zQn5ODDkoSwDXF}gWme=TY+ezvFLqVd=`+9(laiPWFeMf_;31Y67I-Ac7TY-<3v$HV Ppe$WU@p&Si37-A~b}*8< diff --git a/target/classes/RandomizerTest.class b/target/classes/RandomizerTest.class index 7eba454027bc3fc2a07b8340fe9ca96ca27e1c84..329d52b46748fa467defb3a7d8620d3cbf81eaaa 100644 GIT binary patch delta 411 zcmZ3?@sf?})W2Q(7#J8#8T2M{U8?5_O3X{i&&{k#E#hJjWZ-1m-;m^c>Ep^jZ1yn5 z{zQQ|8Bxw!Hv0#w7O$1K6wk=ORRq_?$iU-+FvFUWfj_mPAT_xpH6z?O~5(<_n5s0b*9ZAYU+Fgh2!-BEldB7W0FONr1(qz+zS`8-b=UF>nD%F|di; z3>*yn3=%-k>o5p2I5LPca0BH`Aht2^Fz^C-98L^Y3^EL|42(d9S`2aw@<1bWfCeZ4 zSYx15PeS5Y`O_)n^K@3fccUVgxCvQ2tukzBOyglwIveD$=R61W!GN3PF46< zoQgn#J3k6B-a=C({sEU6&-%@KW6j$iKfinf@EG?3lo%TOLXSGv%a> zM5ZD?cPBuTrkD@DYptjAbI z_`kQlljqVF&Zy%CZZgzG@x|{eA)-pF*XwzSsyxZa!*a|}8g}VI#Eu{g;enaiSoV~+ z>)L#q-cJwxwBR7a)6aq;lF_LSsEQ~v%8U0;QT;@R5<-gp8U(0Ote*iWU!n?V&}|9J zbn>Vb%AV*E5&NF-D^}k$*G{qiovMp$jSFnyIomaCP@iXbK@5JxpjNAW#^!vOkZ6ES dlG`dM_!;b+BB0mZD#Qcarc;T|cM9>lzW{gx4X6MB diff --git a/target/classes/WillowChopper.class b/target/classes/WillowChopper.class index a118a2ee11dc9ae383b9292b9230e79a1aa53428..f1f86be3918736b9c68f87edb29714edaf2a0f1d 100644 GIT binary patch delta 560 zcmZ{g&2G~`6otRBCD%z^BtjsS_-WcgNs%BD5*y4SG~q98A<$A0pg$%t!Ns*B$6=c# z5*rqN2qbm{WDrO^0B^vG4Nt&|6>!roBQ!I2W{%D|_so1Zhm+ZFe?ET&F0uPA`&+4O zqHD9&!>xW4xk0?{?YXO-?|VIkURtbYu(@inL{;u#KUN%F*>zqxWiKo@A}@&7;>dOO zY?EtARhu_%aBG5_iLXuTb(WKt+Jdoaahp5Id+o|#g1d^szTS6&PFciW&{^txe%p;q z))a?oQP}MYSd7E)c`-|a`xcWd8FQK~H-Z3 z`wWa{b%~PRg2=HJ7p?@E01*+`W&i3vI@Im1iSNd60XY zvX$b9Kvxjyx7k$MUeut92az6#zkRlaD+3$IEE&*$pU9Ng-~obL{a|F|oXpImIN5_qj?r;)I+HS+GlMHTgUjRzOcKm) z4DORxGpVt8@-TQYcu&60WHXtMx@=_H-!}!)Yyoi&;PxmB?ESoF| zYX5{SR#-g{n8~y-jPyn)AIX1ES|0VgCnjrx*}VF%S>jNh!iL4>iWToR+@R3Ew(kQQlvu{p>IcXgWeBFu|xC# delta 140 zcmZ3;`h}V6)W2Q(7#J8#8RRB%ZBt-p5N2fH4bRNU$uD=#$S){JE#hJjV&DW3Vmu7u zlN%Wigm^MA0U-ke?`{U6$n6XwKHA$DL^lEjm>9T#Bp(AakmO?EVBlupVUPln3=Cor a4Ga4rWq^Dp23Y|6&J;ud