August 10th, 2022
Length: 52 min
How to fix bugs in PHP faster with the Ray debugger
Learn how to implement Ray into to your PHP/Laravel development workflow to understand what exactly went wrong and how to fix it.
Who is this webinar for:
- How to install and start using the Ray debugger
- How Ray works under the hood exactly
- What are the measurable benefits of using a debugger tool in Laravel development
- A bit of special PHP magic that will make your life easier 🪄
What you're going to learn:
- PHP and Laravel developers who want to debug code in a more effective way
- Developers who are tired of using
- Developers who tried to get used to XDebug but failed miserably
02:38 Today we'll learn
06:40 How to debug your PHP code
08:27 Pros and cons of XDebug
09:46 Pros and cons of "dump and die" debugging
13:24 Benefits of using Ray
15:01 How to use Ray to debug PHP code
Hello everyone welcome to yet another Buddy Webinar today we are going to learn how to fix bugs in PHP but not only in PHP in a much easier way rather than using all those dies, var_dumps, console logs and XDebugs because yeah, XDebug is so, so difficult to set up with me I have I have the creator of Ray application, Ray debugger Freek van der Herten. Tell us a few words about yourself.
Yeah, I'm a mainly PHP and Laravel programmer. I work at a company called called Spatie in Belgium. And together with my colleagues, we created digital products and courses. We created a lot of things in my free time I created some sauces as hobby projects, as well. So yeah, I'm into programming and I'm also a little bit let me tilt the camera a little bit into music as well. I got some cool synthesisers, here and there in my room. So yeah, music and programming. That's me.
And I am Maciek Palmowski I am WordPress ambassador and your favourite and only webinar host here at Buddy.
Today we'll learn
So today we like I mentioned we are going to learn a bit about debugging in PHP using Ray. So we are going to learn how to instal and use it. We'll see how Ray works, and how it can speed up your whole development process. Also, if you if you like what we are doing here, don't forget to subscribe to our YouTube channel, you will be not only informed about what's new is coming, but you will have a chance to watch all the other webinars we already did. Okay, so without any further ado, Freek show us how to use Ray and tell us a few words about
okay, I've prepared some slides. I've also prepared a demo already. Yeah, yes. I'm okay. I'll share a couple of slides and I'll show you how it works. If there are any questions, Maciek just just ask them, I don't mind.
Also, if you also have some questions, remember you have the comments sections on YouTube, on LinkedIn on Facebook, use them and we'll try to respond to as many as possible. So
let me take it away. So I'm going to talk about fixing bugs faster using Ray. You have already introduced myself a little bit I'm Freek. I'm a partner in a developer at Spatie you will also find me on Twitter. My handle is @freekmurze. I got a blog freek.dev where I talk about Laravel and PHP development and basically everything that keeps me busy in the web development world. And ohdear, mailcoach and flare are sources that I've created or CO created with my teams. So check check those out if you want to support me a little bit. Before heading into the the talk about Ray itself. I want to say a few words about the open source efforts. That's my company Spatie does. We currently have about 300 packages registered on packages, which is PHPs main code repository. They've been downloaded now for 350 million times, which is quite amazing if you know that our team only consists of nine people. And currently, our open source packages are being downloaded for about 18 million times a month. So people seem to really like it. And that gives us a lot of joy as well. If you want to know more about our open source efforts, just go to our company webpage and go to the Open Source page. If you use PHP or Laravel, I'm sure we have something that could be of use in your next project. Now, those packages, they are not entirely free, there's a special licence on them. And that licence is called postcardware, which means if one of our packages makes it into your production environment, you are required to send us a postcard. And so every day, we get a couple of postcards from the whole world. And yeah, this is one of the things that keeps us motivated, getting those beautiful postcards. And we also take a picture of those postcards, and we put them on our virtual postcard role, so you can enjoy them as well. And you'll find that base, also on our company website. Now, if you want to support us, we also have paid products next to all the open source products, just go to the Products page to see what we have on offer.
How to debug your PHP code
Okay, with that out of the way, let's talk a little bit about debugging. So debugging in PHP, what are your options? Well, there are two main options, you can either do what is commonly called dump and die debugging, and this involves functions like dump and die or info or print r, or var dump, to quickly put stuff on your console on your screen. And on the other hand, we have x debug, which is like the big daddy, in debugging PHP, it's a step debugger, meaning you can freeze the code, you can see the contents of the entire memory. So it's really powerful stuff you have there. Now, the author of XDebug, he tweeted this in 2020. PHP developers that don't use XDebug for the for debugging are amateurs. Now, this is kind of a harsh statement to make. I think. Derek is probably also a little bit biassed, since he's the author of X debug. And yeah, I want to I want to stress that even though it's a little bit of a harsh statement, I know that probably the probably Derek didn't meant it. That harsh. He also tweeted, learning to use the debug should be the first thing when starting with a new language. I kind of agree with that. But I think just saying if you don't use xDebug, then you're not a good developer. That's, I don't agree with that.
Pros and cons of XDebug
So let's compare XDebug and the other ones a little bit. So XDebug. I don't really want to say anything bad about it. Because when it works, it's really golden. And it's really an amazing tool that Derek has created. And it's useful for a lot of debugging scenarios. So you exhibits allows you to see the entire application at one point in time. So you can just stop the code. And you guess you can specify on which line of code it should stop, and then you can see all of the contents of the variables. You can also step ahead, you can set conditions to where the next the next breakpoint should be. It's amazing. But there's one thing that isn't that amazing. Sometimes it is very hard to instal I jokingly say that if to instal exhibit, you either need one minute or one day, sometimes it just works and sometimes it doesn't. Now in the latest version of things, Xdebug a lot of improvements were made for that. But still, if you're not like on the happy path of installing Xdebug, you might get a little bit frustrated.
Pros and cons of "dump and die" debugging
Now let's compare that with dump debugging. So the good things about dump debugging, it is very easy to do. You won't have any installed problems as these functions var_dump, print_r, dump. They're just simple PHP functions. And they just work all the time, everywhere you don't have any problems with with installing dos. And what I really like about dump debugging is that they allow you to see the state of your application from multiple points in time. What do I mean with that? So in your application, imagine that you're debugging, like some sort of CLI commands or something. And that CLI command has loops and functions going on and all sorts of classes, then you can put dump statements inside of loop or inside of one of the functions you're interested in, run your program, and you can see all of the output that you want it in one go. So you can see like the entire flow very easily on your screen. And that's like a hidden feature of dump and die debugging, to me that you can really see your applications easily from multiple points in time. Now, there are a couple of bad things with the burden, yes, well, imagine that you're creating like a web page. And want to debug stuff. If you put var_dump somewhere, then that's far them will probably output somewhere where you don't expect it. And the entire of your entire of your HTML page will will break. also imagine that you're debugging some kind of demon kind of thing, or maybe maybe just a CLI command, let's keep it simple. You have like a couple of debug statements in there. And then you run the CLI a couple of times the CLI commands a couple of times, then it can be a little bit confusing as if the output came from the latest iteration of your command or the one before that, it can be a little bit confusing when you have a lot of output. In there are also some dangerous things that can happen if you use them. Die debugging, it can be a little bit hard to track down your debug statements. What do I mean with that? If you put some debug statements in your code, maybe you're working with a couple of files, and you put like, dump statements here and there. Sometimes it's a little bit hard. When you've done debugging to track those statements down a bit like where is this coming from? Sometimes you've put maybe some debugging statements in the vendor folder, even, you can just can't find it anymore. If you put a dump statement in your, your own code, and you forget to remove it and you've committed, then there might be a chance that you push it to production. And of course, you don't want to do that. Certainly not where you're like outputting, like a user object where maybe, maybe the password isn't there. And certainly you're exposing sensitive information. So there's a little bit of a danger with using dump and die debugging.
Benefits of using Ray
So there are two options. Dump and die debugging or XDebug. And I thought, or me my team thought, like, Wouldn't it be nice if there were something like in between those two, like I want to have like the good parts of dump and die debugging with without the bad parts. And we've made that and we've called that Ray. And our tagline is, or original tagline was dump debugging evolved. So Ray gives you the good parts of dump debugging. Ray itself is a beautiful little desktop application. And it's also a PHP package. And we also have packages in other languages as well. And all of those packages, they expose a Ray function. And with a Ray function that you can use that instead of have the dump function or the print r or var_dump. And that Ray function is much more powerful in formatting the debug information that you need. So and it's also not only for sending strings to Ray, but it also allows you to see the queries performed by your application. The mailable if you use Laravel, we can even pass your code and it can do a much more. It's a paid piece of software, but we do have a free trial. And I also have a little surprise at the end of the of this talk, but I'm not going to spoil that So just yet.
How to use Ray to debug PHP code
So I've talked a lot about this, let's just see it, see it in action. So let me go to my demo application here. And this is the application that I use to test Ray itself. It's a Laravel application, and it has a lot of commands that each test a different aspect of Ray. Now, don't worry, we're not going to go through this all, I'm just going to pick a couple of them. So I'm just going to type Ray here, and just do all kinds of stuff with that. And I'm just going to do this in this command. But you should imagine that you're using Ray to debug something that you put it in different files, and not just in a simple command here. Okay, let's see it in action. So res desktop application. So let me start this up. This is, this is how it looks like. You can see that by default, it is always visible even over different windows, you can easily just always get it. And there's also a shortcut to show and hide it from anywhere so that you can just call it no matter in which IDE you are in. So let's send something to Ray. So Ray. Hi, everybody. And let's execute this command and see what happens. And of course, you can see that we have hi everybody here in inrae. Let's maybe do something else here. Something else. some thing else. And let's also do that, as you can see that we just get those items also in Ray. Now if I jump to another file here, you can use this little link underneath each item to just quickly go back to where you've added that to Ray. So what you can also do is this is just simple strings. But of course, you can also do erase, if you want. Let's demo this, they have like little array, or maybe entire objects, even in their larval the app object is one of the largest objects, let's send that to Ray. And here you can see, let me make it a little bit bigger. That we get this object here. And we can even open and close stuff to see more information about the properties of that little object that we that we sent here. Let's remove this. And now you can see that we already have quite some output in our little console in our little Ray application here. There is a button here that you can use to get a new screen. And now it's now it's back empty with this arrow function, you can go back to the to the previous to the previous outputs. But you can also do that programmatically. So let me add some more things here.
You can say to Ray, Hey Ray, just clear the screen. From here on or new screen there, there's an alley as well. And if I do it now, then I only see the output of this invocation of the command. That's that's how that that works. What you can also do is add certain colours. Now imagine that you have like a lot of debugging info, a lot of debugging information going on, let's just add some stuff. And maybe this is the important one, you want to see this one this is a special one there, you can give it a certain colour. So you can just add red on here. And then that one will be coloured red. This is the important one. And with these colour filters, you can just filter out the colours that you like. And yeah, we have every colour over the rainbow you can make it red, green, blue. We also have sizes so you can make this one a little bit larger. And you can even add like a label to something maybe this one. This let's just get let's demo this. Let's see what happens. So this one got the label this this one is a little bit bigger. And here we have the colours. So yeah, that is the basic operation of Ray. Let's see what else would I want to show up? Yeah, magic also, boy It's pointed out, before we started the stream, that I use a light theme everywhere like using like you see, I really like white based themes. For me, readability is very good of this. But I know that a lot of programmers really like dark themes. So let me open up the preferences of operate. And you can see that we have in our UI section, you can just add dark mode, and you can see that we have a beautiful dark mode in here. We also have thought of people that are a little bit colorblind. We have a Colorblind Mode, and what happens then, then we give names to all the cars, so colorblind, people can still use this, this as well. Okay, but I'm not colorblind. So I'm going to disable that. And I really like light theme. So let's do it back to the light. Okay, um, let's start using the more advanced features of rate, or and I forgot to mention something, this Ray function, how do you get it in your project? Well, it's very simple. If you use PHP, you probably know composer, it can just require a spotty Ray, and they will get that Ray function. If you use Laravel, you can use Laravel Ray, there are a lot of Laravel specific things in there. And I think we all I know for certain, we also have WordPress Ray and a couple of other PHP specific project packages. They're all mentioned in the docs. I'll show you that later. Okay, but I have Laravel right here. So I'm going to do some Laravel specific things. So I'm going to showcase this command a little bit. And let me put this in comments for now. So what rate that's out of the box is when something is locked, to, to the lock and unlock value, do that with lock info, or lock function, then that lock will also end up in Ray because we think that if you lock something that that is probably something that will help you debug as well. So let me execute this command. So you can see that we get that in Ray as well. And we also took care that even though you don't
use the Ray function, we still which some reflection know where you called lock, so we can point to that. So if we are in another file, and I click here, then I go where this was locked. Now in the Laravel application, if you send a mail, the mails are written to the lock as well. And let's see what happens when I sent a mail in this Laravel application. So let's run this again. And you can see that instead of rendering a simple string, we just render out the entire mail and the information about it. And this just happens when Yeah, you just sent a mail in your Laravel application, there's no configuration required. These buttons in males, the links, they all work, I think there's a link here to our company website, yet spicy Bay, is loading there. And this is very handy for like this thing, email flows, like maybe a password confirmation or something. If I were to have like a larval application with a password confirmation that I can, then I can just use a browser to request a mail with the password, reset link. And then in re I just can see the email and can click link. So it makes it very easy to debug email scenarios. Okay, let's do something else here. Maybe palm the queries, they are also very, very handy. So weigh in when you use it in Laravel. And a couple of other frameworks. We also can do this in WordPress, it can show you every query that was executed, how you can do this. Well, we start like we we clear the screen here for demo purposes. It's empty now. And then we are going to tell to re Hey, start showing our queries from now on. Then I'm just going to call some code that that performs some queries. Then I'm going to say to Ray Hey, stop showing the queries. I don't want to see these ones again. So this makes it very hard. Need to if you have a like a piece of code where you want to see all the queries from to do that. So let's, let's try that. So I'm going to execute this command. And here you can see that we see those queries in Ray before meta them a little bit. As a bonus, you get the connection name, and you also get the time it took to, to execute that query. And here, you can also see that we also detect the place where the query was executed. So again, if I'm in another file, and I click this, you're getting tired of this story, then you get back to the query. And yeah, we took some effort to do this, because Laravel itself, since the query deeper down in the framework, you can imagine that this will call some classes that build up the the SQL query, and we'll execute it somewhere in the framework. But we use reflection to see hey, where have you executed? This piece of code. So this makes it very handy to see where things were executed? All right, let me see. Let me show you another cool thing that we can do. Maybe pause the code. This is this is a very cool one. So we can actually stop your code from running. And why could this v be handy? Well, sometimes you want to see maybe the side effects that your application is making, maybe if some kind of loop. And in that loop, you're altering the state of your database, a want to see after each iteration of your loop, what that has done in your database. So what you can do is you can just pause the code in,
in Ray, and inspect your database before continuing on. Or maybe you want to do something with API calls or something, I think pausing is very, very handy. So let's try that. So we are going to get a new screen, and then I'm going to talk them, we're going to call pass, and we're not going to go any further. So you won't see this. Let's see what happens here. So we're going to pass here, you can see that we're pausing. And I have a button here to continue or to stop. So you can see here on my terminal, that I don't get the control back. Because, yeah, we have passed the code we have not ended yet. So let's continue here. And then you can see we're after the boss. So this has been executed. And the script here ended. Let's see what happens when you press stop. If you press stop, we are going to throw in an exception. And here you can also see in, in re let me make this a little bit bigger, that we also render exceptions exceptionally well. So you can see a little bit of a stack trace here. What we can also do is share that exception. So if you want to share this exception with somebody else that can help you with that, you can just click this button. And then you get like a URL where that you can share with others where that exception has all the information about it. And this link should you visited, it works at the time of this recording. This is a publicly shared error. So yeah, that is exception handling in Ray itself. And yeah, I think it is, it is very handy. I use that boss regularly also to debug a lot of things. Okay, let's move on to maybe one or two things and then I'll just continue with the rest of the presentation. Maybe measuring things that is also a good one. Let me clear the screen make this a little bit smaller. So imagine that you want to see how much time a little piece of code takes to run. I think we've all done this at some point like, like, if you want to measure something then you want to then you're probably are going to store like the time in a variable then you're going to do stuff then you're going Going to get the current time again, you're going to subtract the original time from that, and then you have the time that the court needs to execute. I've done that 100 times. But I'm not doing any more now because they can do that now, for me. So what are we going to do in this demo, we are going to create a new screen. And then we are going to call measure on Ray, and then we're going to start measuring performance. And I'm going to do this way. For now. Then we're going to sleep and then we're going to call measure, again, let's see what happens in Ray when we do that. So let's measure the stuff start measuring performance. We waited one seconds. And here you can see that yeah, we took a little bit over a second because there's a little bit of an overhead. This how much memory we used. And yeah, this I'm going to explain in a bit. But you can see that we easily have measured like that one second of time that we needed here. And I want to point your attention to a beautiful little design detail that my colleague Willem this. So when you start measuring performance, the little label that we have here has like dotted lines at the bottom, because we're going to start and if you stop measuring performance, those dotted lines are on the top, which is I think, a very nice detail. Now let me add these things again. And let's see what happens here. So now we have three measure goals. And you can see that the first little bit is like the total time that we needed to end for the first. For the first leap, we are at one second, but here with the third call, so this outputs, then we slept in total three times. And since the last call two times. So you can use measure for multiple points in time as well.
Okay, let me show you one more cool trick that we can do. But yeah, like, like I've said, we can do a lot here. But yeah, you should probably go to the to our documentation to discover it all, whenever I find a thing that I want to work. And I think it can be easier, I add stuff to great. Now there's one big feature that I haven't talked about yet. So all of these tests here that I did with Ray are done locally. But remember what I said about die in dem debugging that if you leave like a dump, call in a push that to production, then suddenly you might be exposing some information about your application. Well, Ray doesn't have that problem at all. Because if you push ray to production, and Ray detects that, hey, there's nothing listening to me here, then the Ray function won't do anything. But what Ray can also do the desktop application is create an SSH tunnel to your to your server. So you can see race data from production. And I'm going to simulate this with a little script that I've put on my own server. So I'm going to SSH to my own server here. And I've got a little folder here called Ray. And if I take look at the index of PHP here, then you can see that I have a Ray call here. So if I execute this in the index dot php, yeah. Oh, PHP, how do I execute PHP with PHP, of course, like that, nothing, nothing happens. But there's like a little button here. And this is the Server button. And here I can connect via SSH to service. And let's execute the script again. And you can see that we have a ray call coming from, from the fake dot dev server. So we can use ray to fix like little things in production as well. No need to sneakily change something on your server, without going to Yeah, just directly on your server. No, you can just push something to Ray and and see it there. And let me prove that this isn't some kind of trick. Let's maybe edit this and let's add the red colour here. And let's execute that again. You can see that now have the red colour here. So yeah, that's also a nice thing that that ray can do. Um, alright, let me show you something else. Because you're probably thinking, yeah, Ray all good and all that I'm working in a project that doesn't have like F like a, I doesn't have like composer available. And this might sound very strange, like, how can you have like a PHP project where composer isn't used? Well, in a default WordPress installation, you won't find anything composer related there. And we got a few questions from the WordPress community about that. And we, we solve that. So let's open up another programme, which is called coach runner. And this is a programme that I sometimes used to run little snippets of PHP or other languages. And I'm just going to use the Ray function here. So Ray Hi there. And let's execute this. And let's see what happens. And you can see that, yeah, we can't call Ray because yet that function isn't defined that isn't in my project. Imagine that this was a WordPress project. Yeah, you can't just make up the Ray function. Well, there's something that we programmed, and it's called global Ray. Let me show you that. I've disabled it, but I'm going to enable it again. So I'm going to instal global Ray again.
And let's now execute this piece of code. Again, an Ray isn't open. So let me open it up, you can see that we are, we are actually using the Ray function, even though we didn't define it here before. This is quite, quite magical. I can, I can assume. But this allows you to use Ray literally, in every php file on your system. Even small files, like like this one that don't include a vendor directory at all. Now, I'll spoil how we do this. If you want to see the code of this on Spatie.be the global Ray repository here. It's something called global Ray. And what this does is it will add something to your PHP dot ini file. Maybe I can just show it to you. So if I go to my PHP dot ini file, and oh, I did something wrong the next time. Let's just do anyway. Think prefix? Where is it? The figs prefix used I thought it was prefix, my soul wrong now.
Up be open the version of the INI file before the moment you installed the government.
Yes, I will. So first of all, I'm also a user. Because, as you mentioned at the beginning, the problem with the bug is that it sometimes just doesn't instal. Especially because I'm a Windows user. So it was always so random. And using Ray was very surprising that it just worked out of the box without any problem. So
everything should work really. Yeah, really. But when
you compare it with xdebug this was, for me at least the biggest difference because I could spend like hours trying to make xdebug work. And I could debug code using Ray. So, so far, for me, it was always a great solution. I use it most with PHP and with twig templates. So because there is also a solution plugin for for this WordPress implementation of twig. Timber. So it's also available, it works really great. But I have one question regarding because as you mentioned, is the bug is very powerful, because it is. And rate is somewhere in between this. I read this nice term, it was called var dump and die driven development. and xdebug but where do you think that Ray falls short comparing xdebug. what it can't do an xdebug can?
Well what what extra work really is very good and is showing really the entire state of your application. If you want to see like wait, let me tell it another way. With Ray you have to think about beforehand which things do you want to send to Ray with xdebug, you can just see the contents of everything. You don't have to make a decision before it you can just hover over variable here is the content of that variable. And yeah, that's something that that vary, we'll we'll, we'll probably never do. Because yeah, it's just isn't impossible for me to do something like that. And of course, like, setting breakpoints and the nice IDE integration that x debug has, that's something that ray will probably never do. Because Ray's a little bit of a pragmatic kind of, kind of tool. So yeah, I think seeing all the variables that you want, that's like a big plus for an extra worker. And I to into to make that a little bit complete, because I don't want to come off as like an easy Buck hater. I use exhibit sometimes as well, but only for like, really involved kind of debugging things. But for I think, most day to day, the burden of, of smallish and even medium kind of things. I use very myself, as well. So I think they both have their place.
I understand. Yeah. Because this was something that, that interested me, how do you see, we also have one question from the audience. How we can use rate inside a Docker container or on hosted AWS server?
Well, you can do that. I must say that I'm not a big Docker user, but a lot of Ray users are. And they helped to write the Docker documentation for Ray. So in the documentation of Ray, you find how you can configure it. It's mostly like most things with Docker, I guess, for why for for warding the right ports to Ray. Maybe I can also mention that, yeah, how does Raywork in itself, in Ray in the Rayapplication, we just have a simple HTTP server that is listening. So everything that is sent to Ray is fear sent via the HTTP protocol. So if you just configure your Docker ports, just right, you can just use it in your Docker containers as well.
And with AWS server, it will it will be just a typical remote. Remote Server, right? Yeah. Okay, yeah. So so these are all the questions. At the beginning, we also want a small poll on YouTube. And we ask, is using die and Verdammt? Your preferred the bugging method? And the good news is that most people said no. 16% said no. So there are still 38%. That should try using, for example, right? Because it's really simple. And it's much easier to use rather, die. And that's all all those other commands. Oh, and we get one more interesting command here from from has, I only is the back for quite old Legacy product with modern code bases, I find Ray is usually enough.
Nice. I can I can agree with that. I luckily don't have to work on all code bases, too, too much. So I'm lucky to mostly work in modern Laravel projects. And I also use Yeah, Ray most of the time.
So thank you, thank you very much for for explaining us. What, what really is and for this really beautiful coupon code because that's, I mean, you won't get re any cheaper than that. Let's let's be honest.
I don't think so. Yeah, I'm not I'm not going to pay people to use Ray. So zero is really my limit. Like
yeah, I mean, at this point is it's the price of Xdebug so yeah, yeah, so
yeah, and I'm pretty sure that if you decide to buy it, it'll pay for itself. You know, I think our normal price is now I think around 40-50 Euros. We have PPP pricing. So in every country, it's a little bit different. But even if it if it's already saves you like a half an hour of debugging, you already got got a price out of it. So I think it's that cheap. I'm a little bit biassed, of course, but I think this about most development tools I happily pay for for tools that make me a little bit faster. And if that little bit faster is just an hour, yeah, then it's already worth a lot, I think.
Yeah, that's true. I mean, the bugging can take a lot of time and having all those variables put in one place. That especially this pausing and resuming, especially in the loops, as you mentioned, this is this a huge, huge time saver. So so thank you. Thank you so much, because, like I said, it's a huge helper. So like I said, Thank you so much. And I want to share some more things. So first of all, if you want to be if you want to know what is happening with when it comes to our webinars, don't forget to sign up to our meetup comm group called Buddy CI/CD group, we are informing every time about the new webinar that is upcoming. Also, like I said before, subscribe to our YouTube channel. Of course, you also can follow us on Twitter, Facebook, and LinkedIn. But if you want to be informed about the new webinars, I think that YouTube is also a great place to do so. We will announce next webinar soon, so, so hang tight and follow us on those social medias. Because it's also going to be something in something very interesting. So Freek, thank you once again. It was really a pleasure having you here. And thank you to everyone who was listening and watching us. Thank you all and see you soon. Bye.