From 58c9b94f500e8b7ddff1abf0c900859dc5d0b6b3 Mon Sep 17 00:00:00 2001 From: davpapp Date: Thu, 22 Feb 2018 11:28:01 -0500 Subject: [PATCH] Creating new images for testing inventory --- src/ColorAnalyzer.java | 6 +++ src/Constants.java | 19 +++++-- src/ImageCollector.java | 8 ++- src/Inventory.java | 57 ++++++++++----------- src/InventoryItemsTest.java | 1 - src/InventorySlot.java | 7 +-- src/InventoryTest.java | 15 ++++++ src/WillowChopper.java | 63 ------------------------ target/classes/ColorAnalyzer.class | Bin 6117 -> 6117 bytes target/classes/Constants.class | Bin 419 -> 810 bytes target/classes/ImageCollector.class | Bin 3599 -> 3811 bytes target/classes/Inventory.class | Bin 3109 -> 3204 bytes target/classes/InventoryItemsTest.class | Bin 2539 -> 2393 bytes target/classes/InventorySlot.class | Bin 1768 -> 2732 bytes target/classes/InventoryTest.class | Bin 3885 -> 4680 bytes target/classes/WillowChopper.class | Bin 1278 -> 0 bytes 16 files changed, 74 insertions(+), 102 deletions(-) delete mode 100644 src/WillowChopper.java delete mode 100644 target/classes/WillowChopper.class diff --git a/src/ColorAnalyzer.java b/src/ColorAnalyzer.java index f0b5c90..2f3afb2 100644 --- a/src/ColorAnalyzer.java +++ b/src/ColorAnalyzer.java @@ -1,3 +1,9 @@ +/* + * I made this class when I was trying to do color and feature matching with Haartraining in OpenCV. + * I no longer really use this, except for printCursorColor, which also prints the cursor's coordinates. + */ + + import java.awt.AWTException; import java.awt.Color; import java.awt.MouseInfo; diff --git a/src/Constants.java b/src/Constants.java index 573c239..63030d3 100644 --- a/src/Constants.java +++ b/src/Constants.java @@ -1,7 +1,18 @@ public class Constants { - public static final int GAME_WINDOW_WIDTH = 1000; - public static final int GAME_WINDOW_HEIGHT = 1000; - public static final int INVENTORY_WIDTH = 1000; - public static final int INVENTORY_HEIGHT = 1000; + public static final int GAME_WINDOW_OFFSET_X = 103; + public static final int GAME_WINDOW_OFFSET_Y = 85; + public static final int GAME_WINDOW_WIDTH = 510; + public static final int GAME_WINDOW_HEIGHT = 330; + + + public static final int INVENTORY_WINDOW_OFFSET_X = 655; //top left corner of inventory, fromm top left corner of screen + public static final int INVENTORY_WINDOW_OFFSET_Y = 290; + public static final int INVENTORY_WINDOW_WIDTH = 171; + public static final int INVENTORY_WINDOW_HEIGHT = 350; + public static final int INVENTORY_SLOT_WIDTH = 171 / 4; + public static final int INVENTORY_SLOT_HEIGHT = 254 / 7; + + public static final int INVENTORY_NUM_ROWS = 4; + public static final int INVENTORY_NUM_COLUMNS = 7; } diff --git a/src/ImageCollector.java b/src/ImageCollector.java index 4053142..b69f31b 100644 --- a/src/ImageCollector.java +++ b/src/ImageCollector.java @@ -77,9 +77,15 @@ public class ImageCollector { return screenshotOutputDirectory + itemName + "_" + counter + ".jpg"; } + private void generateInventorySlotImages() throws AWTException, IOException { + Inventory inventory = new Inventory(); + inventory.updateAndWriteAllInventorySlotsToImages(); + } + public static void main(String[] args) throws Exception { ImageCollector imageCollector = new ImageCollector("/home/dpapp/Desktop/RunescapeAI/TensorFlow/IronOre/"); - imageCollector.collectImages("ironOre"); + //imageCollector.collectImages("ironOre"); + imageCollector.generateInventorySlotImages(); } } diff --git a/src/Inventory.java b/src/Inventory.java index 31a1256..b86476e 100644 --- a/src/Inventory.java +++ b/src/Inventory.java @@ -10,17 +10,6 @@ import javax.imageio.ImageIO; public class Inventory { - public static final int INVENTORY_OFFSET_WIDTH = 655; //top left corner of inventory, fromm top left corner of screen - public static final int INVENTORY_OFFSET_HEIGHT = 290; - public static final int INVENTORY_WIDTH = 820 - 649;// 820 - public static final int INVENTORY_HEIGHT = 350; // 530 - - private static final int INVENTORY_SLOT_WIDTH = 171 / 4; - private static final int INVENTORY_SLOT_HEIGHT = 254 / 7; - - public static final int NUM_ROWS = 4; - public static final int NUM_COLUMNS = 7; - Robot robot; Rectangle inventoryRectangleToCapture; InventorySlot[][] inventorySlots; @@ -34,13 +23,13 @@ public class Inventory { } private void initializeInventoryRectangle() { - inventoryRectangleToCapture = new Rectangle(INVENTORY_OFFSET_WIDTH, INVENTORY_OFFSET_HEIGHT, INVENTORY_WIDTH, INVENTORY_HEIGHT); + inventoryRectangleToCapture = new Rectangle(Constants.INVENTORY_WINDOW_OFFSET_X, Constants.INVENTORY_WINDOW_OFFSET_Y, Constants.INVENTORY_WINDOW_WIDTH, Constants.INVENTORY_WINDOW_HEIGHT); } private void initializeInventorySlots() { inventorySlots = new InventorySlot[4][7]; - for (int row = 0; row < 4; row++) { - for (int column = 0; column < 7; column++) { + for (int row = 0; row < Constants.INVENTORY_NUM_ROWS; row++) { + for (int column = 0; column < Constants.INVENTORY_NUM_COLUMNS; column++) { inventorySlots[row][column] = new InventorySlot(row, column); } } @@ -52,23 +41,26 @@ public class Inventory { public void update() throws IOException { BufferedImage image = robot.createScreenCapture(this.inventoryRectangleToCapture); - - // For test image generation only - //ImageIO.write(image, "png", new File(getImageName())); - updateAllInventorySlots(image); } - - // For testing only - public void updateWithFakeImageForTests(BufferedImage testImage) throws IOException { - updateAllInventorySlots(testImage); - } private void updateAllInventorySlots(BufferedImage image) throws IOException { - for (int row = 0; row < 4; row++) { - for (int column = 0; column < 7; column++) { + for (int row = 0; row < Constants.INVENTORY_NUM_ROWS; row++) { + for (int column = 0; column < Constants.INVENTORY_NUM_COLUMNS; column++) { inventorySlots[row][column].updateInventorySlot(image); - //inventorySlots[row][column].writeInventorySlotImage(image, row, column); + } + } + } + + public void updateAndWriteAllInventorySlotsToImages() throws IOException { + BufferedImage image = robot.createScreenCapture(this.inventoryRectangleToCapture); + writeAllInventorySlotsToImages(image); + } + + private void writeAllInventorySlotsToImages(BufferedImage image) throws IOException { + for (int row = 0; row < Constants.INVENTORY_NUM_ROWS; row++) { + for (int column = 0; column < Constants.INVENTORY_NUM_COLUMNS; column++) { + inventorySlots[row][column].writeInventorySlotImage(image, row, column); } } } @@ -79,8 +71,8 @@ public class Inventory { public boolean isInventoryFull() { // TODO: this will fail if some unexpected item shows up - for (int row = 0; row < 4; row++) { - for (int column = 0; column < 7; column++) { + for (int row = 0; row < Constants.INVENTORY_NUM_ROWS; row++) { + for (int column = 0; column < Constants.INVENTORY_NUM_COLUMNS; column++) { if (inventorySlots[row][column].isInventorySlotEmpty(items)) { return false; } @@ -91,8 +83,13 @@ public class Inventory { public Point getClickCoordinatesForInventorySlot(int row, int column) { Point centerOfInventorySlot = inventorySlots[row][column].getClickablePointWithinItemSlot(); - int x = INVENTORY_OFFSET_WIDTH + row * INVENTORY_SLOT_WIDTH + centerOfInventorySlot.x; - int y = INVENTORY_OFFSET_HEIGHT + column * INVENTORY_SLOT_HEIGHT + centerOfInventorySlot.y; + int x = Constants.INVENTORY_WINDOW_OFFSET_X + row * Constants.INVENTORY_SLOT_WIDTH + centerOfInventorySlot.x; + int y = Constants.INVENTORY_WINDOW_OFFSET_Y + column * Constants.INVENTORY_SLOT_HEIGHT + centerOfInventorySlot.y; return new Point(x, y); } + + // For testing only + public void updateWithFakeImageForTests(BufferedImage testImage) throws IOException { + updateAllInventorySlots(testImage); + } } diff --git a/src/InventoryItemsTest.java b/src/InventoryItemsTest.java index b4ff817..2696f0f 100644 --- a/src/InventoryItemsTest.java +++ b/src/InventoryItemsTest.java @@ -17,7 +17,6 @@ class InventoryItemsTest { String testingItemDirectoryPath; public void initialize() throws IOException { - System.out.println("running initialize..."); items = new InventoryItems("/home/dpapp/Desktop/RunescapeAI/Items/"); this.testingItemDirectoryPath = "/home/dpapp/Desktop/RunescapeAI/Tests/ItemNameRecognition/"; } diff --git a/src/InventorySlot.java b/src/InventorySlot.java index 84d9887..dad2d8c 100644 --- a/src/InventorySlot.java +++ b/src/InventorySlot.java @@ -39,13 +39,14 @@ public class InventorySlot { } // For test image generation only - /*public void writeInventorySlotImage(BufferedImage image, int row, int column) throws IOException { + public void writeInventorySlotImage(BufferedImage image, int row, int column) throws IOException { + System.out.println("Written inventory slot image..."); updateInventorySlot(image); ImageIO.write(this.inventorySlotImage, "png", new File(getImageName(row, column))); } // For test image generation only private String getImageName(int row, int column) { - return ("/home/dpapp/Desktop/RunescapeAIPics/InventorySlots/inventorySlot_" + row + "_" + column + ".png"); - }*/ + return ("/home/dpapp/Desktop/RunescapeAI/InventorySlots/inventorySlot_" + row + "_" + column + ".png"); + } } diff --git a/src/InventoryTest.java b/src/InventoryTest.java index a0a4068..3b9b508 100644 --- a/src/InventoryTest.java +++ b/src/InventoryTest.java @@ -35,9 +35,24 @@ class InventoryTest { {"empty", "oakLogs", "empty", "logs", "willowLogs", "empty", "willowLogs"}, {"logs", "empty", "oakLogs", "oakLogs", "empty", "oakLogs", "empty"}, {"willowLogs", "empty", "logs", "willowLogs", "empty", "logs", "logs"}}; + String[][] expectedItemNames3 = {{"oakLogs", "willowLogs", "willowLogs", "willowLogs", "oakLogs", "willowLogs", "logs"}, + {"empty", "oakLogs", "empty", "logs", "willowLogs", "empty", "willowLogs"}, + {"logs", "empty", "oakLogs", "oakLogs", "empty", "oakLogs", "empty"}, + {"willowLogs", "empty", "logs", "willowLogs", "empty", "logs", "logs"}}; + String[][] expectedItemNames4 = {{"oakLogs", "willowLogs", "willowLogs", "willowLogs", "oakLogs", "willowLogs", "logs"}, + {"empty", "oakLogs", "empty", "logs", "willowLogs", "empty", "willowLogs"}, + {"logs", "empty", "oakLogs", "oakLogs", "empty", "oakLogs", "empty"}, + {"willowLogs", "empty", "logs", "willowLogs", "empty", "logs", "logs"}}; + String[][] expectedItemNames5 = {{"oakLogs", "willowLogs", "willowLogs", "willowLogs", "oakLogs", "willowLogs", "logs"}, + {"empty", "oakLogs", "empty", "logs", "willowLogs", "empty", "willowLogs"}, + {"logs", "empty", "oakLogs", "oakLogs", "empty", "oakLogs", "empty"}, + {"willowLogs", "empty", "logs", "willowLogs", "empty", "logs", "logs"}}; testGetNameInItemInventorySlotHelper("inventory_0.png", expectedItemNames0); testGetNameInItemInventorySlotHelper("inventory_1.png", expectedItemNames1); testGetNameInItemInventorySlotHelper("inventory_2.png", expectedItemNames2); + testGetNameInItemInventorySlotHelper("inventory_3.png", expectedItemNames2); + testGetNameInItemInventorySlotHelper("inventory_4.png", expectedItemNames2); + testGetNameInItemInventorySlotHelper("inventory_5.png", expectedItemNames2); } @Test diff --git a/src/WillowChopper.java b/src/WillowChopper.java deleted file mode 100644 index efeca52..0000000 --- a/src/WillowChopper.java +++ /dev/null @@ -1,63 +0,0 @@ -import java.awt.AWTException; -import java.awt.Rectangle; -import java.awt.Robot; -import java.awt.image.BufferedImage; -import java.io.File; -import java.io.IOException; - -import javax.imageio.ImageIO; - -public class WillowChopper { - - Cursor cursor; - CursorTask cursorTask; - Inventory inventory; - ObjectDetector objectDetector; - Robot robot; - - public WillowChopper() throws AWTException, IOException - { - //cursor = new Cursor(); - //cursorTask = new CursorTask(); - inventory = new Inventory(); - objectDetector = new ObjectDetector(); - robot = new Robot(); - } - - public void run() throws Exception { - System.out.println("Starting ironMiner..."); - while (true) { - String filename = "/home/dpapp/Desktop/RunescapeAI/temp/screenshot.jpg"; - BufferedImage image = captureScreenshotGameWindow(); - ImageIO.write(image, "jpg", new File(filename)); - ArrayList ironOreLocations = objectDetector.getIronOreLocationsFromImage(filename); - System.out.println("--------------------------------\n\n"); - /* - if (character.isCharacterEngaged()) { - // DO NOTHING - // do things like checking the inventory - } - else { - find closest willow tree - chop willow tree - } - */ - /*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); - }*/ - } - } - - private BufferedImage captureScreenshotGameWindow() throws IOException { - Rectangle area = new Rectangle(103, 85, 510, 330); - return robot.createScreenCapture(area); - - } - - -} diff --git a/target/classes/ColorAnalyzer.class b/target/classes/ColorAnalyzer.class index 239d38d1a011f738f7a914351e7f550f21924a2f..0b16f5a4e6a96c7a230b08bfdbe34da95916f45a 100644 GIT binary patch delta 305 zcmWNL%Sr-q6oLKV%xR`(V4|ekU>CFt6}m8uB8aIl0#m6)H=%-}3oepq9e)T~ zwCD*6+y*^EPY?vYM`w9{=ls6!G!xCl=bj$yqZN}5EOns!0h=xy^`)1!LFI)0yg2QQ zpfgI8F)YRzVuCClJ2F=!uQJIqQ@k+U@Vb4?P0~V&er9o)ljS_iEN~-Pokd<*Qt#oP zKw1zPbsedhS=v|;MNSlX;;f1=C&2ZF-eYOzrhKr)0Nc3YoT0!yyFB2lO!V6>5@8>k zqR2{8DvP2b!jhm4mEHS0d?ff|IyoWCsa&0jqDoTcwB&1CNas?yu{-Tby~WP8TNN_$ TT1^#fEC)ka$2?3SHlo!sveIlyV;){0N+D0-6X;*c3om>E zYHyX#;1ejd@8N!PcimU_b^Y$TTX#RphBrVXL0T|%)hKu@+UV3@Mny$+%=ee*rkNfL zdNJuELR@A)OAN3fYDfGNhInR}7e;D{_JVR;8W^REBr(QBjWfptSE8Os@ye8b_y2gN zNid@?0(aqgnn(*GBZvhlUt~~plI5BajHqx@c*~8DiTpbAFkV)Co;^#P`!m)Nj*XmTih0fHu_E}kV Ssf$+Ldn@dF$v)^0EA2}9DQzMJbR#L)XbqMGim%~=xN>FU!Uyo7 zi2to3H)`D6^y~SDbMAfbzrF$3M46J;kN*^irIaQleoYu`#uFj=OC7Gi;xt3Ktm+1P_%w|S zVfKgi-G~iNG!(T;seZ24%IrtnvD7A%oUT?%nkR+`BZszQyGI27&Tf?u$hEJnF#K4L zVg;*&m})zg*1K<59m8z2EMBCxn`WzOc5K04KLhTq-6cfS!3%W{2;p+O*J)Y>TeMAl zD|_P2u?F7B2BSzJh!Lg`lMkcJV-km%BNB`Hafv6GV-m-iCncU@o|brqc~;^Cb5i0t z=9I+qObZe(GA~KI%+5*N6`yOIAnP#@%)B7|>_yt(Qv?+8Hu;Qt-$86)n~AXFDZ3vL CQ;z`v delta 248 zcmZ3*wwRgg)W2Q(7#J8#8N?@Ysiz9MJNmlDhkN?D_=f{2mkOTi-SRufs28Sfsuh7=pH5p5T6@`4|EDh50K;os?Z10j6j-IYdZt~ fMz9t^APF)6q+JL|@<0?Y2s4NPd5jFAU>Pw0G}b7l diff --git a/target/classes/ImageCollector.class b/target/classes/ImageCollector.class index 9847b8f3913e80399d95758c42e4801cd6145cbb..4bc1724a8d44a507a38eec65d70f461f36e09274 100644 GIT binary patch delta 410 zcmZ8bO-lk%6g_XUdOk;m=nE=PC|XF%+PG>tG!SJV)+WKhglP=5AX@knTFmdrnk=Vg z%Dy-Kjs8b;RFdc|?z!jOd(V02^Ir?<^E>DQSjC5@7G-m;Y&lk~*su)e#Bv(d+G)spv%2^S*2QsS^1iCsdkZ=QeCRBSZx)*6`Jpme0{P`Gh32DUG8|*b=JVdMD z;uUV tqA(HocrY_Q9{*?Lp-^Dn?w^b#p72aJ#f%rG2|B%!Yk0$ZUl+XTzaKh&RxJPk delta 197 zcmXAhJq`g;6otPxB;GtC2u49DbfQ$*0+FB*wL(LpmDqw}R-rJA|KC}F#v(LUA#S+E zz4tpg=e!E@ym@>s0Z=3GOmN@{oD;EQOHmK_%hv@vu@&?O_3{f9Vl W7BWP*;7F;(RoLRj{iiE>a%H~w!X(N7 diff --git a/target/classes/Inventory.class b/target/classes/Inventory.class index 76dd518adbe1d12f860e9fb65eac33b88ff47005..c7a17dbf9faad062fd6884a45dccd6fda89e7e83 100644 GIT binary patch literal 3204 zcmb7GT~8Ee6n@_QU}YU~0YM6j;y0`xE1>uRVil!D5mXRFt94jL9NFF3?#}wvTkm_@ zHcgZE#*2E(-PVsRJ5rxEk^MRSpn)$`_|+ zyctyJuq%hJ(v*j?*0eKX7Tj{tQrJ>+pt8+F4Z)$QtmBpx8gJel52BEFG>Y1;mE&Hb zx-%wkxK%e~=WTabA>7?FqYyv;C}R~|+sT(=XjEtkqC7J@9qh%>tkA5tY$rW78Ehy- zMw|sJjxbscY(hgE3T+17L4!h4JlST}eqsdy2APUshk>LRwyk5RvlF9j2DXdQ<{Bf( zC59bjBM4WM8b=pe>v?Fmfhg*DXxz?Q6Xo2zRh%~Gv!u0Y+{u{P8MA21v;Q*U-m^*9 z#wuNdF{Ef*g|Cz#jvgG4R1Ye|y2tphXGT1x4aBe^hPXWR8K_4*h9e4_g489WIQlUl zr;o8nJS`;%7oCR+YK*nXIN5S8&qGtLnOVAI7Ib_uoMNT{j;`beoL1PIzUSnu^g_Wb z6w>Fc(vs^G(pSrQtCTSd)|s)iHciJdgfrswEbH6t$x3T<$}QUY#X&EDa|SlTU=ZcP zg6XoPU3kyH`(RwnnWDv4Q(UZkAkZT|l$Labp241~Z0(%6Xr<4V@7}eF*20)P4N65X z8W_hVg{_{aGudpAo36UTjvDCoP=vOq-k?6-=CB`E3|tk5&7Q+m-W2xvVdNKPi|m^> z!kKn-=p_mLnt>TX+V=1*rv12XU=BB!r8ZsVQ{yS@dP|m`JlYp6SL!%n=GaE7a1>fa zLvL18WOm!YO?=2!=&q_->!DJjS_w#dl>+S1ayF|6#0>$;7+8P|q#6sU)A?M%eN0l{ z#AnvK81+cj&Mb{MPI1A`Q$D3prx>^p076#77ZqK0?7T~f^usoAA4>|`D=^ZmdVAJp zujVBY52C5NMsXfMJ#uhjU>{Y-gWfSvzzMe6Be5tNDCwuiaXt;OH8Py!R&ny~njmW? zw};Qcfb+}D%HXD7x5X^d2M5Kz&1{>?aZf(S?!?jE~NQ< z47+t4U7jyLj!j76I8HEk z@^YFv4pV)n_;+_QEc)5uW$d2evG$I|7@SCHL>&P;0eam-V zhu6^()R%Ogr}#wRIpHgw=Y7R1+=1z1f8k^67S!@+U+rc7GepDBD_!`z--SO%p3_xr z8(tt47fHo92gxNiUwB6aW1!57Hh8HjK^B@?^#<41P}qOXvfYl*Z(SKwB;k~s)mqi$w6 zt7bV7uImtoJ@kOLfq=IGKSYDJWjtWo9sJL)3XxL8;TMI;D?D6BW5eWE`nzsTPkZz7 a7SG+*-o1XV3%u9ik?v=O$2=Xvlm7rmErap^ literal 3109 zcmaJ?O;a0J7ClcNw2|9bfWZXh&)AL-u@&Q(WClV^gcK_QDT8Df?8MNBHnb6HMYQ~p z?_|99c2bo}RkHCSS!AkWQ#G#2E}Q&=RLy2Ksmf-4z?5rd&U@W-x4|`bNss&Pd*|MJ z&b?2+{O9jK0l0{J8X^Ln#l|hO;n=Oa8e#&;o5n38TQ?eO+49Owv*rl&7fbW`Qnfs{ zxKu6_D*5WtLUFo!SwIv84&>~{mSZ%Wd86Joqd?@oz~MbNF6WDHUarzDP6`|h+zN@? z_>Q52?cn%zfkVN5Wv1*!mv=G(eY<@AMVu1YSGqF0G*@1z$iu8{zqE7ZnJcp;wWSHf zTlR|08j~}sZsWF-os&D`0z=jgF>|DWgw)NdoimzFyJa$|(1jg0FLn8sDs|i066n5m zZN_IZG-2#;zIl zd81`X+uMve>lW$SAJ8?fVSqO)UF5&vc^Pp^$8#9ekdnr9V2(^0+K-v$5m6EhUJy?Az3(X4l)B4PK}?Mr~u(XsX;alvt&Yp;X+5cLdI4 z*X>O+yV^9G&Fr+fwc*&!>|DEHZqW_&nkS!>f+GqZ2BZ`?3j z=4w$|<5JCcb-V|T++jD;RK4!krW6-A5rTdeili*A90EuGe?X3y8)m_B)(gglsq!e; zt*W^tN2k-_s`jKVt2#`XTCaQOsk{UR*GxxJS~51-&AXiaQp&yLN>oe74crtsl@6Lq zNwdRNSPj|bTRwK7U9YP-y()nkI&3ugE`&}<%JQ2{=Pt9}i%<2QXV$s8Rolqfc5BsY zP{}RU?}v~8gbdP`g1%#04Toyw;pk}NmcX$c7&$Y_Eg7{MvJe-dCmj;s1?a>be4v53 z1yia#IzB`PANM=*#K$^5QP$lAEx!4EHU3zbt@4dsNroO!7oU$;#csE1X2Ft!9Sq4i zIkh;!Zj;ZloXa>mXlb+}*hjlFWG86v583kkfsoyWK^zR(N!r~ZyNBm{L-rxseIdJ_ zQTZ0}8}tmSm5+m3Idoj*T=3~+ZYOAUa6O4rIK#iMvI4<1mD$D%{0#H+B0t&8V~j3t z6A_&53^c!l4CybBI;jHvsFs1q|u%pu~vN{{Yh;Sczuy2D4BJ2Fmz+{ics#2sJk zj@<7SC%f@ox46EI*B;_h5F^1@z-d-=CWJZQWAZ)sFu!FslK)pTT2lKNZ$us<7oB*3 z)6v%+;Be+ghgJp0|_+J>=tU#pw)Bbs_cyN%4fg)xG~FM-lnc!tWFG#hACt z`h@zMr^&|bVo!M+e|m`OZVpD-B^N>*ba}A_=AVICVid_-4-3D@&!tCLn8}Q6<63~* zrD_Q85h^jBkffeVTVcmB2<1r=@*5sUtHl+W%EnKqu=lJ@NZrZ{~G(A z0mDr^M=C0$qRI#03dgiUD(2Y2i=m{>dr3ub)=NrbLj_HI5b-B)N$8EZEWD4Fm+9AJ zRK5aZJNZ4rR*3^Wl+3IzpZyWHm&alp?o{%WGCx`#i$BJl#lBcyd>fwzT=ghr-eWIb w=liilrIuBSlPGq_#ecxNl<2-vDm%moco=}chC3J{==po{rYeSAdJ-=)ygUr zR5FxBQ|pOTW@T+7nn^6D&2aK>EM#`TrJ)3FzQw9aOTbX0L4s_?Ic^d9SuLLs;+6&t zHmE8b2x`y~;-7@!wkEVFXlBqBaw(yq6>SW1GHrMaVjwu9;sU}7I(Uy* zEq3A}pA{qKCS2AKK^K1~`sHp7J?Q0M#Xg#+U&B=laEob79>jG8Lwv#H7jGcS-m-AeSYFL+sF=dEf_wahR3XMN!{11CRO7ye2YASLrD5+N9%+cm?5~XfSG&U)1m%OFS-r$qvCpF9ek9 zAK{4Es`gR62aj&^?!mW1aRFuYFN0`cP>KrJ>CMiPrxo&Gft5UlI;e!QlWkNi$9b}3 zvix+Oq3?)p6*@=s9P0I5YO)L8QVxMw#B|src5kEAX>zxZgmP%ygfDb}_K2jDcWED2 zBC=C9a-32QeFwPqT3~L^*70{^L@_^NEzD$BQ*#$;;HI`7gvbiRivfz=L@oE4D_z56 zF}kV32yT%s!jyfRa%GJ2akD);1_T8{O#Gh?lZ$j>r|Fz#(|w9f^S^9tcXGJ933(gV z0x_qY!|Xv8b46~S|8mo57NDNEH4vi!aSIXyon{ZA7mXyYW{lC@G}`j3(FqB}imRzX zJ5E^p|FCwQuqI>|Ovi9SQoyocOrc^pralS<6g1@{3Z5t=9g3IcfhRbDBtlB37c-XJ tN1X*awU8LH%;k{CA^D#Cf{Y9~03G=m9R*x*Mng`^v<0RTB$ZEC`3>s5nW+E( delta 1220 zcmaKs&vO%H7{@>F?q)ZQE2e2_iA}N429gaVSgcBFp;SdvDy^*|#UB_Y#KmM=(`{{0 zryM*n4%HihaQsYM{Rr7h(*Nwdr8614Ygz zf*Ivta77(gh2Te3jz49SAQsj=ZSxGz24mXfsUpu=j4JFu_?>WT6`L`RDol4Nj6{7V zdp5>66BfsXWLUadaO>r2MOsk`*V44j^Slt;(~8j|Cv0Bg<)Bwjo0B#tnF=QK@#qkz zY^IqBuIMx7EU#J21wZR){dGR*X0jy?BdK(M+1*kz}OFE1SIfxu#P6UvJ$FY3ePSdxaoE z&LG8Z`bo<(C$=16Kqi)w=?u1LI|N@@@%1-2BiwTAVxF_&p%DRjQy@&<5}0oEEs{hm zsZq+}ZOCe}KllF{mAS2P{=X!SZA+|&8uS0un0U9zdsi_x=xobPnoT~~q_!>i`#%Lc z!Ugt=;EYJkieN|di(gg^(tzozrvib4?meR<22Wxb3FU5#bLhbWl&baN9wl Qqb|t=q~m-dS&dJB2SUEsX%^m%p>LZy34p?YM-?3Q7#SX3cq1ubECoA8R!Pw>3=T z3PaRw3WlDM;M#Ka3w6s8W1`MYyO_XLhV%qs1a~slCMnY(RK}95LZP6djB5%AySqcf z4@ERoP-Rd&satahl?_>8D}s(I#oV|GhFJ{*IGjL@y7HWg0?O7lHP2c#E|WYB*HNd7 z3J=FUXWGQxo279(g#AESg$>KPyBhA{K0};js7Z!Y*2wvPb+|z$ zTOTs8p!~6{e8MpFFH`;_@Qfi=Ade*dg@%`S#gGs#Sx$B`?8)Xvy8j%!xXfcEmiYKJ zmWlXNh~NnQ%rUYwi*AZqP-q7Xe89z|*~UzMunjB!2`7?s>#!&Dss2^Ct7v>ib7F-O zBiKi4GAJ5E0!Pt>Asj*h`{_I%is1nIXh*U*g&hQwQ3`&X%4OJ(IHDBOKSh_aj}q;p z^i8j0X)<|h6@FhEcajg diff --git a/target/classes/InventoryTest.class b/target/classes/InventoryTest.class index 63e34c7302ff001b75c506ea23bfef15c4b94d46..3e92f8e0d87e9ba3cfe712c944bba6dfe971a7c3 100644 GIT binary patch delta 1306 zcmZuwZBG+-S)yQ?Ba#eyP&uT-H_SaCpb*`=~l?Tb{4 zFZEro)@rM*TBTo1YBjKJ6BE-fP5l9liC_Ey#xH&{YIUcWmQbE8S__fSV?j5pQo4K<2}LJL?UKJ;|5~rmqMMZCGe3812U-2<-0H_H>=&+ z9s_&viTp!N&G?eRu$y}m!TR2q>B2#IQp?p2TLX^BU$kQH2#y+?nb7o zeQ?naV&Kl;v;svw*6%7+!U5HS#Z_9s8!8?{B;c(ov7x%uh8hQ!IZ$iCZCVZm9=cyb zkxZr44Yy#PvLEj#w=iG%8%4@P1b7;X`9hTNE|l^Ul%GNwzmFh)f^y-*0Pn{bzm&c71UFtCl7@7m#4GwH_;C%DzcFd+L zh4>VS2b`K3ppy8RXtW2-v1{2AgMe%#;kJioV>gCmdwNk`C$AaBd>#>_@LA*iS>)*B z5`RUOs2~D)H9fz-nWnBI6YFWx1{4sMQXWQ&%@U%gKxC37GRYFbr({c^FH(lj@HweT zC)4{V5*Vf)55x=T>;+Vo^_hg|v2-aX(4<7T-~4K3$h_g(NZSPfOVh>JXI8 vq;Di2crpsUZ?evVHv8&-PkAdXM+d3zlrKHmKIcp|(tm>nDm3DzEpGH5`nL|3 delta 1113 zcmZvbOK=ob6o$Xs-7`ID+ROt&h&TzAfRG_?GEqYyBtSI85MB}jVjOi62PZQ~hG2{u zz_%cx*SDzU3O7_iVTC~~*Orz`%Oz`;RJpQJmS?(y@wMpw@9lH$|NrNl+dr(nRPFru z$G6`DNxr<|{ATD)=7EZ6Aw5~>&rPLsh5WJUzT??!h;90oxiZ-2@*ods$4aUldW%(+ zd|0t8b0>3jOj1YNnvUkiL+t!-WP=~srO#PaYLEWfif`MeSh09MmoNAnt$ybI|BreK z4vGUVBOKIafzIwnT@Le@BAl80hjWFwuKu9I<2+%LQbdoWrc%w>RBpVvH=oa@Q#qF> zc}kxStO<_sw9UA_6j){r zR=3#eV>6s`DMRFDc-iF@Uey!!#?TC}yS%}h`m()x$uy@N&T`J?ZGF?e+kA)fdfq-C z`N-u2&pE8%6PHiCAVO4j*VRcj(~VL&eqxKP45N$OWEtgBPCe$lE4wIMp15N2`$8ErHVFIv4OR;(N6Qk7$+mt#W|~DtU&G zM_x&m34J1RZ_Ti|`6BgZhjo#v5`DZvD#|s)+bXO!5zya7YG=EJwMUBR6{fA!2{y_; zNuQ_EE>Xn3-_p|Rj!Fl|N-dSaH8Dv++}tHaAD5NIl$5&`EjEKXUA}?O!qzwP`9IsvDt-*#OXLdGTmQ;WCek=Nkvx8a& z^jFc!ns>dz<6`AKwB*&w^FAMVQ!f2EzecO~emGcafLy1K|J~Lhg6tBzyZ_eK@LvUo T7YYta2^WOZ5bK|NZoc>vUsc-7 diff --git a/target/classes/WillowChopper.class b/target/classes/WillowChopper.class deleted file mode 100644 index e5184f1af1b099118a62d2ec1e2d8ed992132740..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1278 zcmah|TT|0O6#kZ$hK3@g+(9vjU;(9GK!G9(1)Vw_akvg|Zo>k>G~3yxApc5dL}p}0 z-~CaHCz}%FiOeMDoISU1&-wEA^4D(wGgvjy#L%|mxUM`Y9Lj1{Cqca@NARUzA&U3=Yd7Oq~je6&zI_yp|w=JGRSjB>XIwM zr@}$SbSZ3dbwV-CN|q&cO_wwhe&XlWgA;Nk797v<7a3yN@omDe`qdUy-;rL;Kqo_Y zl(4k38Tkx!GjwW~BXh;I$iWaV$UR{qhQ1Wqkv1?u;3K>y`q7sJ!@U%eFb&+N3*3Zj zVkiuGkU}d`1|CvKghInMF%pJ6N}&yR7}`sYCqC9IWuZ2C*%b_#lC-(I&6N|_jl;Nq z=+uJf8!MtA#8llgFm-h&y{YI<2A)!mMi4rblBxyI8N4k|iJEke#hzu$O4V_BFgdGA z<90=*HgB29C8hXj$*K94%{@>0R#{k4k}oZ8`KMK3CO=8XyCud%4%5L@XJ{|kaFrU- zhOZp&ARp{+(B@UYuEd6|gz##I(tpn@V#o3Jpdd9bdEi9(+25)I@)QI><_p%%BTBq<_{vU~J+Xy%QJc-#y3R8SaugM5=X$VNyp(9X-R?cgko&mcBi@ zdj@gR+R=*v^kI~^KTf_Bb)$-yz$8hA$5H1vSxkL3*o$U3Rb!=a?@|{J_}cPrUvX6*nmzn4jpjA9&9wo&`-OBWh%{3&^asr0KRx7@&Et;