Build the future of the web with WebAssembly and more Google I/O 18

Show video

Hello. Everyone is everyone hearing me hey. My. Name is Thomas and I'm the product manager for v8, and webassembly on Chrome this. Is my second, talk ever like this but I'm really thinking it might also end up being my last talk ever if the Google assistant, gets any smarter, than it already is. Right. Now it's making phone calls and I feel like soon it'll end up doing all the talking for us which, let's, be honest is the real end goal here anyways right, well. Anyways. I joined the web assembly team a little while ago and since, then I've been learning more and more about web assembly and what, it enables on the web and as. I learned more I started getting more and more excited, about how, it could change not. Only what we can create on the web but, also how we create it so, what, is web assembly anyways well. Web. Assembly, is a new low-level binary, format for, the web this. Means that it's close to the CPU, machine, code that your, computer understands, and it. Has all the security, that we've come to expect from executing. Code on the web, it's. Compiled, from other languages which means that you can write something like C++, and then compile, it into web assembly. Because. It's so low level and compiled from other languages, it also offers, maximize, performance in, this. Talk I want to talk to you about why web assembly is such a game changer for how we create things on the web then. I want to actually jump into some code and show, you how you can be writing web assembly, today, then. I'll showcase some of the amazing, applications, that we've seen on the web already, utilized. Web assembly, to great effect and then, I'll close out by showcasing a little bit of what we still have on the roadmap for. Web assembly features, okay. So what, are the actual advantages, of web assembly, and why might you want to use it. Well. First, off is this performance, because. Web assembly, was designed for speed it offers better performance than JavaScript camp, javascript. Is a dynamic, language which. Is great - making it easy to write but, it also means that, the JavaScript, engine has. To optimize that JavaScript as it's being executed on the, page web. Assembly is optimized before it actually hits the browser and this allows it to offer better and more reliable performance than JavaScript. Secondly. Webassembly.

Offers. Amazing portability. Because. You can compile from other languages you can port not only your own applications. To the web but, also the incredible wealth of C++. Libraries. And open, source applications, that exist out there and. Because. C++, specifically, is supported, on practically, every platform, including. IOS and Android you. Can now write C++, as the common language across your different web and mobile. Deployments, by leveraging web assembly. Lastly. And potentially, most, exciting to many of you out there is, the prospect of more flexibility. When, writing for the web specifically. The ability to write in different languages, since. The web's inception, javascript, has been the only fully supported, option for, developers, who want to write logic for the web but, now with web assembly you have more choice. The. Current fully supported, languages, are C C++. And, rust but, there are many other languages that are experimenting, with adding, support including. Kotlin and dotnet. Both, of which have shipped experimental, support for web assembly. So. Why, do these powers, and, abilities, and web assembly actually matter in the first place and why do we want to do interactivity. On the web well. To really explain that I want to go back to a time when, we didn't have any interactivity. On the web whatsoever. This. Is the first-ever web page, published, by Tim berners-lee in, 1991. As you. Can see in its original form the, web was really just slightly, formatted, text meant, only for consumption, of information, aside. From clicking on links there was literally nothing you could interact with at all. Then. JavaScript, comes along and is famously created in a single 10 day hackathon, this. Brings, some level of basic code execution, to the browser and. With. This foundation of JavaScript, we see the first real, web at the Kay actually. Come to the web, these, include examples like Gmail but, also things like MapQuest, and eBay. As. Interest, grew in what you could do with interactivity, on the web we, saw an incredible explosion of developer. Created libraries, and these, were libraries such, as jQuery, for doing Dom manipulation, angular. And other popular, frameworks, for organizing, your page content on the client and also. Things like three Jas and d3.js, to, make beautiful and interactive, visualizations and. There. Are so many more other libraries, that expand. What we can collectively create, on the web this.

