In this episode, Damien Burke, software entrepreneur and creator of EarlyWords.io, Neverbust, and Neighborhood Council Management System, talks about how in working in so many different industries over the years, it all comes down to User Experience. It doesn't matter who you’re building software for, it needs to be clear on what it does, it needs to provide a benefit, and it needs to make it easy for users to see what that benefit is.
Damien also has an interesting definition of God Objects, which he shares with Relicans host Ali Finkelstein, and gives advice to engineers that he wishes somebody would have told him 20 years ago: write ugly code. Write the ugly code and then make it better. It's so much easier to make code better than it is to initially worry about writing good code.
Should you find a burning need to share your thoughts or rants about the show, please spray them at firstname.lastname@example.org. While you’re going to all the trouble of shipping us some bytes, please consider taking a moment to let us know what you’d like to hear on the show in the future. Despite the all-caps flaming you will receive in response, please know that we are sincerely interested in your feedback; we aim to appease. Follow us on the Twitters: @PolyglotShow.
Jonan Scheffler: Hello and welcome to Polyglot, proudly brought to you by New Relic's developer relations team, The Relicans. Polyglot is about software design. It's about looking beyond languages to the patterns and methods that we as developers use to do our best work. You can join us every week to hear from developers who have stories to share about what has worked for them and may have some opinions about how best to write quality software. We may not always agree, but we are certainly going to have fun, and we will always do our best to level up together. You can find the show notes for this episode and all of the Relicans podcasts on developer.newrelic.com/podcasts. Thank you so much for joining us. Enjoy the show.
Ali Finkelstein: Hi, welcome back to the Polyglot podcast. I'm Ali. You can find me on Twitter @endingwithali. Today we have Damien Burke. Damien, can you start by telling the listeners a little bit about yourself?
Damien Burke: Yeah, sure. My name is Damien Burke. I have been building internet startups for about 20 years.
Ali: That's awesome. And on the topic of internet startups, what sort of genres of companies have you worked for, what fields, and what industries?
Damien: That's a great question. That's one I don't usually think much about. I've been all over the place. For me, the most important thing when building software I always want to go to the place where software isn't. Software engineers have the best software in the world because we built it ourselves for ourselves. We also have some crap stuff too, but we won't talk about that. [Chuckles] But you look at places that are far-flung from the software industry, things that don't look cool and just haven't been looked at yet, there's so much opportunity there, and there's so much opportunity to make the world better, to generate wealth and to just improve the lives of people because they haven't had the attention of software products and software engineers put on them. So that didn't answer your question.
Recently, I was the senior product manager at an on-demand helicopter startup, which is really cool and brand new, and it didn't work out. I have consulted for things like a drayage company, drayage, which is the movement of shipping containers specifically from the port to a nearby warehouse. That's a very short part of the global supply chain world. I'm working in government tech right now, building software for neighborhood councils, which are the smallest unit of government in Los Angeles and close to the world, I think. And in the past, I have another project I built for poker players. I was a professional poker player for several years and built a product to help professional poker players out.
Ali: So you've touched on a lot of different industries and a lot of different sectors of the world. What's something that you find is consistent across all of these different industries?
Damien: I think it comes down to ease of use and user experience. Those are kind of two ways of saying the same thing. It doesn't matter if you're building it for government users or if you're building it for the general public. It needs to be clear what it does. It needs to provide a benefit. It needs to make it easy to see what that benefit is. One of the big problems I have with the poker product is there's a huge benefit, and it all centers around this magical math that I discovered; I didn't invent it, somebody else invented it, and I found it. [Chuckles] But it was difficult to communicate what that benefit was, and so that was the real trouble with different users: it's not exactly obvious what you're getting out of it. And so that becomes most important, making it obvious what benefit you're getting, making it easy to use and get that benefit.
Ali: Interesting. And I think we can now tie this into what you were telling me about before we started recording, which was God objects and how ease of use isn't only important for the user, but it's also important for the developer.
Damien: Yeah. And I'm so glad you brought that up because -- and it's probably really clear for you because I understand you work in developer relations, and you build software for software engineers. So thinking of an engineer's user experience is really important and ingrained in everything you do. When you build products for people who are not on the team building the product (you can't see me waving away where they are), you can think about their experience: What's the user's experience? What is this person over there going to experience? And forget about my colleague sitting in the cubicle next to me or who's going to pull down those protocols. What's going to be their experience with it, or what's going to be my experience with it when I look at this next month or next week? Will it help me next year?
Ali: Awesome. You were saying that you have a very interesting definition of God object. I think that maybe you should lay it out for our listeners, so they know what it is because we were talking about it before, and it seemed like it was pretty technical.
Damien: Yeah, forgive me, everyone out there, especially the pedants. And if you correct me on the pronunciation of pedant, then you're one of them. [chuckles]
Ali: I don't know what that means, so...
Damien: I may not use this word. I didn't come up with this term. I may not use it the way that people use it, and I may not have the most precise and accurate definition of it. When I say God object, what I mean is that thing in your object-oriented system that is kind of center and everything is kind of pulled towards it. It's funny. I was thinking about, because I knew we were going to talk a little bit about this, I was thinking about my really, really early experiences in learning object-oriented programming. And when they don't tell you why you're doing programming object-orientedly, ooh, that's a fun word, object-orientedly. If nobody tells you why then your object is just a place to put your methods. And then you learn your object represents some aspect in the domain or the world around you. It's great when they represent physical aspects, and it's more difficult when they don't. But they represent some singular concept. But in every domain or at least almost every domain, there's one singular concept that feels so much more central, and so it will tend to pull in all of the functionality of your app, and it will interact with all of the other objects and all the other pieces, and that can be difficult. You no longer have the clear separation and organization that makes it easy to see where things go, how things work, who exactly does what, and why? Because everything is happening in or through this God object.
Ali: In what situation have you faced dealing with a God object?
Damien: Oh my goodness, I feel like every project I'm on has one, and they have different issues. I'll start with an easy one, the neighborhood council management system. I get to plug it because it's my project. [Chuckles] The God object that emerged out of that is a meeting. You have neighborhood councils, they have boards, have committees. But most importantly, they all have meetings, and so much of what the system does is dealing with that: When are the meetings? Where are the meetings? What was decided at the meetings? Taking minutes of the meetings, everything goes through a meeting. I've had to be very careful going okay, no, the meeting doesn't really have agenda items. Agendas have agenda items. And so how can I make an agenda a separate thing from a meeting? And doing those things to kind of clarify both technically where this data is stored and how can I access it and change it? But also, from a UI perspective, when I look at a meeting, what do I want to see? I'm struggling with this right now. I probably don't want to look at a meeting. I probably want to look at either a meeting's agenda or its minutes. So this is one area where that pull of the God object has given me issues.
Another example where this happened was with the on-demand helicopter company. We had journeys, which were the center of everything. Customers come to the site, and they book a journey, or sometimes they don't book a journey. Sometimes they look at a journey and say, "Oh, is this something I want to buy?" And they buy a journey. And then our concierges come through and go, okay, let me assign this journey to this flight. And then somebody says, "Well, how much will that journey cost?" You got to ask about the journey. Well, where did it go to? And then when did it go from a go-to from the customer's perspective or from the operator's perspective, the guys who actually are the people who are actually flying the helicopters? Everything went through a journey, and it was huge. We had a whole lot of them, and it caused a lot of problems.
Ali: Interesting. I'm super interested in hearing about these problems. What kind of chaos do these God objects cause in prod?
Damien: They can cause anything. They can kill you anywhere. In this case, since you mentioned production specifically, one of the issues is that we had a lot of them because every time a user wanted to go, "Oh, well, should I go from this place to that place? How much will that cost? Or should I go from this place to that place?" In some user flows, that would cause a journey to be created. And so, every click-through of examining how much it would cost to go from point A to point B every time users saw that, a journey was created for them, which we can use to calculate how much it costs. This created a lot of journeys, especially as we got press. We measured our visitors per month in a six-figure range. And every one of those visitors might've created 1 or 10 or 20 journeys, that table grew very quickly. Now everything else is going through journeys. So if a concierge needs to go okay, who can we put on this flight? Well, let me look at all the journeys, except there's a whole bunch of them. Most of them were never purchased. All of them extended back to the beginning of the operation, and so that's a huge join, and that join is really being done for everything that the system was doing. And for things that were already complicated and difficult, we had some very complicated SQL in this project. So things that were already complicated and slow just got way more complicated and slower.
Ali: And I should say on the other side, what about in development? What kind of issues did these God objects cause?
Damien: So we had one issue because the origin and destination that a user booked is not the same. The locations that a user chooses are not the same as the locations we send them to or take them from. For instance, at one particular location, we could have three operators with three different helipads, but they're all at the same address or at some general aviation airport. So we would show the users that's one location, but then at the other end, our concierges need to see three locations so that they can put them with different operators because operators are connected to the particular location. They're going to land where they can land. Now our journey has a user origin and destination, and it has a real origin and destination. This is incredibly confusing. When do we show which, and what do they mean? And why do some exist sometimes and not other times? That was just one of the types of confusions that we ran into.
Ali: What have you done about it in the past?
Damien: When it gets to be too big, you have to pull things out, you have to split it. And this is true about every object. It's just your God object will inevitably -- that's why it's called the God object. It’s the one that draws everything in and pulls everything to it. It's always good to recognize these and split them early because putting things together is so much easier than taking them apart. It just blows my mind the difference there. So what we did in this case, we separated the journey. We separated it into two objects, one being what the user purchases and one being what they actually get. So they make a purchase saying, "I want to go from A to B." What they actually get is okay, this helipad at A location to that helipad at B location. These are very different things, and you can create them separately. And there are a lot fewer purchases than there are users looking. I look at something I go, what does this look like? Is this something I want? I can make 20 of those before I make a purchase, and so now that purchase table is purchases; that's a good name for it. That’s not what we used, but that purchases table is a lot smaller and easier to deal with.
Ali: Interesting. So in the future, say you're giving a talk to people about designing object-oriented systems, at what points would you say having something like a God object is good or when is it bad? And do you generally say, "Hey, don't do that," or do you say, "Hey, yeah, it's okay here but not okay there"?
Damien: Well, I would say that a God object is almost inevitable. I can't think of a domain where every class of object is equally important or equally central. If you think of your objects as a network, these things talk to these things. Those things talk to those things. There’s going to be a Kevin Bacon in your object network that everybody's connected to somehow. And that's fine. That's okay. I think where it's really valuable is being aware of that and being aware of where that might give you problems. That central object is going to have a strong tendency to take on more behavior and more responsibilities, and so knowing that you should always be very suspicious. If you go, okay, this is my God object whenever I want to add something to it, or whenever I want something that goes through it, I should be very suspicious of that because that is the obvious answer, and it will almost always be the obvious answer, and the result is I'll have something that is too large to work with. So know that that's the obvious answer. When that answer comes, you go, okay, is this really it? And maybe it is, and maybe it is for now. Maybe it's like, oh, okay, maybe it's not quite right, but I'm going to put it here now, knowing that I'll probably want to move it soon as opposed to waiting until you have a deadlock database and going oh, no! What happened? Why is this class 10,000 lines?
Ali: Speaking of 10,000 lines, it sounds like you have some experience trying to pick that apart.
Damien: Splitting out that journey object was -- I say it's a 12-week project, but I honestly don't know. I distinctly remember having worked on it for a really long time and going okay. In two more weeks, I'll be done. [chuckles]
Ali: It's always two more weeks.
Damien: Which is great because I'm going on vacation in two weeks, and I don't want to pass this on to anybody else, so it needs to be done. And those two weeks came and went, and I wasn't done. I went on vacation, and I came back, and I kept going. [Chuckles] And it was more than two weeks after that before I actually did it. And that was a huge project because, again, everything went through this object, and it had all of the most important data. And being able to do the data migration and the class separation, and do them all at once and have everything go to the new classes as necessary, was huge. And I did it all over months on a single long-lived branch that was heavily tested. I thank the Lord above for that one or me because I wrote the test [Laughter]
Ali: Or the God object.
Damien: Yeah. And I got to say that is one of the most impressive things I've done as an engineer because we shipped that deploy, and it was almost flawless. I think there was one tiny UI issue for a tertiary user. It blew my mind that that actually works. But then I did my own little personal retrospective and post-mortem, even though nobody died, and I'm, like, this was the longest living branch I've ever worked on. Meanwhile, we have ten other engineers that are moving at a rapid pace. They're great engineers, and I'm constantly trying to have to rebase, make sure that they're not breaking, or fix the things that are no longer relevant. That's actually where the problem was. I hadn't incorporated. And I don't want to do that, I don't want to spend all my time rebasing things and having these long-lived branches, and I would never recommend somebody do that. And it took so much effort and work and, honestly, intellectual firepower, and it was not the right way to do it. So why did I do it like that? And the answer is I didn't want to ship ugly code.
Ali: That's the secret: you never want to ship ugly code.
Damien: I didn't want to ship ugly code, and I should have. The way to separate these objects is to do it slowly, piece by piece. If I extract agenda from meetings, it might not do all the things an agenda should do. Some of those things the God object is still doing that the new object should do. And so it's really confusing, like wait, shouldn't that thing be over here? Yes. Yes, it should. It's not yet. It's not done. Software is never done. So that's what it comes down to. I didn't want my team to see this inconsistent object that was confusing, and that was wrong, honestly. Things that should be on it, weren’t. I could have written a lot of pass-throughs where things still get called on the God object, and the God Object now knows to delegate before those calls get changed. Those are NoOps functions: It's not pretty, it's not elegant, but I should have shipped them anyway. And especially with the team who knows what direction we're going towards. And so they know like, oh, this is a thing in progress. It doesn't make sense because we're heading in this direction, and we all understand what direction it's going towards. I could've kept shipping code the whole time. I would've got done a lot faster, probably.
Ali: Speaking of shipping code, just curious what were some of the challenges when it came to -- you did it in one big push. What were some of the challenges you faced when having to deal with prod data and breaking up this God object, and having future instances following this new object protocol?
Damien: That was the big thing, the production data. I think we still had downtime deploys. We were resigned to the fact that we were going to be down for 1, 2, 15, 30 minutes. That was scary also because we didn't know how long it was going to take. You can test it on development, but that's not the same. You're not going to create 100,000 records. You're not going to have the same behavior if you did. Databases are very much a black box. Sometimes you don't know what's going to be fast and what's going to be slow. That was very scary. Getting the data over in a way that was provably consistent was difficult. I wrote a lot of specs to show that the data at the end meant the same thing as what we had in the beginning, and that was very difficult. We don't usually write specs for database migrations, and for good reason. But this was a big, dangerous thing, so I had a lot of specs for that. That was also another problem because we don't usually write specs for database migrations. There wasn't the framework and the sensibility to do that. And then also because I'm doing it in one big push, I felt the need to make it reversible. If I was doing little pieces, I guess I would have still made them reversible because it would have been a lot easier. But this big thing is also very big. It's double the amount of work because you have to be able to do it, and you have to be able to undo it also.
Ali: What kind of challenges did you get from the people when you were like, I'm going to do this. I'm very curious to know how did people react? How was communication with engineers? What were they pushing back on?
Damien: Everybody was on board. I'm usually the guy who goes whoa, that's really big; let's not do the really big thing. So that was a failure on my part this time. Everybody knew that this was a problem, and all the engineers want to fix engineering problems. That's awesome. Let's fix the engineering problem. The big issue there was a lot of pairing. I take a lot of credit. I've been taking credit for this project the entire time, but I didn't do it alone. [Laughs] I was pairing almost every day with that, and that became a challenge. As this project went on and on and on – rotating a new pair in, it was a lot of time bringing them up to speed, like, what's going on? Why is it doing all of this? Which was also valuable because sometimes things didn't make sense. And there is cruft from things I did earlier when I thought they made sense. So having to explain it to somebody new and them going, "Wait, what? I don't understand," helped me see A, sometimes it didn't make sense, and it was wrong, and it was great that they came in and said, "What's going on here?" so we can fix it. And also, it made me see, oh no, this is complicated when I show it to the person they don't understand it. So we need to make it so that when I show it to somebody, they'll understand it. I will never consider it acceptable for a particular feature or story to go for three or five days. Something has gone wrong there.
Ali: Really? That's actually a really interesting takeaway because it's not even related to the object, but it's more just about your project planning, right?
Ali: It's a much more meditative meta take away.
Damien: Yeah. It's tough to use the word agile in our industry because there's a whole sub-industry surrounding that. But if you look up agile in the dictionary, and I know this because I have, it means able to change directions quickly. And if you spend a week doing something that's a week, you're not able to change directions.
Ali: Yeah. Interesting. What are some of the security aspects you had to tackle when decoupling a God object?
Damien: I didn't give that question a lot of thought. I was able to not give that question a lot of thought thanks to one really great technical choice we made in this project and one I make in all my Rails projects. There's a security framework called Pundit. It's basically simple objects that connect ActiveRecord objects, database objects to what a user can do with them. So you have a policy that associates with objects, and you give it a user, and then it can tell you what the user can do on that object. So really, all of my security concerns were ameliorated by just copying the same policy. I had one object, now I have two. They have the same policy because they were one before. So that was a really neat trick. That made things a lot easier.
Ali: Yeah. That's awesome. And then what about security aspects from the different industries that you've worked in? How have they affected your job as an engineer?
Damien: In a lot of ways, the security issues are all the same. I worked many years ago on a social media network for teen girls, young teen girls. And one day, I came in, and I said -- This was many years ago, so forgive me a bit. I said to one of my bosses, "Should we be using SSL on the site?" And he asked me several questions, and the answer is "Yes, we should."
Damien: I know that. Use SSL everywhere every website uses SS. It's interesting because that is probably one of the -- well, no, they had other security concerns, so maybe that's not as good an example. But my point is that the security concerns are largely all the same. There are a couple of industries where we had to have security audits, and so that involved both looking at our codebase and looking for common mistakes and errors and basically writing it through something like Brakeman also some pen testing, and they came through with reports that were mostly BS thankfully. I think we did an amazing job. They came back with a list of a dozen things that most of them were like, oh, this is ridiculous. This is not a real thing. There might have been some real things in there. I don't know. But anyway, having to have those security audits and then having to go through and fix the things, even the things that are BS that come out of the audits, that's one way. With the gov tech thing, gov tech is super interesting. California and most states and I think the federal government also have what we call Sunshine laws. Shot aside, the reason why Florida man is such a meme is because of the Sunshine laws in Florida. Like the city itself, there's a lot of sunshine. And so there's a lot more data about the weird things that pop out of Florida that turn it into great news stories.
Ali: I'm also from Florida.
Damien: [Laugh] So yeah, so it's not that Floridians are weird, although they are.
Ali: We are very weird.
Damien: It's that the government is very transparent, and so we can see all the weirdness. [Chuckles] But in California, the law is called the California Public Records Act. And as a government official, it gets – I mean, it’s hairy. The point is that somebody could walk up to you and say, "I want all of your emails related to parking on this street." And now you have a statutory legal obligation to respond to them both completely and timely. And it's a bear. There are people who do this religiously both to find out about government and figure out what's going on also to embarrass government officials also just to grief the government. So this is the real hassle. So one of the choices I made with the neighborhood council management system, I'll plug it again, is, and I put this on the homepage, it's public by default. All the data that goes in there is visible to everybody who just wants to surf around and see what's going on, and that's a strange choice because it's not useful for almost everybody. But it also means that there are no CPRA requests against this system. If anybody says, "I want the data from these things." Like, “Here it is. It's on the website. Click here.” And just one more way of making life easier for the users there.
Ali: That's awesome. It seems like, as a software engineer, you really like to keep the end-user in mind, no matter what position you're working in.
Damien: Absolutely. Isn't that what it's all about? This was true of me. My interest is in the code. My interest is in the cool technical problems. And luckily, I've been in the industry longer, and part of it is an increase in capability. And part of that increase in capability comes from my experience and my skills, but also our tooling got better. And I'll use malloc as an example even though I'm not old enough; I actually needed to use that. But when I have to worry about, oh goodness, do I have enough memory? How do I allocate the memory? Did I make sure to release all the memory? Am I causing memory leaks? When I have to think about every variable and where it's stored in my RAM, I don't have the mental capacity to also wonder if this button's confusing, right?
Damien: So as we get better as individuals, and also as an industry, we can look out more. We can look out and see like, okay, well, if you put the button here, it's going to be different from where that last next button was, and that can be confusing. And we can look out and go, oh, but you know, if we put this functionality next to this, it's going to make the user feel a little less like they're dealing with something that cares about them, or it's going to cause them to treat the person they're dealing with a little more roughly or less humanely, think about the bigger pictures. That's been so much of what my career has been about. The progress of my career is how can I make a bigger influence and have an influence on a wider scale?
Ali: That's so interesting. And following that kind of train of thought and jumping back to something you said earlier, what has been one of the most interesting technical problems that you've faced throughout your entire career?
Damien: Wow, so hard. It's been so long since I was interested in a technical problem. [Laughs] That's not true. It's been so long since I've had something that was uniquely interesting. [Laughs] Last month, I had the problem of how can I use Jekyll 4 with GitHub pages? [Laughter] That was the technical problem I was solving, but that's not particularly interesting. Actually, it was a little interesting. [Laughter] Honestly, I think the most interesting technical problems are techno-social, but I think maybe they all are.
Ali: Did you watch The Social Dilemma?
Damien: No, I suppose I should.
Ali: Yeah, you should. [Laughs]
Damien: But on a small scale inside a team, how do I name this class so that the next engineer who looks at it immediately knows what it does or this method? Here's something that's come up a lot, sometimes the simple or the at hand solution is to add a bit of technology. I'll give you an example where this bit me. I led the migration away from AWS to Heroku. The company was using, I think, maybe three or four EC2 Instances. And we're like, ah; this is complicated move it to Heroku it's way simpler. The day that migration happened, we learned that one of those EC2 Instances was running Nginx and doing a reverse proxy. All of a sudden, this got very technical, sorry. [Chuckles]
Ali: It's totally fine. This is a technical podcast.
Damien: Okay, great. One of these instances was using Nginx as a reverse proxy and serving basically a second application that we didn't know about, a blog.
Ali: [Laughs] Ooh! Surprise blog!
Damien: So we migrate the application over to Heroku. The blog is gone now. And here's another thing that we didn't know about this company, the blog is the most important thing. So we're panicking a bit. It was a little bit of panic to discover it, and it was a little bit of panic to fix it. But here's the issue that we got bit on: there were multiple technologies. It was a Rails app, so it's entirely possible to integrate a blog into a Rails app. You're not going to get as good a blog as you will with dedicated blogging applications. But what you will get is one less technology, one less thing that when somebody pushes something, it breaks and they don't know about it. That's a difficult technical problem every time.
Ali: What's your Twitter?
Ali: Yeah. That makes sense. And as we're coming towards the end of our conversation, I'm curious if you have any pieces of advice for our listeners.
Damien: I'll give a piece of advice for engineers that I wish somebody had told me 20 years ago: Write ugly code, write code with duplication, with wrong variable names, with bad class structures or no class structure. Write the ugly code and then make it better. Don't try to write the good code first off. You don't know; you just don't know. It's so much easier to make code better than it is to write good code, especially if you write executable specs too. I'll tell a story that kind of illustrates this about a man I knew who's a working screenwriter, pays for his room and board, and everything based on jobs he gets to write screenplays. But the thing about writing screenplays most of the work as a screenwriter is not writing original screenplays; it’s rewriting. And he was very good at this, that's what he told me. He could take any screenplay and make it better, and it was his career, and he liked it. But he wanted to write his own original screenplays, and he was stuck. He couldn't write his original stuff. It just didn't come out. I had this conversation with him twice "Can you write a bad screenplay?" He's like, "What?" "Can you write a bad screenplay? You know how to make bad screenplays good. If you can write a bad screenplay, then you can make it good." It didn't work out for him.
Ali: Oh, no.
Damien: Or maybe it did. I haven't talked to him in a very long time. Maybe he's writing awesome original stuff now. I honestly don't know. It didn't click for him at the table we were at at the time. So I don't know. [Laughs]
Ali: Oh, no.
Damien: I'll give this to all of the thousands and millions of listeners here in the hopes that it can help some of you write the bad code and make it better. You'll never know what it should be until you've written what it shouldn't.
Ali: Yeah. That's really great advice. And where can our listeners find you?
Damien: You can find me at talariasoftware.com. That's where I write a lot about software. I have a series being published now called Joyful Rails; you can find that there. Subscribe to the RSS feed. It’s fun stuff. You can also see me – I'm a panelist on the Greater Than Code podcast, which is published every week, and it's absolutely wonderful. And it is exactly what's on the tin – talking about things that are Greater Than Code. Or you can find me on Twitter @ExMember, but don't, you don't want to do that.
Ali: And yeah, you can send your hate mail to him.
Ali: But you can find me on everything @endingwithali, A-L-I. Thank you so much everyone for listening. I really appreciate you, Damien, for taking the time out of your busy schedule, as well as you, the listener, for taking time out of your busy schedule to listen to us. So thank you so much.