From c9b1b99cc0a346e0ad89911d6499396a3f987cee Mon Sep 17 00:00:00 2001 From: trav Date: Thu, 15 Jun 2023 19:49:42 -0400 Subject: [PATCH] backup as im working --- __pycache__/tozpl.cpython-38.pyc | Bin 0 -> 3956 bytes custodisco-kiosk.pde => custodiscokiosk.pde | 11 +- description for gpt.txt | 17 ++ drawing.png | Bin 0 -> 1772 bytes kiosk.py | 112 +++++++++++ kiosk2.py | 181 +++++++++++++++++ kiosk3.py | 91 +++++++++ kiosk4.py | 76 +++++++ kiosk5.py | 107 ++++++++++ kiosk6.py | 208 ++++++++++++++++++++ pythonzpl.zpl | 1 + scuttlebot.js | 39 ++++ tozpl.py | 135 +++++++++++++ 13 files changed, 972 insertions(+), 6 deletions(-) create mode 100644 __pycache__/tozpl.cpython-38.pyc rename custodisco-kiosk.pde => custodiscokiosk.pde (87%) create mode 100644 description for gpt.txt create mode 100644 drawing.png create mode 100644 kiosk.py create mode 100644 kiosk2.py create mode 100644 kiosk3.py create mode 100644 kiosk4.py create mode 100644 kiosk5.py create mode 100644 kiosk6.py create mode 100644 pythonzpl.zpl create mode 100644 scuttlebot.js create mode 100644 tozpl.py diff --git a/__pycache__/tozpl.cpython-38.pyc b/__pycache__/tozpl.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4345bcf9a24e37f2187f2a01a314a10ea7642cb6 GIT binary patch literal 3956 zcma)9&2JmW6`z^iC6`OeR$^7M+%$FCG&U2#cHN*~Fajqw>^N~`$CeXkn`p7(ti+Yb zU21kIOT-c_Ah(CM2P4SQ2kBD4*P{6ka_HYM2zu$Iy7lb#(BGStY?5u$axuT1kGC`L zy?I}}H#Oxk{F-0V{CaBYT(m)u_7XN_QV$MK$z2S=;Bkw1>FMn%)6+W=*c08{Kd%T5Qp9 z^k-pk87=!15HX)i<_pQCz(H1d`1rxneaLpXUzIiKfyR|}*}%I7rl#aEv*yX;avF1W z`GR~A?}j`9R%UeFzkTycnruaRq*@&39sQ_(7VQdJ)&WRfu%JY+g1#VDNPbzBE*(wB z(t&go9V1W38TliA|`CZMIG{2|$N1A`E z`F+hl(R@www&tzZ$9-qF0Pd7^o$c~A3A&6Vbv=DFs5&9^jvp!v4uJDLxgXAbD_ z13^HSaX?0K;1E;@sst`Ujerd5pia;rm?AhvaGYS8;01yg31D;VV1|ISdvJ;1Hi0DA zCip$U9>Jdo{!H*S!QTO~4c_9D1PcV036==j1O>q(K-1Pvp5|dk*B`_(ZwD(od6el! zEA94Flx0CX+SYD2>;Dlw`v>TnzRk(HjYTD{|qa@GHxB6M0 z$~et7&gbc%*E!eQ(QXjLNt_1(=_7j=z<9+x(_FBz=bOjlt6cnJFf(GC=Z=nP(XAZ) z=w9f8jFJ8not*9Qg75Po40KNv0zIo>>y~;IW4o}*@t(8K3TuvGuCmYOU~o_PVza7f zYi*~!DADznio!e!R#Lg6Zqod8l#r%KZ$X%~;#j-wD3pOrTiRVs)0}!uTiqgJH}0+l zy)bWUCnhKNE3JN{da2QF2_KqGTjYBx4^~y$4e$|}M`j`v_wZEE1}}~3Ve*49eUSap z$3`C>tf1iQ>{BrmLo4Ud2WiHZeCS9q{;avfN&$yH1)T&I^=9Gf8@9Sr&PtoK6~?+@i7%87Q!h^DhNSK$2}5dRZl! z&D?y0K0=CHh7`>&sEbgMdIO;O4>iDR)?oheAkre~`A(=*xTD@DqW6f%QDL$c=}Opx zWk@}}n)a1(r(h*cLbapq^)ybJ4RiI%H=h`v)0K7u8wwb+g=R|_B#g8IaV;2cRoXCYh@Qid zcA=FO$F$~;QHw#|Wj%YUDEJxDW5RbUJ3=Q=|RnZqxUH$J@DpHf0n^afxK+8Aate1xYFELsvHToWkDcMalW;!UCsLhMQ^AKU}AoBif-ux`NErQfedf zeefyZ&=t%ZDWHcx{{M1-`VY_e9FYX!hvfbrk{sQ|=9`8`1bw*wu|v}%w=Zi86;PL~ z@F`!={Mu9gih2v9CADnke%`E{dopNdlId>~g`hb-2nLqV=4K9}^?w2&^F!rGrzuPz7?^Ne-pL|XCbjZ0&7ox!x)>j?AC7W0UE$b|_%=a+f}JE&5sQP$ z^0m9m_x+I*s4Oanl(^M>Kp(9yP`?oboBgm;uBbcMUj2fAQlxHVd6>toZj`rEsVHwK@*ic)h3-+&MXD`==eKNn z=Bl9vMiqZH3qU5VyH$5yaL;vr>{@tRuBC`(%p2&YY4QqMMp-&%yNojD9&~L2Hq~PY z&&J-Cn&lQHC&W6G{0UyVc3AI4lj&bKdJ35{$kPCo_%G=gN@rAjdt8x*Nmt!4PJ&=* zP?suv5GQNrddXU|uC3cQZklS>cana$x1&PP8zIb>>H&tn81xK3+A$}U8vPFn((a}5 VBHkho%IKdDf{i$~?K-aE=3kI(g1`U( literal 0 HcmV?d00001 diff --git a/custodisco-kiosk.pde b/custodiscokiosk.pde similarity index 87% rename from custodisco-kiosk.pde rename to custodiscokiosk.pde index 05278b1..7decc86 100644 --- a/custodisco-kiosk.pde +++ b/custodiscokiosk.pde @@ -50,8 +50,7 @@ void displayMainMenu(int buttonY) { } void displayCreateItemScreen(int buttonY) { - textSize(64); - textFont(createFont("SansSerif", 64)); + textFont(createFont("Serif", 40)); fill(0); // Black text("do you have an existing Scuttlebutt account?", width/2, height/4); @@ -121,11 +120,11 @@ buttonNoPressed = false; void checkButtonHover() { int buttonY = height/2 + (height - height/2) / 2; if(state == 0) { -button1Hovered = mouseX > width/3 - 100 && mouseX < width/3 + 100 && mouseY > buttonY - 50 && mouseY < buttonY + 50; -button2Hovered = mouseX > 2 * width/3 - 100 && mouseX < 2 * width/3 + 100 && mouseY > buttonY - 50 && mouseY < buttonY + 50; + button1Hovered = mouseX > width/3 - 100 && mouseX < width/3 + 100 && mouseY > buttonY - 50 && mouseY < buttonY + 50; + button2Hovered = mouseX > 2 * width/3 - 100 && mouseX < 2 * width/3 + 100 && mouseY > buttonY - 50 && mouseY < buttonY + 50; } else if(state == 1) { -buttonYesHovered = mouseX > width/3 - 100 && mouseX < width/3 + 100 && mouseY > buttonY - 50 && mouseY < buttonY + 50; -buttonNoHovered = mouseX > 2 * width/3 - 100 && mouseX < 2 * width/3 + 100 && mouseY > buttonY - 50 && mouseY < buttonY + 50; + buttonYesHovered = mouseX > width/3 - 100 && mouseX < width/3 + 100 && mouseY > buttonY - 50 && mouseY < buttonY + 50; + buttonNoHovered = mouseX > 2 * width/3 - 100 && mouseX < 2 * width/3 + 100 && mouseY > buttonY - 50 && mouseY < buttonY + 50; } } diff --git a/description for gpt.txt b/description for gpt.txt new file mode 100644 index 0000000..fa4ec81 --- /dev/null +++ b/description for gpt.txt @@ -0,0 +1,17 @@ +hi. I wonder if you could write a python program for me. The program is a kiosk with a number of different screens. In addition to the buttons described below, each screen also needs a home button in the top left that returns to Screen 0 as well as a back button in the bottom left that goes to the previous screen. Below I've detailed each screen, please generate the corresponding full screen (1366 by 768 resolution) python program: + +Screen 0: this is the title screen it has 2 buttons: create Item and Lookup Item. Create Item goes to Screen 1 and Lookup Item goes to Screen 14. +Screen 1: this screen has 2 buttons, Yes and No I Want to Make One Now. Yes goes to Screen 2, No I Want to Make One Now goes to Screen 7. +Screen 2: this screen contains a list that can be scrolled through and once an item from the list a Done button can be selected. The Done button goes to Screen 3. +Screen 3: this screen contains a live video feed from the webcam. There is a button, Take Photo, which causes a 3-2-1 countdown to appear and then the camera video feed is frozen. Once a photo has been taken in this way the Continue button may be pressed which takes us to Screen 5. +Screen 5: this screen contains a text box where the user can enter text. Once any text has been entered a Done button may be pressed which goes to Screen 8. +Screen 6: this screen contains some text and a button that says "I Understand" which goes to Screen 3. +Screen 7: this screen contains a texbox where a user can enter text. Once any text has been entered a Done button may be pressed which goes to Screen 6. +Screen 8: this screen has a rectangle (whose shape is of the ratio 2.25:1.25) where the user can draw. There is 1 button, Done, which when pressed goes to Screen 11. +Screen 9: this screen contains a text box which the user can enter text into. Once any text is entered they may click the Done button which takes us to Screen 10. +Screen 10: this screen says "thank you!" and has a big done button which goes to Screen 0. +Screen 11: this screen has 2 buttons, Sticker and Tag. A printType variable needs to be stored depending on which button is pressed. Both buttons take us to Screen 10. +Screen 12: this screen has 2 buttons, Re-print Tag, which takes us to Screen 8, and Post Update, which takes us to Screen 9. +Screen 14: this screen shows a live video feed. Once a QR code has been detected on the video, the QR code is decoded and stored to a variable. Then the screen changes to Screen 12. + +thanks so much! diff --git a/drawing.png b/drawing.png new file mode 100644 index 0000000000000000000000000000000000000000..f800bfd022d352d05988e2d57de88f3c0b66bc8e GIT binary patch literal 1772 zcmVf*p7{~wP-8LJP5>s(OLadQ`;K;QHv_|5P8~q3s;saD1kdS~iT;SLbfYg2f4sh!M zkquNTxAX%b;*?6cAmSxe>kzLW4l^E)U*_>_6)B~f{~_}3{_?!di)TCryu7@;yu7@; zyu7@;yu7@;yu5}b$c0)4Zq_auyX}DOC8v)#b0jsJ9u;I&rm%vJ@01LtoC@TrNCskC z1tqR9P=&2N$0d%ESRmqo0;*p_09+>!1fUpa;gc;AR;ubDIe>D=X^An$SPfxg+Qr+ME)K#8vITV|MI`Ju8KLiV+}{Ft}; z*`C=gS5)0Oj#^kNwyL`KTGbJUNnH?KTS{9PwyV}4qBA;^wokjGpqS~{p3$@Z(1?hB zHDb&ALj!>8NfleJs@n|>z-Us%c1*jr&{Qq60Ch|K-D3>ch?G;%!i=!3UzF3`l{CNG z>y*lw?jeTFj>Nahnyl`s-xyJ@tjQkxwBH!85g`Dukg*pw4EN0;lUcDhlAs1|TCq{6 zMi%Ue0>G`>DZ6?M05#9B^JQ(#o~Xnq;Q)nchMiUe5dkqUG_6wls_Yt;{y}OiOdmxt zFf^?atNb#&BM+#;TnWv*^Y8JEMUnUDKM&I>g-?JN(wR=CZ1Bw|2f* zb`ee;vGgLGI%129aQY%*YI5M`hX2iD6ORpJdgA7>GdE1HU3pAz^?59F!_pSUJ&_u= zws6DTtko;K7qID{7mF{#DWk8#0ZeuXdhBA2lFdY8Q7;k$07ju(3LjxS3;|a@sjP*) zzpGG0#5=A2`G#A0!wTabzQJWUi)0YfbqLyDJdaZVvMDO89}hYgz0x;42d9yN_1`G< z479Gbq!)?ZtVL}s?!_t%SPR=&GJ5Z1|K10AJtrR}S2N7{77N zU}A|A#?{xvA~!5_!x)(u(+noYG(%vywqtwm+cDG+vSttF!_T-t*LNbTu{!Lt?JRSM zjdG?U^}7U*-$Y?6iLojEo~wxdg;KW1$&5=nJSKha!W86Zfa!5n&|i!IrpGBv9DSF8 z>2a0Qp8zmjNny*IjSy_uG{yu>;p7h@Qz5e0vT89AGuYu&$930&jR7&uwB68#oleXL zptgzx+l|Mhwu%J$5u?z5`mpB5Q8I+dc`J6ZW=pk=y~AUX@@Gl4eV4JM+IDJ5wR1Cy zovc|>?cB5aQ#E#NGRgi_J5Kvk?O^?>8oM@i8TU}eY+1Prd$1q6+p)e>(`t%d5z&l@ z`p;T36FZP|SabwlKY8;GK z8pW+IoU8)v%W7-qZGFr z8TwPJwG^VtRGqY`9E!Q&b4mF;Yj%BAu~B4v_s5Ulko%zCVe=+gv%@v6ac0iZKZ_k{c! zpQ&u7RrO4#RO+jgh=>vugSM7RuiEZ(0%Q3xt_l{XP4`#|<3X;%GJ3Z~VZ*%rD5uxT zyKSr?g>7y)ZLvp1b=bDxuxgM#w3#z{JQ3~ppDWjO3$Ox^TaFFu-ERCK0j^rkD(g1A zUEm=uZ4F^>?", + lambda e: canvas.configure( + scrollregion=canvas.bbox("all") + ) + ) + + canvas.create_window((0, 0), window=scrollable_frame, anchor="nw") + canvas.configure(yscrollcommand=scrollbar.set) + + for user in users: + ttk.Label(scrollable_frame, text=user["id"]).pack() + + tk.Button(self, text="Done", command=lambda: master.switch_frame(Screen3), height=3, width=30, bg='peach puff').pack(pady=10) + container.pack() + canvas.pack(side="left", fill="both", expand=True) + scrollbar.pack(side="right", fill="y") + + def get_scuttlebutt_users(self): + result = subprocess.run(['node', 'scuttlebot.js'], capture_output=True, text=True) + if result.returncode == 0: + users = json.loads(result.stdout) + return users + else: + raise Exception("Command failed: " + result.stderr) + + + + + +class Screen3(tk.Frame): + def __init__(self, master): + tk.Frame.__init__(self, master, bg='#bcfef9') + tk.Button(self, text="Take Photo", command=lambda: master.switch_frame(Screen5), height=3, width=30, bg='peach puff').pack(pady=10) + +class Screen5(tk.Frame): + def __init__(self, master): + tk.Frame.__init__(self, master, bg='#bcfef9') + # Assume there's a method to manage the text entry + tk.Button(self, text="Done", command=lambda: master.switch_frame(Screen8), height=3, width=30, bg='peach puff').pack(pady=10) + +class Screen6(tk.Frame): + def __init__(self, master): + tk.Frame.__init__(self, master, bg='#bcfef9') + tk.Button(self, text="I Understand", command=lambda: master.switch_frame(Screen3), height=3, width=30, bg='peach puff').pack(pady=10) + +class Screen7(tk.Frame): + def __init__(self, master): + tk.Frame.__init__(self, master, bg='#bcfef9') + # Assume there's a method to manage the text entry + tk.Button(self, text="Done", command=lambda: master.switch_frame(Screen6), height=3, width=30, bg='peach puff').pack(pady=10) + +class Screen8(tk.Frame): + def __init__(self, master): + tk.Frame.__init__(self, master, bg='#bcfef9') + self.drawing = Image.new('1', (300, 540), 1) # creating new Image of size 250x450 (1.25:2.25 ratio) and color white + self.draw = ImageDraw.Draw(self.drawing) + self.last_draw = None + + # Creating the Canvas for drawing + self.canvas = Canvas(self, width=300, height=540, bg='white') + self.canvas.bind("", self.draw_line) + self.canvas.pack(pady=20) + self.canvas.bind("", self.reset_last_draw) + + tk.Button(self, text="Done", command=self.next, height=3, width=30, bg='peach puff').pack(pady=10) + + def draw_line(self, event): + x, y = event.x, event.y + if self.last_draw: + self.canvas.create_line(*self.last_draw, x, y, fill='black') + self.draw.line([*self.last_draw, x, y], fill=0) # Draw black line on Image + self.last_draw = (x, y) + + def next(self): + self.master.switch_frame(Screen11) # Switching to Screen11 after Done + + # Save the drawing as a .png file + self.drawing.save("drawing.png") + + def reset_last_draw(self, event): + self.last_draw = None + + + +class Screen9(tk.Frame): + def __init__(self, master): + tk.Frame.__init__(self, master, bg='#bcfef9') + # Assume there's a method to manage the text entry + tk.Button(self, text="Done", command=lambda: master.switch_frame(Screen10), height=3, width=30, bg='peach puff').pack(pady=10) + +class Screen10(tk.Frame): + def __init__(self, master): + tk.Frame.__init__(self, master, bg='#bcfef9') + tk.Label(self, text="Thank you!", bg='#bcfef9').pack() + tk.Button(self, text="Done", command=lambda: master.switch_frame(Screen0), height=3, width=30, bg='peach puff').pack(pady=10) + + +#sticker or tag? then print +class Screen11(tk.Frame): + def __init__(self, master): + tk.Frame.__init__(self, master, bg='#bcfef9') + tk.Button(self, text="Sticker", command=self.printy(2), height=3, width=30, bg='peach puff').pack(pady=10) + tk.Button(self, text="Tag", command=self.printy(1), height=3, width=30, bg='peach puff').pack(pady=10) + + tk.Button(self, text="Done", command=self.printy, height=3, width=30, bg='peach puff').pack(pady=10) + + # go ahead and print the thing + def printy(self, orientation): + self.master.switch_frame(Screen10) # Switching to Screen10 after Done + + # Specify the path to your image file + path_to_image = "drawing.png" + + # if sticker we gotta rotate 90 degrees.... I think + if orientation == 2: + image = Image.open(path_to_image) + rotated_image = image.rotate(-90) + rotated_image.save('drawing.png') + + # Get the ZPL code for the image + zpl_code = toZPL.print_to_zpl(path_to_image) + + # send the ZPL to the printer babeee + print(zpl_code) + + + +class Screen12(tk.Frame): + def __init__(self, master): + tk.Frame.__init__(self, master, bg='#bcfef9') + tk.Button(self, text="Re-print Tag", command=lambda: master.switch_frame(Screen8), height=3, width=30, bg='peach puff').pack(pady=10) + tk.Button(self, text="Post Update", command=lambda: master.switch_frame(Screen9), height=3, width=30, bg='peach puff').pack(pady=10) + +class Screen14(tk.Frame): + def __init__(self, master): + tk.Frame.__init__(self, master, bg='#bcfef9') + tk.Button(self, text="Done", command=lambda: master.switch_frame(Screen12), height=3, width=30, bg='peach puff').pack(pady=10) + +if __name__ == "__main__": + app = Kiosk() + app.mainloop() + diff --git a/pythonzpl.zpl b/pythonzpl.zpl new file mode 100644 index 0000000..7b34d57 --- /dev/null +++ b/pythonzpl.zpl @@ -0,0 +1 @@ +^XA ^FO0,0^GFA,14400,14400,32, ,:::L0GFGChV0K0G3G0G2hV0K0G4G0G1hV0K0G4H0GChU0K0G8H0G2hU0K0G8H0G1GChT0J0G1S0GFhK0J0G1T0GEhJ0J0G1T0G1GFhI0J0G1V0G8hH0J0G1V0G4V0G3gK0J0G2O0G8L0G3O0G1HFI0G3HCgJ0J0G2N0G1GCM0G8N0G2G7GEGCH0G4G0G2gJ0J0G2N0G3GFGEL0G8N0G1G8G0G2J0G2L0G1GFGCU0J0G2N0G6G0G1G8K0G8N0G2H0G1J0G1J0G1GFGEG0G4U0J0G2N0G8H0G4K0G4N0G2H0G1J0G1H0G3GFGEI0G4U0J0G1G8M0G8H0G2K0G4N0G4H0G1J0G1H0G6K0G8U0K0G6L0G1I0G1K0G4N0G4H0G1J0G1N0G8U0K0G1G8K0G1J0G8J0G8N0G4H0G1J0G1N0G8U0L0G6K0G1J0G8J0G8N0G4H0G1J0G1M0G1V0L0G1G8J0G2J0G8I0G1O0G4H0G1J0G1M0G1V0M0G6J0G2J0G8I0G2O0G2H0G1J0G1M0G2V0M0G1G8I0G2J0G8I0G4O0G2H0G2J0G1M0G4V0N0G4I0G2J0G8I0G4O0G1H0G2J0G2M0G4V0N0G2I0G4J0G8I0G4P0G8G0G4J0G2M0G8V0N0G2I0G4J0G8I0G4P0G8G0G4J0G2L0G1W0N0G1I0G4I0G1J0G4H0G1G8L0G4G0G8J0G2L0G1W0O0G8H0G4I0G1J0G2I0G7IFI0G4G1K0G2L0G2W0O0G8H0G4I0G1J0G2P0H2K0G4L0G2W0O0G8H0G4I0G2J0G1P0G1G2K0G4L0G4W0O0G8H0G4I0G4K0G8P0GCK0G4L0G4W0O0G8H0G4I0G4K0G4P0GCK0G4L0G8W0N0G1I0G4I0G8K0G4P0GCK0G4L0G8W0N0G1I0G4I0G8K0G4P0GCK0G8K0G1X0N0G2I0G4H0G3L0G4O0G1G2K0G8K0G1X0N0G2I0G2H0G4L0G4O0G1G2K0G8K0G2X0N0G4I0G2H0G8L0G4O0G2G1J0G1L0G2X0N0G8I0G1G8G3M0G4O0G2G1I0GFG1G0G1J0G4X0M0G1K0G7GCM0G4O0G2G0G8I0HFGEJ0G4K0G3GCQ0M0G2T0G4O0G4G0G8I0G2L0G8L0G3GCP0M0G4T0G4O0G4G0G8I0G2L0G8M0G3GCO0M0G8T0G4O0G4G0G8I0G2K0G1Y0L0G1U0G8O0G8G0G8I0G4K0G1Y0L0G2U0G8O0G8G0G4I0G4K0G2Y0L0G4T0G1P0G8G0G4I0G4K0G2Y0L0G8S0G8G1P0G8G0G4I0G4K0G4Y0K0G1T0G8G2P0G8G0G4I0G8K0GCY0J0G1G6T0G4GCP0G8G0G4I0G8K0GBHFGEV0J0G2G8T0G3Q0G8G0G8I0G8K0G8Y0J0G5gM0G8G0G8I0G8K0G8Y0J0GEX0G7GEM0G8G1I0G1K0G1g0gH0G1G8G1G8L0G4G1I0G1K0G1g0gH0GEH0G6L0G4GEI0G1K0G2g0gG0G3I0G1G8K0G3J0G1K0G2g0gG0GCJ0G4P0G1K0G2g0g0G1K0G2P0G2K0G2g0g0G6K0G2P0G2K0G4g0g0G8K0G1V0G4g0Y0G1M0G8U0G4g0Y0G1M0G4U0G4g0Q0G3GFGCK0G2M0G2U0G8g0Q0GCG0G3K0G4M0G2U0G8g0P0G1I0GEJ0G4M0G1U0G8g0P0G2I0G1G8I0G8M0G1T0G1gG0P0GCJ0G4H0G1O0G8S0G1gG0O0G1H0G1HFGAH0G1O0G8S0G1gG0O0G1H0G6H0G7G8G0G2J0G3J0G8S0G1G8g0O0G2H0G4H0G1G6G0G4J0HCI0G4T0G8g0O0G4H0G4H0H1G0G4I0H1GEI0G4gU0O0G4H0G2I0G8GCG8I0H2G3I0G4gU0O0G8H0G2I0G8G3G8I0H2G7I0G4O0G7GFgJ0O0G8H0G1I0G8G1G6I0G4G2G6I0G4N0G3G8G0G8S0GFO0N0G1J0G8H0G8G1J0G4G1G2I0G4N0G4H0G4Q0G3GFG0G8N0N0G1J0G8H0G8G1J0G8G1GBG0G8G0G4N0G4H0G2Q0GCH0G8N0N0G1H0GFG0G8H0G8G1J0G8G0GEG0G8G0G4N0G8H0G1L0G1GCH0G7I0G8N0N0G2G0G1H8G4H0G8G1I0G1J0GCG0G4N0G8H0G1L0GEG3GEG1G8I0G8N0N0G2G0G1G0G8G4G0G1G0G1I0G1J0G4G0G4N0G8H0G2H0G3G8G0G1G0G6H2J0G8N0N0G2G0G1GEG8G4G0G1G0G1I0G1J0G8G0G8Q0G2H0G4J0G8G1K0G8N0N0G2G0G1GBG8G4G0G1G0G1I0G1J0G8G0G8Q0G2H0G4I0G3G0G1K0G8N0N0G2H0GFG8G4G0G1G0G1I0G1J0G8G1R0G4H0G8I0G4G0G1J0G1O0N0G2H0GDHCG0G1G0G1I0G1I0G1G0G1R0G8G0G1J0G8G0G1J0G1O0N0G2H0G7G3H0G2H0GCH0G1I0G2G0G6Q0G1H0G1I0G1H0G1J0G1O0N0G2L0G2H0G2I0GCH0G4G0G8Q0G2H0G2I0G2H0G2J0G1O0N0G2L0G2H0G1I0G3H0G4G0G8Q0G2H0G4I0G4H0G2J0G1O0N0G2L0G4I0GCI0GCG0G8G7R0G4H0G8I0G4H0G2J0G1O0N0G2L0G4I0G3I0G3HFG8R0G8H0G8I0G4H0G4J0G1O0N0G2L0G4J0HFG9GFGCS0G3I0G8I0G4H0G4J0G2O0N0G1L0G8L0G6U0G4I0G8I0G2H0G8J0G2O0N0G1L0G8gH0G4I0G8I0G1H0G8J0G2O0N0G1L0G8gH0G8H0G1K0G8G1K0G4O0N0G1L0G8gG0G1I0G1K0G8G1K0G4O0O0G8J0G1gH0G2I0G1K0G6G2K0G4O0O0G8J0G1gH0G2I0G1K0G1G4K0G4O0O0G8J0G1gH0G4I0G1G0G1GEH0G1G4K0G8O0O0G8J0G2gH0G4I0G1G0H2I0GCK0G8O0O0G4J0G2gH0G4I0H1GCG1H0G1G2K0G8O0O0G4J0G2gH0G2I0G1G2G0G2H0G1G2K0G8O0O0G2J0G4gH0G1G8I0G8G0G2H0G2G1I0GEG1H0GCM0O0G2J0G4gI0G4I0G8G0GCH0G4G1I0G1IFN0O0G1J0G4gI0G3I0G4G3I0G8G1J0G1P0O0G1J0G8gJ0GFGEG0G3GCI0G8G1J0G1P0P0G8H0G1gR0G1G0G1J0G2P0P0G8H0G2gR0G1G0G1J0G2P0P0G4H0G2gL0G1G8J0G2G0G2J0G2P0P0G2H0GCgL0G1K0G2G0G4J0G2P0P0G1G0G3gM0G1K0G4G0G4J0G4P0Q0GFGCgK0G8G0HFJ0G4G1G8J0G4P0gX0G8G3G2G0GDI0G4G2K0G4P0gX0G8GCG2G0G3I0G7GCK0G4P0gX0GBG0G2G0G1P0G4P0gX0GCG0G2G0G1G8O0G4P0gW0G3G8G0G2G0G1G4H0G8L0G8P0gW0GCG8G0G2G0G1G2H0G8L0G8P0gU0G4G3G0G8G0G4G0H1H0G8L0G8P0gK0GEO0HCG0G8G0G4G0G1G0G8G0G4L0G8P0gK0GAO0GBH0G8G0G4G0G1G0G4G0G4W0gJ0G1P0GCH0G8G0G4G0G1G0G2G0G4W0gJ0G2O0G3G8G0G1H0G4G0G1G0G1G8G4W0gJ0G4O0GCG8G0G1H0G4G0G1H0G6G4W0gJ0G8N0G1G0G8G0G1H0G4G0G1H0G1G4W0gI0G1O0G6G0G8G0G1H0G4G0G1I0GCM0G3O0gI0G2N0G1G8G0G8G0G1H0G4G0G1I0GBG0G1H0G1G8G0G7O0gI0G2N0G6H0G8G0G1H0G4G0G2I0G8GEG1G0G1GEGCG0G5I0G1K0gI0G4N0GCH0G8G0G1H0G4G0G2I0G8G1HFGEG0G4G0G1G0G8G0G1K0gI0G8M0G1G4H0G8G0G1H0G4G0G2I0G8G0G1I0G4G0G1G0G8G0G1K0gH0G1N0G2G4H0G8G0G1H0G4G0G2I0G8G0G1I0G2G0G1G0G4G0G1K0gH0G2N0H4H0G8G0G1H0G4G0G2I0G8G0G1I0G2G0G2G0G4G0G1K0gH0G4M0G1G8G4H0G8G0G1H0G4G0G2I0G8G0G1I0G2G0G2G0G4G0G1K0gH0G8M0G6G0G4H0G8G0G1H0G8G0G2I0G8G0G1I0G2G0G2G0G4G0G1K0gH0G8M0G8G0G4H0G8G0G1H0G8G0G2I0G8G0G1I0G2G0G2G0G4G0G1K0gG0G1N0G8G0G4H0G8G0G1H0G8G0G2I0G8G0G1I0G2G0G2G0G4G0G1K0gG0G2M0G1H0G4H0G8G0G1H0G8G0G2I0G8G0G1I0G2G0G2G0G4G0G1K0gG0G4M0G1H0G4H0G8G0G1H0G8G0G2I0G8G0G1I0G2G0G2G0G4G0G1K0gG0G4M0G2H0G4H0G8G0G1H0G8G0G2I0G8G0G1I0G2G0G2G0G4G0G1K0gG0G8M0G2H0G4H0G8G0G1H0G8G0G2I0G8G0G1I0G2G0G2G0G4G0G1K0g0G1N0G4H0G4H0G8G0G1H0G8G0G2I0G8G0G1I0G2G0G2G0G4G0G1K0g0G2N0G4H0G4H0G8G0G1H0G8G0G2H0G1H0G2I0G4G0G2G0G4G0G2K0g0G2N0G2H0G4H0G8G0G1H0G8G0G2H0G1H0G2I0G4G0G2G0G4G0G2K0g0G4N0G2H0G4H0G8G0G1H0G8G0G2H0G1H0G2I0G4G0G2G0G4G0G2K0g0G8N0G1G8G0G4H0G8G0G1H0G8G0G2H0G1H0G2I0G4G0G2G0G4G0G2K0Y0G1P0G6G0G4H0G8G0G1H0G8G0G2H0G1H0G2I0G4G0G2G0G4G0G2K0Y0G2P0G1G8G2H0G8G0G1H0G8G0G2H0G2H0G2I0G4G0G2G0G4G0G2K0Y0G2Q0G4G2H0G8G0G1H0G8G0G2H0G2H0G2I0G4G0G2G0G4G0G2K0Y0G4Q0G3G2H0G8G0G1H0G8G0G2H0G2H0G2I0G4G0G2G0G4G0G2K0Y0G8R0GCH0G8G0G1H0G8G0G2H0G2H0G2I0G4G0G2G0G4G0G2K0X0G1S0G3H0G8G0G1H0G8G0G2H0G2H0G2I0G4G0G2G0G4G0G2K0X0G1T0G8G0G8G0G1H0G8G0G4H0G2H0G2I0G4G0G2G0G4G0G2K0X0G2T0G6G0G8G0G1H0G8G0G4H0G2H0G2I0G4G0G4G0G4G0G4K0X0G4T0G1G0G6G0G1H0G8G0G4H0G2H0G2I0G4G0G4G0G4G0G4K0X0G4U0GCG6G0G1H0G8G0G4H0G2H0G2I0G4G0G4G0G4G0G4K0X0G8U0G2H0G1H0G8G0G4H0G2H0G2I0G4G0G4G0G4G0G4K0W0G1V0G1H0G1G0G1H0G4H0G2H0G2I0G4G0G4G0G4G0G4K0W0G1W0G8G0G1G0G1H0G4H0G2H0G2I0G4G0G4G0G4G0G4K0W0G2W0G4G0G1G0G1H0G4H0G4H0G2I0G4G0G4G0G4G0G4K0W0G2W0G3G0G1G0G1H0G4H0G4H0G4I0G4G0G4G0G8G0G4K0W0G4X0G8G1G0G1H0G4H0G4H0G4I0G4G0G4G0G8G0G4K0W0G4X0G6G1G0G1H0G4H0G4H0G4I0G4G0G4G0G8G0G4K0W0G8X0H1G0G1H0G4H0G4H0G4I0G4G0G4G0G8G0G4K0V0G1g0G9G0G1H0G4H0G4H0G4I0G4G0G4G0G8G0G4K0:V0G2g0G7G0G1H0G4H0G8H0G4I0G4G0G4G0G8G0G4K0V0G2g0G3G0G1H0G4H0G8H0G4I0G4G0G4G0G8G0G4K0V0G4g0G1G0G1H0G4H0G8H0G4I0G4G0G4G0G8G0G4K0V0G4gG0G8G1H0G4H0G8H0G4I0G4G0G4G0G8G0G4K0V0G8gG0G8G1H0G4H0G8H0G8I0G8G0G4G0G8G0G4K0V0G8gG0G4G1H0G4H0G8H0G8I0G8G0G4G0G8G0G4K0U0G1gH0G4G1H0G4H0G8H0G8I0G8G0G4G0G8G0G4K0:U0G2gH0G2G1H0G4H0G8H0G8I0G8G0G8G0G8G0G4K0U0G2gH0G2G1H0G8H0G8H0G8I0G8G0G8G0G8G0G4K0U0G4gH0H1H0G8H0G8H0G8I0G8G0G8G0G8G0G4K0:U0G4gI0G9H0G8H0G8H0G8I0G8G0G8G0G8G0G4K0U0G8gI0G9H0G8H0G8H0G8I0G8G0G8G0G8G0G4K0U0G8gI0G9H0G8G0G1I0G8I0G8G0G8G0G8G0G4K0T0G1gJ0G9H0G8G0G1I0G8I0G8G0G8G0G8G0G4K0T0G1gJ0G5H0G8G0G1H0G1J0G8G0G8G0G8G0G4K0:T0G2gJ0G5H0G8G0G1H0G1J0G8G0G8G0G8G0G4K0::T0G4gJ0G5H0G8G0G1H0G1I0G1H0G8G0G8G0G4K0:T0G8gJ0G5H0G8G0G1H0G1I0G1H0G8G0G8G0G8K0:S0G1gK0G5H0G8G0G1H0G1I0G1H0G8G0G8G0G8K0S0G1gK0G4H0G8G0G1H0G1I0G1G0G1H0G8G0G8K0:S0G2gK0G4H0G8G0G2H0G1I0G1G0G1H0G8G0G8K0S0G2gK0G4H0G8G0G2H0G1I0G1G0G1G0G1H0G8K0::S0G4gK0G4H0G8G0G2H0G1I0G1G0G1G0G1H0G8K0S0G4gK0G4G0G1H0G2H0G1I0G1G0G1G0G1H0G8K0S0G4gK0G4G0G1H0G2H0G2I0G1G0G1G0G1H0G8K0:S0G8gK0G4G0G1H0G2H0G2I0G1G0G1G0G1H0G8K0:S0G8gK0GCG0G1H0G2H0G2I0G1G0G1G0G1H0G8K0S0G8gK0GAG0G1H0G2H0G2I0G2G0G1G0G1G0G1L0R0G1gL0GAG0G1H0G2H0G2I0G2G0G1G0G2G0G1L0::R0G1gK0G1G2G0G1H0G2H0G2I0G2G0G1G0G2G0G1L0R0G1gK0G1G2G0G1H0G2H0G2I0G2G0G2G0G2G0G2L0:R0G2gK0G1G2G0G1H0G2H0G2I0G2G0G2G0G2G0G2L0R0G2gK0G1G2G0G1H0G2H0G2I0G4G0G2G0G2G0G2L0R0G2gK0H2G0G1H0G2H0G2I0G4G0G2G0G2G0G2L0::R0G2gK0H2G0G1H0G2H0G2I0G4G0G2G0G4G0G2L0:R0G4gK0H2G0G1H0G2H0G2I0G4G0G2G0G4G0G2L0R0G4gK0G4G2G0G1H0G4H0G2I0G4G0G2G0G4G0G4L0:R0G4gK0G4G2G0G1H0G4H0G2I0G4G0G2G0G8G0G4L0:R0G4gK0G8G2G0G1H0G4H0G2I0G4G0G2G0G8G0G4L0:R0G8gJ0G1G0G2G0G1H0G4H0G2I0G4G0G2G0G8G0G4L0R0G8gJ0G1G0G2G0G1H0G4H0G2I0G4G0G4G0G8G0G4L0:R0G8gJ0G1G0G2G0G1H0G4H0G2I0G8G0G4G0G8G0G4L0R0G8gJ0G2G0G2G0G1H0G4H0G2I0G8G0G4G0G8G0G4L0R0G8gJ0G2G0G2G0G1H0G2H0G2I0G8G0G4G0G8G0G4L0::R0G8gJ0G4G0G2G0G1H0G2H0G2I0G8G0G4G0G8G0G8L0R0G8gJ0G4G0G2G0G1H0G2H0G2I0G8G0G4G1H0G8L0R0G8gJ0G8G0G2G0G1H0G2H0G2I0G8G0G4G1H0G8L0::R0G4gI0G1H0G2G0G1H0G2H0G2I0G8G0G4G1H0G8L0:R0G4gI0G2H0G2G0G1H0G2H0G2I0G8G0G4G1H0G8L0:R0G4gI0G4G2G0G2G0G1H0G2H0G2I0G8G0G4G1H0G8L0R0G4gI0G4G2G0G2G0G1H0G2H0G2I0G8G0G8G1H0G8L0R0G2gI0G8G2G0G2G0G1H0G2H0G2I0G8G0G8G1H0G8L0:R0G2gH0G1G0G2G0G2G0G1H0G2H0G2I0G8G0G8G1H0G8L0R0G2gH0G2G0G2G0G2G0G1H0G2H0G2I0G8G0G8G1H0G8L0:R0G1gH0G4G0G2G0G2G0G1H0G2H0G2I0G8G0G8G1H0G8L0R0G1gH0G4G0G2G0G2G0G1H0G2H0G1I0G8G0G8G1H0G8L0R0G1gH0G8G0G2G0G2G0G1H0G2H0G1I0G8G0G8G1H0G8L0S0G8g0G1H0G2G0G2G0G1H0G2H0G1I0G8G0G8G1H0G8L0:S0G8g0G2GCG0G1G0G2G0G1H0G2H0G1I0G8G0G8G1H0G8L0S0G4g0G4G8G0G1G0G2G0G1H0G2H0G1I0G8G0G8G1H0G8L0S0G4g0H8G0G1G0G2G0G1H0G2H0G1I0G8G0G8G1H0G8L0S0G2g0H8G0G1G0G2G0G1H0G2H0G1I0G8G0G8G1H0G8L0S0G2Y0G1G0G8G0G1G0G2G0G1H0G2H0G1I0G8G0G8G1H0G8L0S0G1Y0G1G0G8G0G1G0G2G0G1H0G2H0G1I0G8G0G8G1H0G8L0S0G1Y0G2G0G4G0G1G0G2G0G1H0G2H0G1I0G8G0G8G1H0G8L0T0G8X0G4G0G4G0G1G0G2G0G1H0G2H0G1I0G8G0G8G1H0G8L0T0G8X0G8G0G4G0G1G0G2G0G1H0G1H0G1I0G8G0G8G1H0G8L0T0G4X0G8G0G4G0G1G0G2G0G1H0G1H0G1I0G8G0G8G1H0G8L0T0G2W0G1H0G4G0G1G0G2G0G1H0G1I0G8H0G8G0G8G1H0G8L0T0G2W0G2H0G4H0G8G2G0G1H0G1I0G8H0G8G0G8G1H0G8L0T0G1W0G7H0G4H0G8G2G0G1H0G1I0G8H0G8G0G8G1H0G8L0T0G1W0G9H0G4H0G8G1G0G1H0G1I0G8H0G4G0G8G1H0G8L0U0G8V0G9H0G4H0G8G1H0G8G0G1I0G8H0G4G0G8G1H0G8L0U0G4U0H1H0G2H0G8G1H0G8G0G1I0GCH0G4G0G8G1H0G8L0U0G2U0G2G0G8G0G2H0G4G1H0G8G0G1I0GCH0G4G0G8G1H0G8L0U0G2U0G4G0G8G0G2H0G4G1H0G8G0G1I0G4H0G4G0G8G1H0G8L0U0G1S0G8G0G8G0G8G0G2H0G5GDH0G8G0G1I0G4H0G4G0G8G1G8G0G8L0V0G8R0G8G1H0G8G0G2H0G7G1H0G8G0G1L0G4G0G8G0G8G0G8L0V0G4R0G8G2H0G8G0G2H0G6G1H0G8G0G1L0G4I0G8G0G8L0V0G2R0G8G4H0G8G0G2H0G4G1H0G8G0G1L0G4I0G8G0G8L0V0G1R0G9G8H0G8G0G2H0GCG1H0G8G0G1L0G4K0G8L0W0GCQ0G6I0G8G0G2G0G1G6G1H0G8G0G1L0G4K0G8L0W0G3Q0G4I0G8G0G2G0G2G0G1H0G4H0G8K0G4K0G8L0X0G8O0G1GCI0G8G0G2G0G2G0G1H0G4H0G8K0G4K0G8L0X0G6O0G6G4I0G8G0G2G0GCG0G1H0G4H0G8K0G4K0G8L0X0G1G8L0H1G8G4I0G8G0G2G1H0G1H0G4H0G8K0G4K0G8L0Y0G7L0G1GEG0G4I0G8G0H2H0G1H0G4H0G4K0G4K0G8L0X0G1G0GFK0G7H0G4I0G8G0G2G4H0G1H0G4H0G4K0G4K0G8L0X0G1H0GEG2H0G3G9H0G4I0G8G0G2G8H0G3H0G6H0G4Q0G4L0X0G1H0G1IFGCG1H0G2I0G8G0G3I0G3H0G2H0G4Q0G4L0X0G1I0G2I0G1H0G2I0G8G0G2L0G2H0G6Q0G4L0X0G1I0G2I0G1H0G2I0G8G0GEL0G2H0G6Q0G4L0X0G1I0G2I0G1H0G1I0G8G1M0G3I0G3P0G4L0X0G1I0G2I0G1H0G1I0G8G2M0G3J0GEO0G4L0Y0G8H0G2I0G1H0G1I0G8G4M0G2J0G1GFG8M0G4L0Y0G8H0G2I0G1H0G1I0G9G8T0G7GFL0G4L0Y0G4H0G2I0G1H0G1I0GAW0HFJ0G4L0Y0G4H0G1I0G1H0G1I0GCY0GFI0G4L0Y0G4H0G1I0G1I0G8G0G1G8g0GEH0G4L0Y0G4H0G1I0G1I0G8G0G6G8g0G1GFG0G6L0Y0G4H0G1I0G1I0G8G0H8gH0GFM0Y0G4H0G1I0G1I0G8G1G0G8gI0GFL0Y0G4H0G1I0G1I0G8G6G0G8gI0G1L0Y0G2I0G8H0G1I0G9G8G0G8gP0Y0G2I0G8H0G1I0GEH0G8Q0JFGCT0Y0G2I0G8H0G1I0GCG0G1V0G3GES0Y0G1I0G8H0G1H0G3G4G0G1M0G6O0G1HFQ0Y0G1I0G8H0G1G0G1GCG4G0G1M0G1GEQ0GFP0Y0G1I0G8H0G1G0G6G0G4G0G1N0G1GFGEP0GFO0g0G8H0G8H0H1G8G0G4G0G1P0G1GFP0GFGCG4L0g0G8H0G4H0G1G6H0G2G0G1R0GFG8O0G3GEL0g0G8H0G4H0G1G8H0G2G0G1S0G7GCV0g0G8H0G4H0GFI0G2G0G1T0G3GFU0g0G8H0G4H0G1I0G2G0G1V0GFGCS0g0G8H0G4H0G1I0G2G0G1J0G2R0G3GFR0g0G8H0G4H0G1I0G2G0G1J0G2T0GFQ0g0G4H0G4H0G1I0G1G3H8I0G1GET0GFG8O0g0G4H0G2H0G1I0G1G0G7G8I0G3IFGER0G7GFG0G2L0g0G4H0G2H0G1I0G1H0GEK0G3G8G1HFGEQ0GFG9L0g0G4H0G2H0G1I0G2H0G9GEK0G7GFGEG0G1IFO0G7G8K0g0G2H0G2H0G1L0GCG1GFL0G1GFG8I0IFS0g0G2H0G2H0G1L0GCH0GFG8L0G7GFK0HFGEP0W0HFG8G2H0G2H0G1L0GCI0G7GEM0IFJ0G1GEO0Y0G7GFGEG0G1H0G1L0GCJ0G1GFGCN0GFGCI0G1GFG8G3L0g0G2G1IFG0G1S0G3GFG8M0G3HFG8H0G7GFL0g0G3H0G1G0IFGCS0G7HFGCM0G7GFG8N0gI0G1H0G1G0G3KFG8P0G3GFN0G7GCG1G8K0gI0G1H0G1M0G7IFO0HFGEL0G3GFGCK0gI0G1H0G1P0G3IFGCL0G3G1IFG8J0G8K0gJ0G8G0G1P0G1I0G3HFGCI0G5G8I0G7GEO0gJ0G8G0G1P0G1H0G2I0G3HFGEH4J0G1GEN0gL0G1P0G1H0G4K0G4G9GFGCK0G3GFM0gL0G1P0G1H0GCK0I8G3GFGCI0G4G2GEG8K0gW0G2G0G1J0G6G0G8G5G0G1HFH0G1G8H1GCK0gW0G2G0G1J0G7G0G8G7J0GFGEG2H0G8L0gW0G2G0G1J0G5G1G0G2J0G4G1GFGEG0G4L0gW0G2G0G1J0G5G2L0G2G1G8G2G0G2L0gW0G2G0G1J0G9GAL0G1GEI0G3L0gW0G2G0G1J0G8GCR0GEK0gW0G2G0G1G0G3H0G8S0G1K0gW0G2G0G2G0G4G8G0GFG8S0G8J0gW0G2G0G2G0G8G4GFG8G6S0G8J0gR0G3J0G2G0G2G0G8G3G0G8G1S0G4J0gR0G1J0G4G0G2G1G0G6G1H0G8R0G4J0gR0G1J0G4G0G2G1G0G9G1L0G3GFG8L0G2J0gS0G8I0G4G0G2H1G0G9K0G7GCG0G7GEK0G2J0gS0G8I0G4G0G4G1G2G0G9G0G1IFG8I0G1GCJ0G1J0M0G4gK0G8I0G4G0G4G1G4G0G7G0G1GEM0G3J0G1J0M0G6N0GFGEU0G8I0G4G0G4G0G8G0G6H0GFGCM0G8I0G1J0M0G2M0G3G0G1G8M0G1G8K0G4I0G4G0G4G0G8I0G7G0GBG8L0G4I0G1J0M0G2M0G2H0G4M0G2G4K0G4I0G4G0G4G1I0G3G8G0G6G7G8K0G3I0G1J0M0G2I0G3GEH0G4H0G2M0G4G2K0G4I0G4G0G4G1I0G4H0G1G0G6L0G8I0G8I0M0G2H0GFGCG1G8G0G4H0G1M0G4G1K0G2I0G4G0G4G2I0G4I0GCG1GEG0G3G8H0G4I0G8I0M0G2G0G3I0G6G0G4H0G1M0G8G1K0G2I0G4G0G4G2I0G8I0G2G0G1G8G4G8H0G2I0G8I0M0G2G0GCK0G4I0G8L0G8G1K0G1I0G4G0H4H0G1J0G1H0G6G8G4H0G1I0G8I0M0G1G7L0G8I0G8L0G8G1K0G1I0G4G0H4H0G1G0G7H0G1H0G1GEG2I0G8H0G4I0M0G3G8L0G8I0G8L0G8G0G8K0G8H0G4G0G4G8H0G2G0G7G8H0G8G0H1G2I0G8H0G4I0L0G1GDM0G8I0G8L0G8G0G8K0G8H0G4G0H8H0G2G0G6G8H0G8G0G1G0GEI0G4H0G4I0L0G6G0G8L0G8H0G1L0G1H0G4K0G4H0G4G0H8H0G2G0G3G8H0G4G0G1G7G3I0G4H0G2I0K0G1G8G0G8L0G4H0G1L0G1H0G4K0G4H0G4G0G9I0G2G0G1GCH0G2G0G1GFG7I0G4H0G2I0K0GEH0G4L0G4H0G2L0G1H0G2K0G4H0G4G0G9I0G4H0GCH0G2G0G3GFGDI0G2H0G2I0J0G7I0G4L0G2H0G2L0G1H0G2K0G2H0G4G0G9I0G4K0G2G0G3G7GAI0G2H0G2I0I0G3G8I0G4L0G2H0G2L0G2H0G1K0G2H0G8G0G9I0G2K0G2H0G2GCI0G2H0G1I0H0G7GCJ0G2L0G2H0G4L0G2H0G1K0G1H0G8G0GAI0G2K0G2H0G1G8I0G1H0G1I0H0GCK0G2L0G1H0G4L0G2H0G1K0G1H0G8G0GAI0G2K0G4M0G1H0G1I0H0G4K0G1L0G1H0G8L0G2I0G8K0G8G0G8G0GAI0G2K0G4M0G1H0G1I0N0G1L0G1H0G8L0G4I0G8K0G4G0G8G0GAI0G1G8J0G8M0G1H0G1I0N0G1L0G1G0G1M0G4I0G4K0G4G0G8G0GAJ0G6I0G1O0G8G0G1I0O0G8L0G8G2M0G4I0G4K0G2G0G8G0GAJ0G1G8H0G6O0G8G0G1I0O0G8L0G8G4M0G4I0G2K0G1G0G8G0GAK0G7HFG8O0G8G0G1I0O0G8L0H4M0G4I0G2L0H8G0GAX0G8G0G1I0O0G4L0G4G8M0G4I0G1H0GCI0G9H0GAX0G8G0G1I0O0G4L0G3N0G4I0G1G0GFJ0G7H0GAO0G1GEM0G8G0G1I0O0G4L0G2N0G4I0HFN0GAL0GFGBIFGEL0G8G0G1I0O0G2L0G2N0G4G0G7GFG0G4N0GAI0G7G1LFG7IFI0G8G0G1I0O0G2L0G3N0G4G1G8H0G4N0G6H0JFGEG2G0GCG0GCG1G8G1G8H0G8G0G1I0O0G1L0G3N0G4G6I0G2N0G5H0G3HCH0G2G1H0G4G1H0G8H0G8G0G1I0O0G1L0G3G8M0G4G8I0G2N0G5G0G3GCG7I0G2G6H0G4G6H0G8H0G8G0G1I0O0G1M0G8M0H8I0G1N0G5G0GEG0G4I0G2G8H0G4GCH0G8H0G8G0G1I0P0G8L0G7M0G8K0G8M0G4G9G4G0G4I0G3I0G7I0G8H0G8G0G1I0P0G8L0G4GCL0G8K0G6M0G4G9G8G0G4I0G2I0GEI0G8H0G8G0G2I0P0G8L0G2G3GCK0G8K0G3M0G4G5G8G0G4I0G6H0G1G8H0H8H0G8G0G2I0P0G4L0G2G0G3G8J0G8K0G1M0H4G8G0GCI0G4H0G6G8G0G1H8H0G8G0G2I0P0G4L0G1H0G6J0G8S0H4GCG1GCI0G4H0H8G0G3G0G8H0G8G0G2I0P0G2L0G1H0G1J0G8S0H4GCG3G4H0G1G8G0G3G0G8G0G6G0G8H0G8G0G2I0P0G2M0G8H0G8I0G8S0H2GBGEG4H0GEG8G0G6G0G8G0G8G0G8H0G8G0G2I0P0G1M0G8H0G6I0G8S0H2G8G0G4G0G3G0G8G0G4G0G8G3H0G8H0G8G0G4I0P0G1M0G8H0G1G8H0G8O0G1GFH0H2G4G0G7GBGCG0G8G0G8G0GFGCH0G8H0G8G0G4I0Q0G8L0G4I0G6H0G8O0GEG0G8G0G2G1G4H0G4G0G1H0G8J0G1I0G8G0G4I0Q0G8L0G4I0G1G8G0G8O0G8G0G4G0G2G1G4J0G1G0G1K0G1I0G8G0G8I0Q0G4L0G2J0G4P0G1H0G2G0G2G0GAJ0G1G0G1K0G1I0G8G0G8I0Q0G4L0G2J0G3P0G1H0G2G0G1G0GAJ0H1GFK0G1I0G8G0G8I0Q0G2G8K0G2K0GEO0G1H0G2G0G1G0G6K0GEL0G1I0G8G0G8I0Q0G2G4K0G7U0G1H0G2G0G1G0G2R0G1I0G8G1J0Q0G1G4K0G3U0G1H0G2H0G8G3R0G1I0G8G1J0R0GAgG0G1H0G2H0G8G1R0G2H0G1G0G1J0R0GAgG0G1H0G2H0G8G1G8Q0G2H0G1G0G1J0R0G6S0G3M0G1H0G2H0G4G0G8N0G3G8G0G4H0G1G0G2J0gL0G2N0G8G0G2H0G4G0GCN0G6G4G0G4H0G1G0G2J0gL0G2K0G6H0G8G0G2H0G4G0G4H0G7K0G8G2G0G4H0G1G0G2J0gL0G2K0GAH0G8G0G4H0G2G0G6G0G3G9G8J0G8G2G0G8H0G1G0G2J0V0G4O0G4J0G1I0G8G0G4H0G2G0G2G0G2G0G8H0G3H8G2G0G8H0G1G0G4J0U0G3GBO0G4J0G1I0G8G0G4H0G2G0G1G0G4G0G8H0G4G6G8H1I0G1G0G4J0U0GCG0G8N0G4J0G2I0G8G0G4H0G2H0G8G4G0G4GFGCG8G2G8H1I0G2G0G4J0T0G1H0G4N0G4J0G4I0G8G0G4H0G1H0GCG4G0G5G0G6G8G1G8G1G2I0G2G0G4J0T0G1H0G2N0G4J0G8I0G8G0G4I0G8G0G6G4G0G5G0G2G8G1G8G0GAI0G2G0G8J0Q0GEH0G2H0G2N0G4J0G8I0G4G0G4I0G6G0G3G2G0G5G0G2G8G1G8G0GCI0G2G0G8J0P0G3I0G2H0G2K0G8H0G8I0G1J0G4G0G4I0G1G0G1GAG0G5G0G2G8G1G8G0G8I0G4G0G8J0O0G1GCI0G2H0G2K0G8H0G8I0G1J0G4G0G4J0GCG0GAG0G5G0G2G8G0G8G1G8I0G4G0G8J0O0G2J0G2H0G2K0G8H0G8I0G2J0G2G0G4J0G2G0G6G0G5G0G2G8H0G2G8I0G4G1K0O0GCJ0G2H0G2K0G8G0G1J0G2J0G2G0G4J0G2G0G2G0G5G0G1G8H0G4J0G8G1K0N0G3K0G2H0G2K0G4G0G1J0G2J0G2G0G2J0G1G0G3G0G5G0G1G8H0G8J0G8G1K0N0G4K0G2H0G2K0G2G0G2J0G2J0G1G0G1K0G8G1G8G5G0G1G8G0G1K0G8G1K0N0G8K0G2H0G2K0G1G0G2J0G2J0G1H0G8J0G8G1GEG5G0G1G8G0G2J0G1G0G1K0M0G3L0G1H0G2K0G1G0G4J0G2J0G1H0G8J0G4G1G5GBG0G1H0GCJ0G1G0G1K0M0GCL0G1H0G4L0GCG8J0G3G1GEH0G1H0G6J0G4G0G2G7G0G1G0G1K0G2G0G1K0L0G1N0G8G0G4L0G3L0GEG2H0G1H0G1G8I0G4G0G1G3I0G2K0G6G0G1K0L0G2N0G8G0G4M0G1L0G4H0G1I0G4I0G2H0GBGCH0GCK0G8G0G1K0L0G4N0G8G0G8M0G1L0G4I0G8H0G2I0G2H0G6GBG8G7K0G3H0G1K0L0G8N0G4G0G8M0G1L0G8I0G8H0G1G8H0G1H0G3G8G7G8K0GCH0G1K0K0G3O0G4G1N0G1K0G1J0G8I0G6H0G1H0G1G8L0G3I0G1K0K0G2O0G4G1N0G1K0G1J0G4I0G1GCH0G8H0G8K0G1GCI0G1K0K0G2O0G2G1N0G1K0G2J0G4J0G3H0G8H0G6K0GEJ0G1K0K0G3G8N0G2G1N0G1K0G2J0G4K0GCG0G8H0G1J0G7K0G1K0L0G4N0G1G2K0G1H0G1K0G2J0G4K0G3GCG8I0GCH0G7G8K0G1K0L0G3G8M0G1G2K0G1H0G1K0G4J0G4M0G8I0G3HFG8L0G1K0M0G8N0GAK0G2H0G1K0G4J0G4M0G4S0G1K0M0G6N0GAK0G2I0G8J0G4J0G4M0G4J0G1G8M0G1K0M0G1N0GAK0G4I0G8J0G4J0G4M0G2J0G2G6M0G1K0M0G1N0G5K0G8I0G8J0G4J0G4M0G1J0G2G3M0G1K0N0GCG0G1HFG8H0G4GFI0G7J0G4J0G4J0G4N0HFG8G0G4G0G8M0G8J0N0G2G0G6H0G7G8G0G2G0IFG8J0G4J0G2J0G4P0G4G0G8G0G8M0G8J0N0G2G3G8I0G6G0G2O0G4J0G2J0G4P0G3GFG8G0G4M0G8J0N0G1GCL0G1O0G2J0G1J0G8T0G4M0G8J0N0G3M0G1O0G2J0G1I0G7U0G2M0G8J0M0G8G4G8L0G1O0G1K0GFG0GFG8U0G2M0G8J0M0GFH8M0G8N0G1L0GFW0G1G8L0G4J0O0G4M0G8O0G8gJ0G4L0G4J0O0G2M0G4O0GAgJ0G2L0G4J0O0G2M0G4O0G6gJ0G1L0G4J0O0G1M0G2gU0G8K0G4J0O0G1M0G2gU0G4K0G4J0P0G8L0G1gU0G2K0G4J0P0G8L0G1gU0G1G8J0G8J0P0G4L0G1gV0G6J0G8J0P0G4L0G1gV0G1G8I0G8J0P0G4hJ0G7I0G8J0hV0GCH0G8J0hV0G2H0G8J0:hV0G1H0G8J0hW0G8G1K0::hW0G4G1K0^FS^XZ diff --git a/scuttlebot.js b/scuttlebot.js new file mode 100644 index 0000000..aad96c7 --- /dev/null +++ b/scuttlebot.js @@ -0,0 +1,39 @@ +// scuttlebot.js + +const ssbClient = require('ssb-client'); +const ssbKeys = require('ssb-keys'); +const pull = require('pull-stream'); + +const keys = ssbKeys.loadOrCreateSync('~/.ssb/secret'); + +ssbClient(keys, (err, sbot) => { + if (err) { + console.error(JSON.stringify({ "error": "Failed to connect to the Scuttlebot server. Is it running?" })); + console.error(err); + process.exit(1); + } + + const authors = new Set(); + + pull( + sbot.createLogStream(), + pull.drain((msg) => { + authors.add(msg.value.author); + }, (err) => { + if (err) { + console.error(JSON.stringify({ "error": "Failed to retrieve messages." })); + console.error(err); + process.exit(1); + } + + const feeds = Array.from(authors).map(author => { return { id: author } }); + console.log(JSON.stringify(feeds)); + try { + sbot.close(() => {}); + } catch(err) { + console.error("Error closing SSB server connection: ", err); + } + }) + ); +}); + diff --git a/tozpl.py b/tozpl.py new file mode 100644 index 0000000..204cc1e --- /dev/null +++ b/tozpl.py @@ -0,0 +1,135 @@ +#this code was converted to python from http://www.jcgonzalez.com/java-image-to-zpl-example by chatgpt and trav. We modified it together a bit to only accept black and white images :) + + +from PIL import Image +import numpy as np + +class ZPLConveter: + def __init__(self): + self.total = 0 + self.width_bytes = 0 + self.compress_hex = False + self.map_code = {1: 'G', 2: 'H', 3: 'I', 4: 'J', 5: 'K', 6: 'L', 7: 'M', 8: 'N', + 9: 'O', 10: 'P', 11: 'Q', 12: 'R', 13: 'S', 14: 'T', 15: 'U', 16: 'V', + 17: 'W', 18: 'X', 19: 'Y', 20: 'g', 40: 'h', 60: 'i', 80: 'j', 100: 'k', + 120: 'l', 140: 'm', 160: 'n', 180: 'o', 200: 'p', 220: 'q', 240: 'r', + 260: 's', 280: 't', 300: 'u', 320: 'v', 340: 'w', 360: 'x', 380: 'y', + 400: 'z'} + + def convert_from_img(self, img_path): + image = Image.open(img_path) + cuerpo = self.create_body(image) + if self.compress_hex: + cuerpo = self.encode_hex_ascii(cuerpo) + return self.head_doc() + cuerpo + self.foot_doc() + + def create_body(self, image): + width, height = image.size + orginal_image = np.array(image) + index = 0 + aux_binary_char = ['0', '0', '0', '0', '0', '0', '0', '0'] + self.width_bytes = width // 8 + if width % 8 > 0: + self.width_bytes = ((width // 8) + 1) + else: + self.width_bytes = width // 8 + self.total = self.width_bytes * height + sb = [] + for h in range(height): + for w in range(width): + pixel = orginal_image[h, w] + aux_char = '1' if pixel == 0 else '0' # 0 for black, 1 for white + aux_binary_char[index] = aux_char + index += 1 + if index == 8 or w == (width - 1): + sb.append(self.four_byte_binary(''.join(aux_binary_char))) + aux_binary_char = ['0', '0', '0', '0', '0', '0', '0', '0'] + index = 0 + sb.append("\n") + return ''.join(sb) + + @staticmethod + def four_byte_binary(binary_str): + decimal = int(binary_str, 2) + if decimal > 15: + return hex(decimal)[2:].upper() + else: + return "0" + hex(decimal)[2:].upper() + + + def encode_hex_ascii(self, code): + maxlinea = self.width_bytes * 2 + sb_code = [] + sb_linea = [] + previous_line = None + counter = 1 + aux = code[0] + first_char = False + for i in range(1, len(code)): + if first_char: + aux = code[i] + first_char = False + continue + if code[i] == '\n': + if counter >= maxlinea and aux == '0': + sb_linea.append(",") + elif counter >= maxlinea and aux == 'F': + sb_linea.append("!") + elif counter > 20: + multi20 = (counter // 20) * 20 + resto20 = (counter % 20) + sb_linea.append(self.map_code[multi20]) + if resto20 != 0: + sb_linea.append(self.map_code[resto20] + aux) + else: + sb_linea.append(aux) + else: + sb_linea.append(self.map_code[counter] + aux) + counter = 1 + first_char = True + if ''.join(sb_linea) == previous_line: + sb_code.append(":") + else: + sb_code.append(''.join(sb_linea)) + previous_line = ''.join(sb_linea) + sb_linea = [] + continue + if aux == code[i]: + counter += 1 + else: + if counter > 20: + multi20 = (counter // 20) * 20 + resto20 = (counter % 20) + sb_linea.append(self.map_code[multi20]) + if resto20 != 0: + sb_linea.append(self.map_code[resto20] + aux) + else: + sb_linea.append(aux) + else: + sb_linea.append(self.map_code[counter] + aux) + counter = 1 + aux = code[i] + return ''.join(sb_code) + + def head_doc(self): + return "^XA " + "^FO0,0^GFA," + str(self.total) + "," + str(self.total) + "," + str(self.width_bytes) + ", " + + @staticmethod + def foot_doc(): + return "^FS" + "^XZ" + + def set_compress_hex(self, compress_hex): + self.compress_hex = compress_hex + + def set_blackness_limit_percentage(self, percentage): + self.black_limit = (percentage * 768 // 100) + +def print_to_zpl(img_path): + converter = ZPLConveter() + converter.set_compress_hex(True) + return converter.convert_from_img(img_path) + +if __name__ == "__main__": + zp = ZPLConveter() + zp.set_compress_hex(True) + print(zp.convert_from_img("drawing.png"))