 Well, it's that time of the week and it's time for chit chat across upon this episode number 752 for November 26, 2022, and I'm your host, Allison Sheridan. This week our guest is BART Boosh Shots, programming by Stealth installment 141. What's on our schedule for day day BART? Well, it's part two of our mermaid discussion. So well, actually, it's part one of our mermaid discussion. It's part two of our UML class diagrams discussion. So last time we learned about why we care about such things, which is, you know, that's the no-cellic-house-to-way, right? Start with the problem to be solved. And then we went on to look at the, do you call it a syntax? If it's a description of pictures, I don't know. I have the rules for a UML diagram. I don't know. Yeah, maybe rules. Yeah, it's syntax too, though. Yeah, I guess it is syntax. And then I left you on a teaser, which is, oh, yeah. And by the way, these diagrams are made from a text-based Markov language, which means we can keep it in version control and stuff. And that Markov language is our topic for today. And that is a language called Mermaid, which is inspired by Markdown, but for diagrams. Yeah, so is Mermaid the only way to create text-based UML diagrams or just the one that we're going to use? It is the only text-based one I'm aware of. OK. There are other, like, if you pay a lot of money for a development tool, these particularly exist for the more corporate languages like Java. So there are tools where you can just throw, like, five thousand, no, not like hundreds of thousands of lines of code at the tool and it will read the code and pull out the diagram for you. Wow. Wow. Yeah, I mean, they're high-end corporate level tools, which is amazing if you're handed someone else's code to maintain. You just throw it into the analyzer and then you go, oh, thank goodness, I can look at a picture. So here's something. Here's something funny. During Thanksgiving dinner, our buddy Ron was here for Thanksgiving down in San Diego, and I told him what we were doing in programming by stealth. And I mentioned UML class diagrams and he goes, oh, those things are great. We loved using those. He's a systems engineer doing space-based satellites. Oh, wow. I guess that's the only kind of satellites there are. But yeah, satellite communications and he was like a huge fan. He said the big thing that they gave you was if you create them and you create any a widow and or an orphan, you can't go forward. So it finds the widows and orphans that maybe if you were just using text to describe a system and your system's requirements or a function, you could create those and you wouldn't know that you created them. And so you literally cannot pass go unless you close all those connections. Well, that's very clever. Yeah, he's a huge fan. They are very powerful. Both visually and because a lot of times they're machine interpretable as well. So yeah, they're a fantastic tool. Now, so Mermaid is going to be our tool of choice for making our UML diagrams and Mermaid is actually more than just UML. So Mermaid is actually a diagramming tool in general. They have their website lists all the different types of diagram they currently support. And I guess at any point in time, they could add more types of diagram. I think that's true of any diagramming tool because I went out looking for a GUI-based UML diagramming app. And basically what I found was diagramming apps that can also make UML. Yes, yeah. I would have in the past used things like Omnigraphil to do my UML diagrams. And Visio makes them draw.io, my favorite drawing diagramming tool does. Actually diagrams.net is what it's called now. Just tons and tons of them. Yeah. So Mermaid is our choice and it is a JavaScript API that takes these text-based descriptions of diagrams and converts them into images. And like I say, UML class diagrams is one of its tricks but just looking at the docs here, it can do flow charts, it can do sequence diagrams, it can do state diagrams, EOR diagrams, whatever a user journey is. It can do Gantt charts, Pi charts, a requirement diagram, which I've never even heard of. A particularly useful one is actually a Git graph. So you know the way if you go to Gits or if you buy a book on Git, they have these lovely diagrams with circles representing the commits and lines connecting it all together when they describe like, what does it mean to make a branch? Well, I am instantly recognized the style of all of the stuff on the Git homepage. It looks like the Git graphs made with Mermaid. So maybe, either Mermaid is copying off the Git book or Git are using Mermaid, I'm not sure which. But either way, very useful. Something called a C4 diagram, which I don't know what that's about. And oh, mind mapping Allison, although it has an exclamation point and a vest icon, which I think means under construction. Yeah, I did start going down the path of trying to use Mermaid for flow diagrams and it's a big pain in the backside. Doing it text-based way harder than doing it in a GUI, dragging and dropping boxes. And so I'm curious to see whether this is a lot harder than you would think just drawing a box would be with some text fields in it. And some arrows and such. In this case, because you're sort of designing code, I think it probably makes sense that to have it in a text-based format. And the same is probably true of some of the other UML style diagrams. Well, I'm guessing, I'm not sure I'd want to use it for a mind map. Interesting, yeah. But as I say, it works well for this. So that is what we should be using it for. So if they actually have a live interface, because it's JavaScript-based, it works in browsers, of course. So there's a link in the show notes to their live editor where you can just type in Mermaid and watch it in real-time, which is kind of cool. It's also really good for debugging. If you're experimenting about it, just being able to put it into a live tool is so useful, especially while you're learning the syntax like I was this time last week or two weeks ago. Oh, yeah. And then really useful. I will say that as of the date of recording, there is a bug in the live version that it doesn't do the cardinalities on relationships in class diagrams in the GUI or in the live version. And that's kind of important. It's important for us, yeah, which is I thought I was doing it wrong. And then I ran it on the command line and they came out fine. And then I put the identical code into the live one and it didn't work. I was like, oh, okay, my code is right. Just a bug in the live one. So I should really get around to it's all in GitHub. I should log a bug against that actually. I should do that after we record. Do my little bit of civic duty for open source. So because it's JavaScript, it's probably comes as no surprise that we could install it using NPM. And you can actually include it in your own code. So you can actually include the mermaid code as a part of your own project. So if you were doing something like building an electron app, you could get your diagrams for free using mermaid and your pie charts and things. So that's potentially useful. But for our purposes, happily the official mermaid people also wrote a command line wrapper for their library so we can use it as a terminal command, which is of course what we're going to do because hey, that's how I roll. And you can also install the terminal command via good old NPM. If you would like to play along at home, you can download the zip file. It just contains the mermaid text files. To be honest, you can copy and paste them into text editor or whatever and save them as we go. It's probably not much more work than using the download. But anyway, I figured I'd bundled them up for you since I had to write them anyway. It does make it easier to just splat in the commands you've given since you've given us the files. That is true. So because we're getting this from Node.js, we need to make ourselves a folder to work in. Now I would suggest just using the folder from the zip file to work in. So if you pop that open in the terminal, we then need to install the mermaid CLI into that folder, which we can do with our good friend NPM install. I'm not sure the minus, minus save is all that important. But anyway, I just pure have it, I put that in. And then the package is at mermaid-js forward slash mermaid-CLI, which is definitely a copy and paste one. So you have to install that in every folder where you want to use mermaid? Yes. Which generally means realistically, you're going to be using it as part of a project. So you're actually just going to do an NPM install like you would in any of your other dependencies. Okay. Yeah. Certainly for UML diagrams, it's going to be a part of a bigger piece of work. Hypothetically, you can install an NPM package globally, but the mermaid people warn on their documentation side that there are strange bugs, I believe is the phrase they use, or something like weird behavior, something like that. If you do it globally. So I figured, well, if they're warning not to, let's, let's heed that. Always good to read the manual and then obey. So once we have it installed, we can exit. So the command line version of mermaid is MMDC. And the easiest way to run an executable file installed with NPM is with NPX, which is node package execute. So we just, the command for us will be NPX. MMDC, before you read it out loud, I want to cement MMDC, is this specifically class diagram? So we could memorize that as MM diagrams class? No, that is all of the maids. So mermaids. All of mermaid. Yeah. So I presume it's mermaid diagram creator or something. That's how I'm going to remember it the other way. I'm going to remember it the other way so I can remember it. Look, whatever works, whatever works. Okay. So it's MMDC. And because we're doing it over NPM, we're going to do NPX MMDC. So as I say, there is a hello world example sitting in the folder. So our first thing will be NPX MMDC minus minus scale to minus I hello world.mmd.txt minus oh hello world.png. And when you run that, it will make a file called hello world.png, which will contain two classes that will probably make you chuckle slightly, waffle and pancake. Okay, so backing up the dash I am guessing is the input file. Correct. And you've got sumname.mmd.txt and I'm assuming MMD.txt, you're doing that just as a convention to help you remember that was a mermaid diagram? Yeah, I, yes. I could have just thought that MMD but then nothing knows it's a plain text file. So I often do double barrel extensions like MD.txt for markdown and stuff like that. Okay, so you did MMD for mermaid diagrams. Okay, so that's, this could have been pancake.txt and it would work. Exactly. Yeah, it doesn't care about the file extension because the minus I it will just go fetch whatever you gave it with the minus I. So minus I for input minus oh for output. Okay, that's common but what's the minus minus scale space two? So by default it uses td tiny fonts that I don't like. So a scale factor of two means double everything. Okay. You're managing me very, you may want three, you may want 0.5 if your eyesight's amazing but I like two, two works for me. So if we look at that hello world file we will see that it is a very simple piece of markup. It says class diagram V2, class pancake, class waffle. And it makes two boxes, one called pancake and one called waffle. So that is a- Actually you should describe those two boxes to the audience because I'm looking at them but they are not. Yes, so those are like we learned about last time. So your class in a UML class diagram is a box of three boxes, sort of three rows in a box. How do we describe it last time? So three rows in a box I would say. Yeah, so the top row is where the name goes. The second row is where the attributes go and the third row is where the functions go. Now we haven't defined any attributes or any functions so literally our boxes just have their names in the top section, row or region. So the basic syntax is that you could actually have multiple diagrams in one file. So the basic syntax is you say the type of diagram you want so in our case class diagram V2 and then indented underneath that you have everything inside your diagram and then if you wanted a second diagram you could have class diagram V2 again and then it would make two diagrams I'm not entirely sure how it would do whether it would make two PNGs or not. To be honest I haven't experimented because I don't see why I want two in one. But the docs all say you can have two in one so there you go. So if you were doing something that isn't a class diagram you would start with E or diagram for an entity relationship diagram or mind map for a mind map or whatever type of mermaid diagram you want that goes first. Okay, all right. After you've said what type of diagram you want then the rules are different for every kind of diagram. So everything else we learned today is specific to class diagrams and if we were doing mind maps it will be different rules because again it doesn't make sense for them to be the same because they're completely different things. So for us then everything once we're inside our class diagram we start to list our things that we want in the diagram and you list the classes and you can define those and then the relationships are each a separate entry. So if you sort of think of it like you have an entry for each class and then you have an entry for each relationship is how I think of it. Okay and that's inside the squirrely brackets, right? Well inside the squirrely brackets go the details of the class. So effectively the squirrely brackets allow you to make one thing over multiple lines. So class pancake is one thing we're spreading over multiple lines because in theory there'll be other stuff inside our pancake class and class waffle is the same. So this is a very stripped down version because it's a hello world. So it'll become a little bit more obvious when we start to pad these out of base. And then the relationship has to just be separate entries and the order doesn't matter because what actually happens when you make a picture is that all of the markup is red and it builds an internal representation of what you're describing. And only when it's finished reading all of your input does it start to convert that internal representation into an output. So your order of things has no effect on the order of the output because it's just building up a model. Well that makes sense but because you've got these different relationships things are going up into other things and down into other things and the relationships of how many gizintas and get as out as and all that how many quarks there are in a nucleon, things like that, you can't have it be built sequentially. It just wouldn't make any sense. Precisely, which is actually very liberating because you can put things in any order you want and it'll be fine, which is nice. When you're used to programming where order matters this is nice, just throw it in and it's all good. Also for a long time there was no such thing as comments inside a mermaid diagram but they have recently added them so assuming you've downloaded a recent version you can make a comment by starting a line with percent percent and then adding in your comment. Can they please add that to Jason, come on. Oh please, please, please. Yes, that would be so useful to have that in Jason. Okay, so let us look at our class diagram syntax. So we define each class by saying class space, name of class space, open curly brace, hypothetically any content we want and then a closing curly brace on a line by itself. And it is important to have that space before the curly brace because otherwise mermaid thinks that your class is called my class curly brace. Oh, okay, okay, so no cuddling. No cuddling. No cuddling with the mermaid. There, we'll remember it now. There you go. And the closing curly is again a thing by itself because it basically means, no, I'm not adding anything else to this class, I'm now done. Otherwise it would see that as being a part of your relationship or something. It would get very confused. Okay, okay. So the simplest thing to add to your class is an annotation. So remember last time we said that you can annotate your class with the word abstract. That's actually the only valid annotation for us. And the annotation- Don't forget what an annotation is. So an annotation will show up in the name part of the box. It is a way of sort of, think of it as a tag, probably the easiest way. So we're tagging this class as being abstract. Now, if we were working in other languages, there will be other annotations possible, but in JavaScript, the only annotation possible is actually abstract, because JavaScript doesn't have- Okay, so it's either abstract or it's not there at all. Correct, in JavaScript. Okay, yeah. Okay. And so yeah, so it's angle bracket, angle bracket. Wait, what do you mean in JavaScript? You mean in these classes? Okay, UML can do more than we're learning about. So we are learning a subset of the UML class diagram. Right, but we're learning UML class diagrams. Okay, well- This isn't JavaScript we're writing. Correct. So UML class diagrams can do more than we have learned. Yes. Because other languages can do more than JavaScript can. Okay, but you said it's either abstract or nothing at all in JavaScript, but we're not writing in JavaScript, we're writing in UML. If you are describing JavaScript classes with UML, then the only annotation possible is abstract. If you're describing Java classes- Look close. Yeah, there we go. So if you're describing Java classes, you could have other ones like interface and there's loads of other ones in other languages, but in JavaScript, abstract or bust. Okay. So that's the easy part. Then we have to start adding our members to our class. So UML calls attributes and functions, it calls them all members. And our members actually have some of the rules in common, which is nice of it. And then the syntax is a bit different, but let's share it with what they have in common. So the marker for saying this is public is they're called visibility markers and plus means public and minus means private. And again, if we were working in other languages, there would actually be other possibilities because other languages have some, have visibility between public and private, but JavaScript has none of that. I would like a translucent indicator, please. It's actually protected as a very popular one, but JavaScript doesn't support it. So those are plus or minus. And then the other thing we can have is what's called a classifier. And the only classifier that comes into play for us at the moment is the dollar sign which signifies static. So dollar sign is static. So attributes and functions can both be static as a classifier. Yes, thank you. Okay, so let's look at the attributes. So the syntax, it takes the form visibility marker followed by type, space name, followed by classifier. And everything apart from the name is optional. And both the visibility marker and the classifier must be cuddled if they're present. So if you don't have a type, then the visibility marker juts against the name. The visibility marker can't be on its own. It has to be nudged into something. And the classifier has to be nudged into something. Think of them like magnets. Okay. So you clip one onto the front and you clip one onto the back. Okay, okay. And whatever you've got in between, if you've got more than one thing, if you've got a type and a name, they've got a space between them. But if it's only a name, then it would clip on both sides. And you can't have only a type. Yeah, that makes no sense. Because you have to have a name. You have to have a name, precisely. Yes. Okay. So that's a hard to say, but it actually makes a lot of sense when you see it written down. So if we look at a very silly example, we have class diagram V2, class my class. Then we open our own cuddled curly to open it up. So the most basic thing we could have is an attribute called a most basic attribute. It just has a name. That's it. Okay. So we could say, oh, we'll make it a public basic attribute by saying plus a basic public attribute. We could give it a type. So we say minus string space, a private string attribute, or we could have like a type and a visibility and a static. So basically a plus date space, a public static date attribute, dollar. Okay. So the important thing in that last one is it's got a plus at the beginning. It's got a dollar at the end. So the plus tells us a visibility. The dollar is the static attribute classifier, sorry. And then it's got date is the type and this long name you've written out is just the name. Yes, they've got a space between them because they can't be up against each other. Okay. Yeah. Got it. Yeah, I mean, it is sensible. By the way, this is much, it is much more sensible when you've just described it. There is great value in your description because I read it and I was like, what? Cause these names got really long as you were trying to be descriptive. Yeah. Right. I see what you're doing now. Okay. Yeah. And so if you run that through, so NPX, MMDC minus minus scale two, minus I example one, minus O example one, you will see how they look and they look just like the email specifications as they should because of course, mermaid is doing all the heavy lifting. So the static stove is underlined and the rest of it is actually pretty much as you typed it. Okay. And it appears in the middle box because they're attributes of course. So, right. Right. Moving on to functions then, the rules are not massively different, but there are more of them because functions can do more things. So again, the visibility marker goes on the front and has to be cuddled. Then we have to have a name. So the name is the only thing that's required. Sorry. The name and the parentheses are required because if you leave off the parentheses, it becomes an attribute definition. If it's just the name. Oh, does it know it's a function? Correct. So the name and the parentheses are required. Everything else is optional. So we have our optional visibility marker. And the parentheses must be, hang on, the parentheses must be cuddled to the name. The parentheses must be cuddled to the name. Yes. Okay. And so it's visibility marker cuddled to the name. Then the parentheses cuddled to the name. If you would like, you can list your parameters but you don't have to if you don't want to. And then if you want to classify, you have to cuddle it to the end of the parentheses. And then if you want to return type, it's space and then the return type. Okay. So the simplest function definition is just my function opens, open parentheses, close parentheses. Okay. And then all the rest is optional. And then the parameter list is comma separated just like you were writing it in JavaScript. But you have the option to have either name comma name or type space name comma type space name comma type space name. Now, in your written thing, it says that the return type can be void. So it's not really optional. No, no, you can just not say it. But if you want to explicitly say nothing, right? Not saying something is not the same thing as explicitly saying nothing, right? Yes. No, I should have said no. No, that isn't right. Okay. So if you want to explicitly say there's no return type, you can write void, but you don't have to write void, that's optional. Correct. So if you want to have your return types, if you're being really completist and you want to explicitly say this function returns nothing, then you give it the return type of void. Okay. It's quite a common practice in many languages. And then functions can have a second possible classifier because a function can be abstract. And the classifier for that is a star. Okay. So if you want to, yeah. Say again, what does a star mean? Abstract. Okay, all right. So unlike in the generic members list, the classifier was always at the end, but that's not the case on functions, even though functions are members. So that isn't something in common. Well, the classifier is cuddled to the end of the name. I don't think that I say in the text, it was always at the very end. I thought I changed my text. We verbally said it. So that's why I wanted to draw attention to it. So the visibility is always the starter and your classifier is cuddled to the end of the name, but you may have other stuff after that like void. Yes, or a dormant return type like string or Boolean or whatever, yes. Okay. Wait, so is string a classifier? No, no. The classifier is dollar. So string would just be a return type. If you have a function that returns a string. Oh, thank you. Thank you, gotcha, gotcha, gotcha. Okay. Yes. So again, we have our silly example class, class diagram V2, class my class. Oh, don't read this out. Don't read it out, right? It's basically a visual description of what I've just, or a visual example of what I've just said to illustrate the point. And when you generate the diagram, they end up in the lower box because that's where the functions go. And again, standard markup. Now the official markup, by the way, has a colon separating the return types. So you'll notice that the diagram has its colon, but the markup language is space delimited so it doesn't have its colons. Oh, interesting. Well, so you don't have to worry your pretty little heads about where those colons go. Precisely because it's doing the hard work for you. You're just telling it what you want and it knows the rules and it follows the rules. And so it comes to a nice diagram. That would seem to eliminate a lot of errors. Oh yeah, those from me anyway. Yeah, because I always forget. But get your spaces correct. If you mess up your spaces, you're still doomed. Right, because basically what you're doing then is you're naming things weirdly because everything just becomes part of the name if you coddle it all together. Which is because, oh, the name is required. You probably notice. Yes. You probably notice because it would be, you know, my class string. Oh, I lost you for a second, but I think you're back. Yep, we just had a little hiccup. We're good. Your internet connection is unstable according to Zoom, but I think we're back. I think we're back. Okay, so next up then is our relationships. And so these are just a one-liner. So we have our class with its uncuddled curly brace down to its curly brace on its own, but our relationships are just gonna be one-liners. One-line, one-line, one-line, one-line. And so the structure is the name of the two, the name of a class goes at the beginning and the name of another class goes in the end. And then between the two, we have an ASCII art arrow of some shape. And if we would like, we can have cardinalities inside quotation marks. So class name, space, quotation marks with a cardinality, space and arrow, space, cardinality, space, class name. And the cardinalities are optional. And are the cardinalities at the end where they would be drawn? So if you say class one, parentheses, or sorry, quote two, that means the two is gonna be sitting up next to that class name. Yes it is. And the second one is gonna be near the second class. Okay. Yes. And when you're drawing the arrows, they're a nice ASCII art. And you can actually draw them either way. So whatever way your brain likes, you can actually draw them either way and it'll be fine. And yeah, so again, they can be mirrored and they're ASCII art. So if you want inheritance, it's minus minus and then a pipe and a greater than sign. Yeah, it is a greater than sign. Yeah, yeah. Which looks kind of like a triangle-y sort of a shape. Which is what the inheritance arrow is. Okay. The composition arrow is a filled-in diamond, which is represented as minus minus star. And the aggregation one is an empty diamond, which is represented as minus minus lowercase o. Okay. It bothers me that the arrows can go either way. And they only go one way on the diagram. Oh, the diagram will be correct. But why wouldn't you draw them the way that they should look? Like you would want it next to the one on the left, wouldn't you? Well, no. Okay, so if you prefer to write the parent class first then you draw your arrows with the head towards the parent. If you prefer to have the child class first, then you draw it with the head towards the second class. Oh, that's optional. So you could be looking at somebody's UML and not know what it means. No, no, no, no. The diagram will look right. It's just if I look at their mermaid text, I won't know what it means. But it will look right. The ASCII art will be just like the diagram. It will be right. Okay, so let's say Mike Price and me and Dorothy are all working on these class diagrams for xkpasdbd.net. And I like the parent first and Dorothy and Mike like the child first, we're gonna be fighting drawing them, writing them differently in the same exact document. Yes, at which point I'll come along and say on the coding standard for this project is an autosat coin. Yeah, autosat coin early. Just to let you know, because you know me, Mike and Dorothy, we're just gonna be all over each other. We're gonna be up in each other's business on this. You do know, of course, that the way this usually works is people can't remember the syntax so they just look up at the document. And so if I do it right once, you'll all do it without even thinking about it, you'll all copy it. Oh, aren't you adorable that you think we won't have opinions part? I just believe in human laziness. Sorry, economy of effort. Because no one remembers these syntaxes and you could go look up the docs, what do you do? You scroll up and you hope to good as you find what you want when you scroll up, right? That's what I do all the time. I'm usually copying from myself, but you know. The parent is always near the tip of the arrow. The parent is at the tip of the arrow. And so whichever way around you draw it, it'll work just fine. And it is Ascii art. So it's very marked down like in the sense that it's this sort of Ascii art way of describing the relationships. So again, we can see the diagram for our atom from last time. I literally just took the atom from last time. And so you can see there in the example, we have our class nucleon, which you've marked as abstract. And then we can have our atom and our nucleon and they have their cardinalities and their arrows. And now I remember the last thing I had meant to say, which is that you don't even have to say class name of class. If you don't need to define anything about the class other than the relationships, just use it in a relationship and it will come into being. Because remember, it's building up the structure as you go. Okay, so when you say nucleon and you've got the arrow pointing towards it and then say proton, nucleon just became a class. Nucleon just became a class. And proton became a class, but I want nucleon to be abstract. So I have added a line that says class nucleon abstract. But I didn't add class atom. Oh, sorry, sorry. All right, you notice. Okay, and you didn't add class proton or neutron. Yes, because I have nothing to say about their content. So just adding them in a relationship is enough to make a blank class, which is great. Okay. That's just building it up as it goes. And so that works exactly as you would expect. So that is, you know, that's it to be honest, right? We now have our ASCII art, we have our syntax for everything. So everything we learned last time, we can now mark up in this texty language and we run an MMDC command and we get a diagram out. So now all I have to do is actually draw the diagram for all of the classes for HSXK past WD. I mean, how hard can that be? That's all you gotta do. You'll be really good at the syntax by the time you're done. That is very true. Or you'll have a hot mess, one or the other. Yeah, either is possible, right? But yeah, it'll be good practice. So I'll be very curious to see how I get on. Cause that's gonna be my first time using, like what's the phrase in anger? I mean, that's proper in anger, you know? So yeah, we'll see next time how it looks. I imagine it will be long. I wish you the best of luck. Actually, I think a good, we don't, you know, it bothers me when you don't give us homework because it doesn't, it doesn't cement. But if I was to do homework on my own, which I may or may not do, it would be without reading what you did, not studying what you did to create the class diagram, the UML diagram for the atom, would be to just look at last week's notes and try to, try to create it. That would be a really good thing to do actually. Yeah, because last week's notes describe the rules and then they show the picture. So could you replicate that in the code? Yeah, that's a perfect exercise. Yeah. I know everybody hates me when I ask for homework for PBS, but I don't, I really don't learn it. It just goes in and right back out if I don't get to practice, if I don't get to type it a little bit myself. Yeah, that's a good point, actually. And I got, I'm so out of practice at this, like forgetting to do things like set you homework and stuff. Yeah, anyway. Well, if this was a, definitely a short one, I could use a bite-sized deal. This, my granddaughter's about to wake up and when she wakes up, you will all hear it. Well, it is Thanksgiving. So you're in holiday mood. You may have had too much turkey yesterday. So the brain may be functioning on half power. Yes, it was the turkey that caused that. Yeah, not the, oh, what is it? You love to drink gin and tonics? Gin and tonics, not the gin and tonics. No, it was the turkey, definitely. Definitely. All righty. Well, you and I will be chatting in tomorrow, but the listeners will next hear us on this show in approximately two weeks, I hope. So until then, folks, happy computing. If you learn as much from Bard each week as I do, I'd like you to go over to letstashtalk.ie and press one of the buttons over there to help support him. He does 98% of the work here. I'm just the stooge that listens to him and asks the dumb questions. If you go over to letstashtalk.ie, you can support him on Patreon. You can donate via PayPal or you can use one of his referral links. I really hope you'll go over and help him out. In the meantime, you can contact me at Podfeet or check out all of the shows we do over there over at podfeet.com. Thanks for listening and stay subscribed.