Is One of my favorite, things about working on the web platform is that, you, have this easy ability for any developer to. Package, up some functionality, that they're the expert on and then share that capability, with everyone, allowing, us to build amazing, things that we wouldn't have been able to otherwise. Browsers. Also continued, to advance during, this time you, had things like v8, revolutionising. JavaScript, performance to. Expand, what you could actually feasibly, create, with JavaScript, you, also had capabilities like, WebGL bringing, interactive, graphics. Html5. Bringing, new capabilities, to the DOM and just. Recently with Surfer serviceworkers. Allowing, you to do offline. And so much more all. Of these technologies, and others, continue to expand, what was actually possible to do on the web and the. Industry responded, in kind by, bringing more and more of their applications, to the web we. Saw examples like, Google, Docs Trello, and even Microsoft Office 365 all. Start, to move to the web. But. Why why. Was there such an appetite for, application, and interactivity, on the, web in the first place why, didn't we just leave interactivity. To the native operating system where, developers could have full access to everything and choose, whatever language they wanted to be developing it well. There are three fundamental powers. Of the, web that actually make it a fantastic space, specifically. For applications. First. Off is link ability this, means that your app is not only accessible, by a single click on any other page but. You can even share your application. Or a specific document for your application, through, a single, shareable, clickable, string. Secondly. The, web application, is ephemeral and this, means that your users don't have to worry about the process, of going and installing, your application, or whether the application is trustworthy the. Application, is securely, delivered, in a sandboxed environment as soon, as the user needs it. Lastly. The web is the only truly universal platform meaning, that your application, is accessible, by anyone on any device this. Also means that you can maintain a single code base and be sure that every user can access your application, something, I think all of us can really appreciate and. So. Because, of these incredible, powers that the web offers for interactivity, we. Went from this, small, scripting, language all the way to this incredibly, powerful, and popular platform. Filled, with amazing applications. And capabilities, but, which was still fundamentally. Powered by this same, scripting. Language that was never really designed to do all of this in the first place. That's. Why the web browsers came together to, create web assembly and it's why web assembly, is now shipping in all four major browsers, making, it the first run time since, JavaScript. Was created, more than 20 years ago to, be shipped in every browser. Web. Assembly isn't meant to replace JavaScript though the two were designed to interoperate and within chrome it's actually the same team working on both rather. Web, assembly, is the foundational. Power that, unlocks the ability to create new native-like. Experiences. On the, web and it, gives you a porting, path to move your applications, to the web without. Having to rewrite them. Okay. So hopefully that gives you a little bit of a sense of what webassembly, can offer and gets, you as excited as I am to jump, into some code I want. To start off by showcasing. The final result of what, you can actually build right here at i/o by going and checking out the code lab that we have available to you or you can access it from bit dot Li's laughs laughs mio 2018. And. Without further ado here it is this. Is a hourglass. Example, where, we've taken the chipmunk physics engine which is the one utilized by cocos2d and then, we've leveraged web assembly to bring it into the browser we.

Use The engine to simulate this running hourglass, where, every single grain of sand that you see in the hourglass is actually, its own SVG. Dom element. And. If I want I can actually play with it you can see this for yourself when you go and check out the code lab but, you can turn it over and have all of the little SVG, elements, respond, accordingly okay. So let's have a look at some actual code and again. The. First thing I want to mention is web assemblies amazing, tool chain unscripted, some. Of you may know him scripting from when it was used to turn C++. Into, Assam Jas which was a precursor to webassembly, M scripting. Has since morphed into a fantastic, tool chain for, web assembly it's. What you'll use to compile your source file into, the web assembly format but it also does so much more for you it. Offers a lot of automatic, translation, such, as translating, your OpenGL, API calls, into, their WebGL, alternatives. And it, also simulates an entire file system for your ported applications, to utilize. It. Also includes, the C standard library and. Provides. Alternatives. To Linux build tools such, as configure, and make you. Can read all the details of atom script Anatomy scripting org. Ok, so let's look at some code. Here, I have the computational, equivalent of a hello world which. Is a simple C function, that calculates the, nth Fibonacci number. You'll. Notice these two additional pieces at the top this, top line is included, is. Used to include the M script and library and then, this second line is used, to tell M script in that, we're going to be calling this function and that it shouldn't remove, this function even if it seems to be unused. This. Is the command that we'll use to actually compile, our file and we can step through each of the pieces. You'll. First use EMCC, to, actually execute the inscription compiler. Then. We'll pass in - s latin. Equals 1 to, make sure that M scripting will output webassembly. Since, it still outputs, as in J s by default though this will be changing to defaulting, to webassembly soon. We. Also want to name our output file so we will pass in - o fib, KS, and. Then. Finally we'll pass in our input file fib dot C and this is the whole command that you need to execute. EMCC. Will then give us back two different files fib, Lassen and fib, KS. Cybil, azzam holds, the minimal web assembly, binary, for a Fibonacci function while. 50s, holds. Some helper code to load the web assembly module and set it up properly, it's. Worth noting here that I'm scripting has many different, ways to, output, code based on your needs in. This example we're having an output this.j, s helper file but, you can even have it out put an entire HTML, page with a terminal simulator, in it, to help you get started these. Are both useful ways to get started but they include some code that might not be necessary in, every application and if, you're trying to create something that's truly production-grade, it'll. Be important important for you to dig into the m script in library, and documentation. To figure out what to include. Alright, so next let's have a look at the HTML page that you need to use in order to actually include this at. The top line we'll just use the simple script tag to import.

