 Alright, so the talks about, called Big Spice and Box, I was doing binary programming in JavaScript. And my intention behind the talk is essentially to promote this idea that we don't deal with binary. So, you know, pretty much all of computer science is essentially abstraction, right? We look at a ball and we say, you know what, it isn't really a ball, it's a wheel. And we just start calling it wheel for the entire step, right? So, everybody else on top thinks it's a wheel, but really it's a ball, right? So, this is kind of fundamental behind software in general and a lot of technology. It is the same fundamental about, behind binary, it's called one signal, one and we call the other signal zero. And then after that, we call this abstraction, we stick with this abstraction and all the software layers on top, just think that they're getting a one and a zero, right? I recently saw an example of a TED talk where somebody was transferring. It's kind of the same principle that you have, you know, the light spectrum and you have two frequencies of light. You send one frequency and the other guy thinks this is zero. You send another frequency and the other guy thinks it's one, right? So, that's kind of the fundamental. But once we have this abstraction in place, what we do is we build other abstraction layers on top. So, the moment we have one and zero in place, we build these software things for data types. And in all our programming languages, we just deal with data types. But what if for a minute, in just a minute, we move below our data types and we start looking at data back in the ones in the most forms? Can we get some advantages from it? So, you know, why think in binary, right? We have a perfectly good abstraction of data types, right? We can think in integers, we can think in strings, we can think in arrays. But why think in binary? Thinking in binary helps because whoever designed the language didn't know your use case, right? So, when you have certain specific cases, it can help thinking in binary. You could get, you know, better data transfer. You could send less data over the network. You could get faster processing of the data. You could do things quickly just because you know what the binary information looks like. And if you didn't, you would spend more time doing it, right? So, that's kind of the basic of why you want to do it. You also might want to do it, you know, to comply with existing standards. You want to implement a client to an existing protocol that is binary, you know, right? And you need to deal with that information. So, these kind of things take you to this level of thinking in binary. And I personally think that we don't do this enough, especially in the web application world. We're stuck with our data types. And even if we're thinking in a different data type, we think in text-based data types. It's a way to bulky and we could think of them differently and we'll get into that in a little bit. So, this is basic math again. I'm going to talk a little bit about the basics because I know that at least I didn't remember my college binary mathematics class. So, I'm going to revise it as quickly as possible in the room so that everybody has those basics afresh so that we can discuss the other stuff, right? But to really understand binary numbers, you need to understand decimal numbers. And we all know decimal numbers really well, right? We've dealt with decimal numbers since forever, since we started learning mathematics. So, basically, decimal numbers have 10 digits, right? And because they have 10 digits, they're called base 10 numbers. So, let's take this number, for example, you know, which is kind of assumed to be the answer to everything. So, we have 42 in decimal, right? We could write 42 in decimal as 2 into 10 to the power 0, right? Which is 1, 2, 4 into 10 to the power 1, which is 14, right? So, this is how we get 40 plus 2 and we get 42. And this is a very generic formula. It works for every decimal number which is essentially that, you know, you take the digit. So, whatever 0 to 9 digits that you have, you take the digit. You multiply it by the number of digits, which is the base, right? In decimal, we have 10 digits, so 10. And the position. So, you start measuring the position from here. This is 0 to 10, this is 1st position, 2nd position, so forth, so forth. You can have an infinitely long number like that. So, if you start thinking about this formula, right? You could, you know, extend it and you could say, okay, this is the 0 to 10, 1st position, 2nd position. As a 2nd position, this becomes, you know, 8 into 10 to the power 2, which gives me 800. So, I can get 842, which is the number by looking at the data like this. And what is the advantage of looking at the data like this? Is because, you know, this will help us thinking of other number systems. So, that's why we, you know, we kind of got the basic. This is the important formula. The digit, the number of digits. So, a particular digit at that position, the number of digits and the position. So, you raise to the power and you get, you know, you can calculate whatever number value. So, binary numbers are kind of similar. They have, instead of 10 digits, they have 2 digits, right? So, because they have 2 digits, they're called base, 2 numbers, right? And a binary digit has either 0 or 1 and it's called a bit. So, it's kind of the same thing. So, now let's say I have this binary number, right? I have 1 and a 0 in binary. So, how will I understand this number? You know, I'll go back to my same formula, which is, okay. So, what is the digit at this location? 0. What is the base? 2, right? And what is the position? 0. In this case. In this case, right? So, if I expand this, it will look something like this, right? You know, 0 is the digit to the base and 0 is the position. Then, to the base, 1 is the position and 1 is the digit, right? So, I could then calculate that, okay, this is 2 plus 0. Which is essentially 2. I could extend this with any number of digits, right? And it doesn't have to... An important thing to remember when you start dealing with binary data, this isn't limited by bytes. It can go on till whatever number of binary numbers, right? The formula still will continue implying. You don't have to think in bytes. You can think in bigger numbers. And that's important to remember. So, we have a binary digit. But we have slightly better ways of thinking of it. You know, slightly higher level abstractions if you will. So, we had binary digits to record bits. We clubbed 4 of them together and started thinking of them as nipples. Generally, we don't use these nipples a lot, but they're important in one place, and I will get to that in a little bit. But basically, what's important to know is you can store 0 to 15 in a nipple, right? And if you know hexadecimal numbers, 0 to 15 should mean something to you. So, a byte is 2 nipples, but 8 bits. And it can store 0 to 255 values. The same formulas apply, you know, if we have bit values filled in, we can apply the same formula to calculate the value. So, similarly, you know, just like we had base 10 numbers, we had base 2 numbers, similarly, we had base 16 numbers. And base 16 numbers have 16 digits. 0 through F, and that's why they're called base 16. But what's really interesting about hexadecimal numbers is that hex digits fit exactly into a binary nipple. And this is important, right? So, 4 bits can be represented by a hex digit. This is important because when you start writing 1s and 0s, right, lots of them, it just becomes hard to read. So, you want a way to compress and read efficiently. And hex is a nice way to read this stuff. So, because I can take... So, let me explain that, right? So, let's say I add this 1 nipple, 1, 1, 1, 1, 1, right? The value of this is 15. 15 and hex is 8. So, I've got to write this nipple as 8, right? And that's kind of key because now I can write a, a, and that will tell me that it is 15 followed by, you know, 1, 1, 1, followed by 1, 1, 1. And that makes binary information readable the moment you start writing in hex. It is so useful that we have a hexadecimal notation in JavaScript, right? A way to write numbers in hex. That's because we don't have a binary notation, sadly. There should be, some languages do. But we have a hexadecimal notation, right? And it, it makes things easy. Sorry? What did I do? Oh, sorry. Yeah, I'm sorry. My mistake. F and F. So, byte order. People are listening. So, another important concept to understand is byte order, right? So, what we've done so far is we've taken we've created the first level of abstraction we extracted a signal out to 1 and 0, right? Two different signals into 1 and 0. The next level of abstraction we created was, you know what, let's take a bunch of these signals together and call them a nibble first, then take eight of them together and call them a byte, right? But once you have bytes, an issue arises, you know? Which is, you know, so I have to form this binary number, right? We have to start from 0 and go up, but in what direction? And that direction is where byte order starts to play, play a role, but not at the bit level. We don't bother too much about the bit level. We do deal with it at the hardware level. But in JavaScript, you know, this is what is important to understand. So, think of it like this, okay? Let's imagine there's a network pipe here, right? So, if there's a network pipe here, the first byte that comes is called B0, the second byte that comes is called B1, the third byte that comes is called B2, the fourth byte that comes is called BZ, right? So, this is what I call network byte order, you know? But you have to imagine your pipe on the left and remember that your pipe is always on the left. So, if stuff is coming over the network, this is the order. And this is also about digging in, which I know is a very cryptic name that doesn't really convey much. Network byte order is nice. But basically what I'm saying is that the least significant value of a number is at the same, the most significant value is at the same. And so, let's say if I were trying to write, you know, one, the decimal number, I would write one here because it's the least significant position, right? It means that one would mean one. If I would write one at the most significant position, one would start meaning a bigger number. And I don't want that. I want to send one. So, I would write it here, right? In little Indian, it's the reverse. So, if your data is coming from here, you assume the reverse order. And why are we doing this? See, byte orders are important when you're thinking in a next level, higher binary numbers, which is, you know, words. So, I want to combine bytes together and I want to think in words. And in words, I can either store the bytes like this, the way they came from the pipe, or I can store them like this, where, you know, I do this. And this is important because hardware architecture is kind of wary underneath. You know, I would do the opposite. If I wanted to store one, decimal one, in a little Indian notation, I would store one here. So, it just seems wrong, right? It seems like, you know, bigger, bigger values should be on this side, at least in our traditional decimal stuff, bigger values are always on this side. So, all right, so that was kind of the basics, right? I wanted to cover the number system because... So... But numbers in JavaScript... All right, so numbers in JavaScript are this... follow this particular standard called IEEE 7-4 double precision floating point, blah, blah, blah. The basic important thing to note is let's store in 64 bytes, sorry, 64 bits, which is 8 bytes. But it's not stored in our number system that I just saw, right? It's stored in a slightly complicated format. The point of this slide here was that we will deal with JavaScript numbers a lot, but we will not deal with them in this form because they get converted the moment we start dealing with them. So the moment you start using binary operations in JavaScript, most binary operations will just convert this number into something else. And we'll look at what that's something else in a little bit. So binary operators, especially when you're dealing at the bit level, are called bitwise operators in JavaScript. And what's important to note about... this has to do with that numbers in JavaScript thing, if you have a bitwise operator, the value that is sent to that bitwise operator, the operand, the entity that the operator is acting on, is always converted into a signed 32-bit integer, which is stored in BigIndium. This is important to us. And this ignores those complement. Those complement basically means that the signed bit is always on the left side. So you have this one location for plus and minus. But essentially what we need to know is it's 32-bit, which is 4 bytes, and it's BigIndium. So it looks like what we were drawing a little while ago. So now let's look at the basic operators that are available. So we have a bitwise AND. The AND basically says you have two numbers, number one and number two are bits. So these are 32-bit integers, like stuff is in JavaScript. They're 32-bit values. But when you're doing an AND, places where both of them have one become one, everything else becomes zero. And this is a simple bitwise AND operator and should be easy enough to understand. And this OR basically says that if one of them is one, the stuff becomes one, right? The answer becomes one. So if one of the bits is one, the answer becomes one. Exor, a lot of people aren't generally... It's a very useful operator. But basically what it says is Exclusive Org. Only one should be ON. If we are comparing bits, you start from here. See, in this, this number also has one, this number also has one and one. This one only has one and one. So these are exclusively one and only one of the numbers become one. It's hard to explain, sorry. NOT is basically just reverse the bits. So you have zero, put one, you have one, you put zero. Shifts are important to understand. Shifts are important. Shifts are very simple, though. All they're doing is, you know, if you have this number, when I say, so all you want to do is you want to move all the bits this side and insert two here, right? So move all the bits to the left and insert two empty zeros there. Um... It was right... Sign propagating right shift is, you know, the opposite of this is this thing where what happens is here it looks the same, right? What I did was instead of moving in this direction I moved in the right direction, right? These two bits fell off, right? Um... But there's something unexpected happening here which is clearer from a signed example. So nine was an unsigned value. It didn't make a lot of difference. It was minus nine, right? Um... It makes a difference. Makes a difference because when I shift the empty spaces don't get filled with zeros. They get filled with ones. And this is very important. This is very important. If you want them to be filled with zero, you use a different operator with just three arrows. And in that case this will get filled with zero, right? But this is important to understand. So... All right, so... So far what we did was we understood, you know, how binary numbers... To deal with binary numbers. Um... The next thing to think about is how do I organize? So far I've only looked at integers and we've looked at integers also very briefly. So the way you store... The only way we have to store binary reasonably stored binary information so that we can operate on it is the number data type in JavaScript. Okay? But the number data type, um... As we looked at before, has this weird 64-bit format that we don't really care about. But when we need to work on it, it gets converted to a 32-bit format. Right? So once we have these... So let's start thinking of numbers as 32-bit signed integers. And let's just, for a minute, assume even though in JavaScript, you have floating point numbers and you have, you know, longer numbers. Um... But let's for a minute just assume that the numbers available to us for the purpose of binary data are 32-bit signed numbers. Right? And then once you have this unit, um... a 32-bit signed big Indian-ordered number, which is basically saying that there are four bytes in the big Indian order in that number. We can say, you know what? This is not number. I will treat it as something else. I will treat it as my own way of creating new data formats. And this is where encoding starts to come. So most of the time... And what is text? Right? It is in the end in computer science, everything is numbers. Right? And in... if you keep going lower, everything is bits. Right? So it's all bits. Uh... Text is also bits. Right? The only thing is it is in a certain format which says number 65 is 8. Right? So there's a table which says, you know, this number is this character, this number is this character, this number is this character. And a byte can have 0 to 255 uh... numbers in it. So you assign a number to each of these um... values. And you... So you assign a character to each of these values and you can create a text format. Right? This is our old UTF 8 format. Uh... The newer ones have expansion capability and they can deal with two bytes at a time because they need more space. And we can have more characters. Uh... But this is what text formats are. But text formats have a problem. Okay? The problem is if I write the number... If I write the number 10 in text. Right? Uh... Number 10 in text right? Needs one byte to store one. And it needs another byte to store zero. Why? Because one is actually uh... 49 I think. I'm not mistaken. 40? One, huh? Okay. So one in Unicode is uh... 41. Zero in Unicode is, you know, some other number. And I need two bytes to store uh... 10. But we just saw that I can store 0 to 255 in one byte. Right? So there's a problem here. Because I now suddenly need two bytes. Actually I need more strings also store length. So I end up storing like four or five bytes to send 10. Right? I need to send 10 to my server. And instead of sending uh... one byte, which is where 10 can fit in, I send four or five bytes. And this is the problem, right? And this is why you need to look at data at the binary level. Another good example would be that, you know, um... I'll actually get to that example a little bit. But basically text is heavy, right? So JSON is text, which is most commonly used by us. XML is even heavier text because it has its own metadata and text, a lot of it. Um... So text formats are bulky. And we need something else. And... and all I'm doing... I mean, the reason I'm giving this talk is to promote the idea that go look at something else. And there are a lot of options, and I will introduce them a little bit in a little while. Um... And these things we generally tend to call them binary formats. But even text is binary. But, you know, in common language, you tend to call them binary formats. Um... Binary formats are basically a set of rules which define data types. Right? So what they essentially say is, if I have an integer, store it like this. Right? If I have a float, store it like this. And typically these formats will look like, okay, you know, um... In case of an integer, put a tag which presents it. So... Um... I have to take this example. Good example. Okay, so... You're trying... So you're getting a stream of bytes on the network. Okay? The length of a byte stream is unknown, let's say. So you don't know how many bytes are going to come. You just... You're getting bytes. So how do I... start reading data from the bytes? Um... And there are several ways. One is... you and I... So you're sending me some data in a byte binary stream. And you and I pre-agree that you know what? The first four bytes that you send me are the length. And then... followed by that length. So the first four... So first four bytes that you send me, one, two, three, and four are length. Right? And followed by that is length bytes of data. Which I will use as a stream. So this will be definition of a string data type. And this is my own custom format. Some format might have this, some other format might not have this. But essentially what I do is send length first and then send length bytes of data. And that is what basically all binary formats do. They send in some information about the length. They may send in a tag here which says, okay, you know what? What is coming is a string. So there might be a number assigned to string. Let's say two... Anything that starts with a two is a string. Anything that starts with a one is an integer. Anything that starts with a one is an integer. Now I could do two things. I could store the length of an integer here like I did with string and then store the integer. So I'd need four bytes to store length and then I need to store the integer. This will make my integer value nine bytes long. That's not very cool. Integers can be stored in 32 bytes or four bytes. So what's going on here? If you and I both agree that integers are always 32 bytes, then we don't need to send this length. And this is what a lot of formats also do is that they have three grids that you know what? Whenever I want to send you an integer, I will send you one and I followed that integer. I will not send you length because we both know integers are always four bytes. So this is what typical binary format should look like. Sorry. So padding could be one of the rules. One of the rules could be okay, you know what? If an integer is only one byte, but what you and I have agreed is that integers are always four bytes. Then I will pad and put zero in the rest of the bytes because I don't want to confuse you. So padding could be one of the rules. But data formats essentially are just these set of rules that define what common data type should look like in a binary form. And I've talked about fixed width and variable width data types. What's interesting and what is relevant to JavaScript? This stuff, everything we've talked so far is mostly common in most languages. What's relevant to JavaScript is how do you store this binary information. And, well, JavaScript traditionally isn't pretty bad. It's been pretty bad because there is no binary data type. There is no binary data type, meaning there is no easy data type to work with binary data. So what you typically do is you stuff the data into a string and then you use these two functions. You know, care code at some location or you use strong care code to create the string. And that's it. It sucks, it's really slow but that's all we have even today in all browsers. It works in all browsers. So if you have to build something that works in binary data in all browsers, string is still probably your best bet. And also, even if I get to the next slide, the next slide will give a different alternative. The problem is that different alternative first needs to use this. Why? Because your data and a web application is coming over HTTP. And when it comes over HTTP, the response that you get from most browsers is text. At least it used to be that's changed now and we'll discuss that. But it used to be just text. So because it is just text, and let's say your server sent you some binary information in text, you need to read that using this care code app. After you've done that, you could copy it into an array of numbers. So you could, instead of using strings all the time, you could use an array of numbers because essentially what is binary information? An array of numbers, right? But you could do two different things. You could store only 0 to 2. So let's say I have a number. There is a, a, so 0x, a, a, b, b. That is my number. And this number I want to send over the wire. So I send this data over the wire in some format. So this value is less than 32 bits. It can fit into one integer. Right? And when you're leading data into an array of numbers, you could store both of these bytes together in one number. Or you could choose to store only one byte at a time. And you might want to do this if you want the flexibility. Right? So array of numbers could be array of numbers that are always less than 255, less than or equal to 255, or array of numbers that are always less than 32 bit numbers. Right? There's like 4 million something, something, the maximum. So you have an option here and different libraries I've seen depending on the data format I've tried to do different things. But this is all really, you know, strings and arrays of numbers are really old things. They still work in all browsers, but they're really slow. Yeah, so that's what I'm going to get out. They're not heavy because memory-wise they're just the same. They're, they're heavy because I don't have good operations to deal with them. I don't have data type-based indices and I didn't use to have it. I now have them, right? I now have them. So stuff is changing. We have new specifications. The first one is block, which is part of the file API spec if you've read that spec. And the file API spec may define something called a binary large object. A binary large object is this in future version of the browser and already I think in Chrome and latest Firefox you have blob. But in future versions of browsers, the intention is that whenever you're exchanging data that is not of known JavaScript data types, you'll always be sending around a blob, right? So for example today, if you read a file using the file API, the result is a blob, right? But this blob on its own isn't very useful because you can't operate too well on it. You need to do other stuff well. Yes, so now XHR 2, new XHR specification, allows you to send blobs. So you read a file, you get a blob. You just take that blob, put it into an XHR and send it over, right? That's all. So you could do that. But you could do that only in new browsers. Well, HTTP was never streamed. HTTP has this header called content type. And content type allows you to send whatever you feel like. The problem was in browsers, we had no way to send an HTTP packet other than XHR or, you know, your traditional form-based submits. And you couldn't change content type. You could. In an old XHR, you can change the content type. It still doesn't work in most browsers because you have to do, I think in the old XHR, you have to do this override, MIME type, blah, blah thing in Firefox. And in I, you have to do something else. If there are a bunch of hacks that you have to do to pull off a new content type exchange, but HTTP supports it. Yeah, I'll get that. So, I don't stand. You will load into? Is it like the entire problem is actually loaded into the library? The whole file? No, it doesn't work like that. File API, if this blob is coming from file API, it actually can't deal with it. If this blob is in memory, then it's in memory, right? So anyways, if I have, I thought it was 10 minutes. Okay, anyways. So, similarly, you could receive a blob. In XHR 2, you just have to send the response type. And then in our response.response, you'll get the blob. And you can deal with the blob. So how do we deal with the blob? Before we start reading it, we can also build our own. So we don't have to read from a file. We can use this class called blobBuilder and append a bunch of strings to it. And here you can send in a content type. So it has a bunch of supported content types. And then you send it into the blob. At this blob object, you could use in an XHR and send up. Send over the wire, right? But what if? So it is part of the new file API standard. It's, well, you can't really call it standard because it's not in all browsers yet. But yeah, it is part of the proposed file thing standard. It's not in old browsers. So, what if I want to read a blob? So, as such, the blob doesn't really have a lot of operations on it. But it will let you read it, right? So we can use this file leader again part of the file API standard. And you can read it as different things. You can read it as text. And you can read it as a binary string. You can read it as an array buffer. And this array buffer is new. Other stuff is not that interesting. And you'll get that result in this result object. This array buffer is the best thing that's happened for binary data in old browsers for a very long time. So array buffer is your traditional byte array. It's an array of bytes. And typically how you operate on an array buffer is that you create a view. Right? So how did I get an array buffer in the first place? I read, you know, I read a blob as an array buffer. Right? So I could create a blob using blob builder. Then read that blob into an array buffer. Right? So this way I can create binary information. Once I've done that, let's say I want to operate on this array buffer. And the way I operate on it is by creating an array buffer view. So array buffers are just the space in memory. And you don't... that object doesn't give you read-write methods. What gives you read-write methods are these views. And views is typically, you know, just a part. It could be starting from the end, beginning until the end, or it could just be a window in between that you're looking at. Once you've created one type of view that you can create is typed arrays. And typed arrays will give you data type specific arrays. So this is interesting. I think the only way I can explain this is by showing an example. So so here's what I'm doing, right? I create an 8 byte array buffer. Right? 8 byte location that I've gotten in memory. Then I create an 8 32-bit array which so what I'm saying is in those 8 bytes give me an array which is indexed by 32-bit integers. Meaning that when I go to index 1 I will get the first 32 bits of those 8 bytes. When I go to the second index, I will get the next 32 bits. But I could do something different where I could say you and 8. And in this case I would get the first 8 bits not the 32 bits. So here I'll get 32 bits at index 0. Here I'll get 8 bits at index 0. Right? Here I'll get 16 bits at index 0. But you know, sign is kind of important. No, so typed arrays are part of another proposed spec called WebGL. But even browsers that haven't implemented WebGL have started implementing typed arrays because they see the value in it. You don't need you don't need a WebGL context. And because you need to implement a file API which everybody agrees on WebGL nobody, you know people, there's no consensus. But file API everybody agrees on and file API has array buffers which means that you automatically just get all the stuff. Yeah, absolutely. And edited, changed formats all for all. Yes. So the typed arrays right now I'm very fast in most browsers they're almost as I mean they're slightly faster than your traditional array approach. No, if you have a WebGL context then your typed array will get your typed array operations will happen in the GPU. But if you don't have a GPU context which is, you know, if you don't have WebGL then typed arrays running in in your regular CPU. So anyway, so you know what you did this. So, typed arrays are one kind of use remember what I said was you need a view to work with array buffers. Type arrays are one kind of a view that you can create on an array buffer. Data view is another kind of view. And data view gives you your traditional byte array view. It gives you the flexibility. So typed arrays have got a problem. The problem is that they assume that every value will always be 32 bytes or a particular data type, right? Every value will always be 8 bits or every value in that array will always be 32 bits. And that might not be the case if you're dealing with dynamic binary information. So data views, you can use them to, you know, read 8 bits or read 10 bits or 20 bits or whatever. There are built-in functions which lets you read 8 bits, 16 bits and you know, there are a library of these functions will let you read them and also let you set them. So you can use a data view if you need a more flexible approach where your data isn't homogeneous. It doesn't look the same. And this is what you would use if you wanted to create a complex data type. So let's say I wanted to send an object over the wire where, you know, first value in the object is ID and this ID is let's say 1 byte long. The second value is a string. Then let's say this is, you know, 100 bytes. It's a fixed length. And then the third value is some age, right? Of data type number. So now I need to read first a byte. Then I need to read 10 bytes or 100 bytes. Then I need to read 4 bytes. And a data view would give me that flexibility of reading how many bytes I want. So somewhere similar to structures. No. You could create your own but there's nothing that gives you ready-made structures. You could combine the data view API and create a structure like this. But there's nothing that is built into the language. Right? So you could create Okay, then maybe I missed it. That's also possible. But, I mean, right now all I know is that you would use the data view API to create your own custom data formats or structures. Some people also still use, so Canvas has, you know, a way to store images and some people use image data to store that because pixels are also 32-bit values and you can use that information. So this is, people use this. It's getting slower and slower compared to typed arrays. The support is almost just the same. So, you know, this will probably go away. So far we talked about, you know, how do I store data and manipulate binary data in memory? But how do I send it over the network? And this is where, you know, your traditional HTTP question comes in. HTTP has no restriction, right? HTTP will let you send an object stream. HTTP will even let you send a custom header which says, you know, this data is of some other type that I don't know of. For example, you know, Google has created this protocol called protocol buffers. The protocol buffer sends a header which says X protocol Google, X protocol buffers Google. And if that happens, then you can send binary information over HTTP. So HTTP doesn't have that restriction. The restriction was because of the XHR implementation. But people were getting around it using, you know, form data and things like that. So you could do stuff. Even XHR works, but XHR needs a bunch of hacks to pull that off. The new XHR works just fine. You could also have, you know, web sockets. And if you have a web socket, you basically have the ability to send any binary information. Web socket API. Sorry. Well, you need to serialize it according to your lalins. If you have a data view, right, you could just send that data view over. But what we're talking about really is serialization is an abstract term. Serialize from what to what. And if it's you cannot send a blob on a web socket. Yes, you can't do that. You need to read into a data view and then pass the data view over a web socket. So finally, you know, these are the kind of basics I wanted to only cover the basics of, you know, what you can do with binary data. What I would like to urge people is to consider binary information. Consider that you can gain. So for example, I deal with a I'm building an application that sends a lot of numbers from the server to the client. And if I start sending all those numbers in strings, well, it just becomes really, really big, right? For example, if I want to send 4 million, 4 million as a string is going to take me about 9 or 10 bytes. But 4 million as binary information will take me 2 bytes or 3 bytes. It does, but it doesn't really matter. It just doesn't matter. Almost to the order of, you know, 100 times kind of difference. If you format and deal with a data format properly according to your data, right? And that's exactly what I'm trying to say. What I'm saying is if you have data that looks interesting from a binary angle, just consider that option that you would send it as a different data type, not traditional data type. And there are a bunch of, you know, you don't have to cook up your own data type or serialization, deserialization libraries. There are a bunch of them available. There's, you know, there's protocol buffers, there's message pack, a bunch of them. There are really old ones like ASM and stuff also. Sorry. Yeah, just last 5 minutes. So, you know, the bunch of them already available. One of the advantages that you might want to consider of thinking about data in binary numbers is, you know, the fast speed that you get with just bitwise operators. So let's say you want to, you want to multiply, multiply by 8, right? Multiply by your number n and you want to multiply it by 8. This runs slower than n left shift 3. These things are out there is important. Understanding that bitwise operators can help you do fast calculations is important. So I would encourage you to look at bitwise tricks. They're sometimes less readable but, you know, at critical times, they can get you a lot of advantages. Like the data exchange we've already discussed that you can, you know, if you have new data formats, you can improve your network over it. You can also improve your memory over it. Sometimes if you want to store data in memory but you don't want it typed to, you know, JavaScript objects, you could still keep it in binary blobs. You could of course build already existing. So using WebSockets you could build clients to existing protocols. People who are using Node.js are writing interesting protocol libraries. I'm sure when WebSockets become popular we'll have those libraries in the browser suddenly. And of course you can do file manipulation and that was pretty much all I wanted to talk about. But in browsers in browsers well, I think in my example I can take a lot of numbers and I can just reduce the amount of payment transfer that we do by all the street times just by having minus customers. You could do some definition that's in audio which sits like this. You could do file manipulation. You could read changes in the browser for the way that you want it to. And I think you need to talk to many of your companies about that. I think you can. I think earlier we used to have a bunch of guys and they have better tools. Thank you.