Our Fib KS. And. Including. This fib KS, is what gives us access to this module, object the. Module object is a central, part of M script n' and it's, how you'll access in scripted functionality this. Module object comes, with a function called c wrap which. Will return, a JavaScript, function that allows us, to call our compiled web assembly function while, taking care of all of the input and output type, conversion, for us and. Then. We can actually just call that function directly and, if. We pass in 12 we correctly see that we get back out, 233. Awesome. So this, is a basic example of, how, you can communicate between web assembly and JavaScript but there are also other ways for you to communicate between, the, border of JavaScript. And web assembly which. One you choose will ultimately, depend on your own preference, and the architecture, of your application, alright, so for, the next example I want, to start off and show a brand new way of how. You can communicate between this JavaScript and web assembly border. Our. End goal will be to make this animating, weirdly spinning ball paints, it onto a canvas by utilizing, some web api's, but. With logic controlled in C++, so let's, start off and we'll create a ball dot CPP, file and you'll, notice once again we include the M script and library to get all the benefits of that provides. Next. Let's, talk about this emj, s function which, seems to have javascript code inside of it despite, this being a C++, file, well. The, reason why we can do this is because, emj, s is a special, macro, known, by the inscription library. The. Format is that you first pass in your return type then, the name of the function and then, the list of arguments, that you'll be calling that function with. The. Great advantage that emj, s gives is that you can now write the JavaScript that you know and love while, staying in that same C++, file so. In this piece of JavaScript, we just simply find, the canvas grab the context, and paint, a red circle at the given location with the given radius. We. Then include, a classic main function. That, calls our function, draw circle. In the given location and radius thanks. To e MJ s and scripting, takes care of converting. These, inputs, into, what. Will be used in the inside of the JavaScript, function and then calling, that JavaScript time function, you, can also find more documentation, on how emj, s works at Emscripten, org. Alright. So this is the command, that we're going to use to compile this piece of code and this time we're gonna get a little bit more fancy and optimized with it we'll. Pass in this -, o 3, which, will tell the inscription compiler, to, optimize, aggressively, including. The removal of unused, code. Because. We're telling him scripting to remove unused code we also have to be explicitly. Explicitly. Tell and script and that we're going to want our old friend C rap to, still be included since we'll be utilizing that later. All. Right now, we have again, an index dot HTML file. Dirt, simple this time it just includes the canvas tag and then, we load our ball AF, script you'll. Notice that we don't actually have to call our main function at all and this is because we named it main and then scripted knows to execute, that on startup because, it's a common C++, pattern and. Boom. You put all that together and you have your single C++, file that. Tells that calls a JavaScript function and then paints this ball onto the canvas this. Is great but so far the only thing that we're actually doing in C++, logic is calling into a JavaScript function so, let's do something a little bit more interesting. We. Want to start by animating, this ball and in, order to animate it we have to clear the canvas each frame so we'll just make another a MJS function, we'll pass in a void return type name. It clear canvas, and no arguments, inside. Of this we're just grabbing the context, again and clearing it completely. Okay. So we want to actually start taking advantage of some of the C++, logic that we can implement and we'll, start off by including, math.h, be, custom scripting includes the c standard library we. Get full interoperable. Access, to, this math library, without having to worry about porting, it ourselves. Then. Further down in our file will. Have this static, float T in order to keep track of time and we'll swap out our main function, for an update function, that will be calling repeatedly just. Like, in our last example we'll, utilize an script and keep alive to make sure that M scripting doesn't get rid of this function but, you'll also notice that we have this X turn c wrapper. Around our function. This. Is included so that M scripting won't do any name mangling while. Compiling our C++, function the. Reason we even have to do this in the previous example, is because that was just C code not, C++, any. Func, C++, function whose, name you want to remain unchanged.

And Referenceable. But from JavaScript needs, to be inside of this extern c wrapper. All. Right and then inside this inner logic we just update our time variable call, our clear canvas function and then draw our draw circle function, with, some funky sign math that we get from the. Math library. Awesome. So now let's jump into our index.html page, and actually set this up so that we'll call our update function on, a continual, basis. To. Do this will once again take advantage of M script and understanding, what the module object is we'll, define this module object then. We set a pre run function on it and this, pre run function simply utilizes. Requestanimationframe. To. Call our update function that. We once again get, from c wrap and. Then. At the bottom we'll also include our ball AF script, and. Just. Like that you have this wonderfully, weird animation. Being controlled by C++, logic. Great. So, now, that we have some of that basic. Non-battle. That we know the basics of writing some web assembly let's, have a look at what some developers, have already accomplished. By utilizing, web assembly. One. Company that's, been able to utilize the, performance, of web assembly, and the link ability of the lab is Sigma, Sigma. Is a powerful, cloud-based, screen. Design platform that. Makes it easy for teams to work in sync on a design, through, a single URL, design. There's product managers engineers and, others involved in design, process can. Now iterate. And design on a single, place to. Gather feedback without. Having to worry about exporting, documents. Or, managing. The application, it's all right there instantaneously. It. Used to be that with native design tools you have to worry about managing, all of your files whether. Everyone involved in the process had the right software installed, and whether, or not people's operating, system even supported, the application, in the first place now. You, can use the power of Link's as the single source of truth while. Enabling anyone, on any device to access your application, or a specific, document while, trusting, that it'll always be up to date. Great. So let's, have a look at how they've actually architecture, of their application, to include webassembly and see if we can learn anything. For. The non performant, part of their rendering. Or of their application, they, use a modern, typescript, language with, the react framework in. The. Center area of their application, they have a single canvas with, all of their logic implemented, in C++ through. Web assembly this. Section has three different components inside, of it, the. First is a custom, rendering engine where they decode, their file format, through, web assembly and then render it onto the canvas by utilizing WebGL.

Secondly. Is a custom, text editor where, they actually been able to utilize popular. Open, source C++. Library, again, by leveraging web assembly and. Then. Finally they have a collaboration, system that uses WebSockets. For fast multiplayer, editing by. Utilizing, all of these different, advanced, tools and features of the web they're, able to create an application, experience. That is not only highly performant, but also has all of the advantages of being an application, on the web. Another. Great company that I want to talk about that's. Really been able to leverage the universality, and ephemeral, Ness of the web is construct, three construct. Three is a full-blown, game engine, and editor, that, allows you to create an export games directly, from the browser. Thanks. To the ephemeral nests they have an onboarding flow that takes you from their. Marketing page loads. Up the editor lets you pick the project and be inside of the application in less, than a minute. Once. You're in the application, you can immediately jump in and start making any edits that you want maybe, adding, a little bit of game, logic or doing whatever other edits you need to and then, when you're ready you can also export, it directly from inside, of the browser this. Is an interesting point because here's where construct, 3 leverages. The universality, of support. For the web platform by. And enabling, their. Export. To different platforms. It. Actually exports, the game as a single web page and then, utilizes, basic wrappers around that content, to make it appear like a native application. Construct. Has all of their UI and, logic implemented in JavaScript, but utilizes, webassembly, for, its audio decoding as well, as poly fillings, functionality. And some older browsers. Alright. Another, company that I'd like to tell you about is AutoCAD but, instead of me telling you about it I'd like to invite Marcos O'Brian onto the stage senior. Product line manager at, AutoCAD, to tell you about the experience himself Thomas, that's great. Hey, everyone how's it going so. My name is Marcus O'Brien and I, lead the autocad product management team at, Autodesk, so. We. Have a couple of people from AutoCAD in the audience here today I'd like to give a shout out to the web team and the mobile team that's come from Tel Aviv specifically. For Google i/o, so. Today. I'd like to tell a short story, about autocad's, journey to the web. So. AutoCAD, is a computer-aided, design and, drafting software, application, it's. Used by the world's most innovative engineers. And architects, to, imagine design and make the world around us. It. Was first released in 1982. It's, not a new application, and prior.

To AutoCAD, design was done by, people using, pen and paper on drafting, boards. The. Cost of revision, was slow and innovation. Was slow as a result, so. The vision for AutoCAD from the very beginning, was, to reduce, the amount of time it takes to innovate to, increase. The number of iterations possible. Within a design process and to, ultimately help, designers. Optimize. For the best possible solution, to the problems they were trying to solve and. AutoCAD. Has changed, the world continuously, as it's evolved, over the last 35, years. More. Than ten years ago or more than 10 years after AutoCAD, was first introduced, the internet, was born, we heard tits Sir Tim berners-lee. Pioneered. This an AutoCAD. Real was, made popular with mosaic. And Netscape. And. Internet Explorer. AutoCAD. First dipped its toe in the water of Internet connectivity with, AutoCAD, mm. I where, I stood, for Internet and many. Years later we first released in 2010. The, autocad web and mobile apps but, really this was just the beginning of the autocad connected, story. So. Now with AutoCAD on desktop, web and mobile and new vision, was born this, was a vision where we could free our customers, these designers, from their desks, so that they could take AutoCAD wherever they go with them to, increase. Their chances at innovating, even further and to, add to the work flows. So. The. AutoCAD web app was intended, to allow people to work from anytime anywhere, and have access to this precision, drafting. App whether, they're at home or on the go I, just. Want to tell you that AutoCAD standard, file type is called a DWG, file, there. Are an estimated 2, to 5 million, DWG. Files opened a day that's. A lot and there's. Some 5 billion, DWG. Zhan cloud sort servers, today so. The anytime anywhere, access is, even, more important, than it's ever been before. However. As much. As we wanted to bring AutoCAD, to a browser. We. Were a little bit limited by the technology that was available at the time, in 2010. We bait we we released, a flash based version. Which. Gotta start, kind of a toe in the water in terms of having a basic, editor in a browser. In. 2014. We shifted, from flash and changed, to html5 and, JavaScript. And this. Work but we realized very quickly that this was not a very scalable way, for us to build this, precision, drafting tool in a browser because. We had all the features already in our C++, code base and we were having to rewrite them in JavaScript, for this browser so. It wasn't very scalable. So. Two years ago we started exploring, what. Were the options for us to to port our common, code base to, the browser and, we got a number of quick wins early on so we started to take it more seriously, and. The. Winds kept coming so. One year ago we were able to release our, first beta viewer, to, our beta. Customers where, they could view. Or read native, DWG. S in a browser, so. To put that into context, customers.

Were Able to open a 25, year old drawing, file and read, it in the browser. About. 8 months ago we. Were able to port our first true feature from AutoCAD core over, to our browser. In. December, we had the makings of a basic editor with, lines arcs and circles on, web assembly, and we, released this this in beta as well to our customers, and then. On March 22nd, of this year we hit a major, milestone, for. The first time we were able to release the AutoCAD Weber and we were finally able to unlock, the power of AutoCAD, in a browser with. Zero download, and install, required. So. How do we make this happen, we. Have the common, AutoCAD, C++, code base, which. We translate with M scripting. Which. Gets compiled, at runtime in the browser, we. Have our reactant, typescript UI running, on the main thread and it. Works together with wedid web assembly modules, running on a web worker to, create the AutoCAD web application, but what. Does this really mean in real terms, so. Having a shared common, C++. Code base means that our C++, developers, can, develop features. And bug, fixes for. Across, our platforms, without ever having to learn JavaScript. Or our other web technologies, and for. Our customers it means that they have enhanced cohesive, experiences. The, feature that you build on desktop. It just works on more on web. So. Here is a look at it running in Chrome you might have seen this made, stage yesterday, so. Customers, familiar, with AutoCAD will immediately recognize this, you, can see it in the canvas here it's very familiar and you, can see that you've got your crosshairs, it's a very AutoCAD, experience, and interacting. With it feels like using, AutoCAD desktop. You. Can see the JavaScript UI it's giving very user. Feedback and control to the user and, it's interacting, smoothly with the performant. Webassembly canvas, that's. Been ported from our C++, code base so. Overall. Building on web assembly helped us lock deeper, capabilities, of autocad's optimized, code base that would have been impossible to rewrite in JavaScript, it. Cuts our development, by orders of magnitude and, in, fact it's more performant, than had we developed this in JavaScript alone. So. With all the CAD running on web. Assembly in addition. To our AutoCAD. Core codebase our, vision for a web app is no longer limited by web technology, so. I'm really excited about where we're taking this and the opportunities, that we're pursuing for, both for AutoCAD and for our customers in terms of what they can do with AutoCAD in a browser, and, with that I'd like to hand back over to Thomas thanks, very much. Thank. You Marcus it's, been really amazing to see AutoCAD. Utilized webassembly, to gain all the powers of the web and enable. Their customers, to access AutoCAD anywhere so. Now that we've seen some of these different amazing high-performance, demanding applications, I want, to go back and talk again about libraries. Remembering. Back to the early stages of the web when, we saw that explosion, of amazing, developer created libraries, I think, we're at a similar inflection, point now with web assembly well. I don't have time to show off all the examples, unfortunately. We've seen some amazing developers. Leverage, web assembly to make everything from physics engines, facial, recognition systems. Video, editing, and even artificial intelligence, these. Tools can be packaged, up and then. Enable, all of us to have, these capabilities for ourselves and I'm so excited to see what all of us will be able to build when, we unlock these new next-generation, libraries. That, are enabled by web assembly. We've. Also seen existing, popular libraries, start, to adopt web assembly to maximize their performance we've. Seen the glimmer rendering, engine which is the one utilized by the Ember framework already, start making commits with web assembly to improve their performance. Okay. So, now that we've seen some cool use cases for web assembly, learned a little bit of web assembly, ourselves. I want, to show off what we still have in the works this. Is some in progress works, so it's not completely refined, yet something. That I think will come across in the style of these slides. Probably. The most exciting, feature that we're working on is threads, which, can double or even quadruple. The performance, of your application, modern. CPUs, shipped with several cores but, historically, the web has had very limited access to, these additional course restricting.

How Performant, your application, could be compared. To native. You. Get some additional access to these cores through web workers which are great but, workers can be quite heavyweight, and they, only, communicate, through post message restricting. What use cases they enable the. Way. Web assembly threads will work is by, using shared array buffer to, communicate, between the workers at high speed this. Also means that existing, C++. Code bases, that, utilize, piece. Or, which rely on blocking can be ported, directly, to the web and take, full advantage, of the, benefits, that threading provides. We're. Also improving the way that webassembly can talk to the rest of the web browser right. Now web assembly always sits within a sea of JavaScript, and when, it wants to make calls to, the Dom or to Web API it's like WebGL it, has to go through JavaScript, to do so. We're. Changing that so the web assembly, can directly hold references, to the Dom or web, API and communicate. Without having to go through JavaScript. Looking. A bit further ahead we've also started exploring, direct ES module, support for web assembly this. Will improve the ability for javascript and web assembly, to import, and interact with modules, of the other type without, having to do any unnecessary wrapping. Together. With letting web assembly hold references, to the dom and web api x' were, substantially. Improving, web assemblies, interoperability. With, the rest of the web stack. Also. Further out is the prospect of adding first-class support for other languages, the. Reason why C C++ and rust are the current fully supported, languages is that they manage their own memory, and don't, have a garbage collection system, that manages it for them as I. Mentioned earlier we have seen. Languages. Like Kotlin, or the.net framework ship. Experimental. Support for web assembly and they've, been able to accomplish this by actually, compiling, down their garbage collector and with, the rest of their runtime environment, - web assembly and then shipping it along with their page, because. Of web assemblies, small, signs, this, doesn't add as much bloat as you might think but, it's definitely not ideal and you also have to be very careful, when making interactions. With the Dom or with, web api's to, prevent you from leaking memory, we're. Working on a proposal called the managed object proposal, that, we hope will add better first party support to these languages, and enable, them fully in the browser. So. That brings me towards the end of my talk and. To close out I want, to really just ask all of you to go out there and build amazing things with web assembly. Go port some applications, for the web go, create some amazing developer. Library that'll, give all of us additional superpowers, on the web, whatever. You do and. Whatever you end up creating I hope you'll share it with others I would, certainly love to hear about it and you can tweet me directly or, you can tweet the awesome v8 team that's actually working on all of this functionality at v-- HAF thank. You so much.

2018-05-12

Show video