December 9, 2011

Filed under: tech»web

Trapped in WebGL

As a web developer, it's easy to get the feeling that the browser makers are out to get you (the standards groups definitely are). The latest round of that sinking feeling comes from WebGL which is, as far as I can tell, completely insane. It's a product of the same kind of thinking that said "let's literally just make SQLite the web database standard," except that for some reason Mozilla is going along with it this time.

I started messing with WebGL because I'm a graphics programmer who never really learned OpenGL, and that always bothered me a little. And who knows? While I love Flash, the idea of hardware-accelerated 3D for data visualization was incredibly tempting. But WebGL is a disappointment on multiple levels: it's completely alien to JavaScript development, it's too unsafe to be implemented across browsers, and it's completely out of place as a browser API.

A Square Peg in a JavaScript-shaped Hole

OpenGL was designed as an API for C a couple of decades ago, and even despite constant development since then it still feels like it. Drawing even a simple shape in OpenGL ES 2.0 (the basis for WebGL) requires you to run some inscrutable setup functions on the GL context using bit flags, assemble a shader program from vertex and fragment shaders written in a completely different language (we'll get to this later), then pass in an undistinguished stream of vertex coordinates as a flat, 1D array of floating point numbers. If you want other information associated with those vertices, like color, you get to pass in another, entirely separate, flat array.

Does that sound like sane, object-oriented JavaScript? Not even close. Yet there's basically no abstraction from the C-based API when you write WebGL in JavaScript, which makes it an incredibly disorienting experience, because the two languages have fundamentally different design goals. Writing WebGL requires you to use the new ArrayBuffer types to pack your data into buffers for the GL context, and acquire "pointers" to your shader variables, then use getter and setter functions on those pointers to actually update values. It's confusing, and not much fun. Why can't we just pass in objects that represent the vertexes, with x, y, z, vertex color, and other properties? Why can't the GL context hand us an object with properties matching the varying, uniform, and attribute variables for the shaders? Would it kill the browser, in other words, to pick up even the slightest amount of slack?

Now, I know that API design is hard and probably nobody at Mozilla or Google had the time to code an abstraction layer, not to mention that they're all probably old SGI hackers who can write GL code in their sleep. But it cracks me up that normally browser vendors go out of their way to reinvent the wheel (WebSockets, anyone?), and yet in this case they just threw up their hands and plunked OpenGL into the browser without any attempt at impedance matching. It's especially galling when there are examples of 3D APIs that are intended for use by object-oriented languages: the elephant in the room is Direct3D, which has a slightly more sane vertex data format that would have been a much better match for an object-oriented scripting language. Oh, but that would mean admitting that Microsoft had a good idea. Which brings us to our second problem with WebGL.

Unsafe at Any Speed

Microsoft has come right out and said that they won't add WebGL to IE for security reasons. And although they've caught a lot of flack for this, the fact is that they're probably right. WebGL is based on the programmable pipeline version of OpenGL, meaning that web developers write and deliver code that is compiled and run directly on the graphics card to handle scene transformation and rendering. That's pretty low-level access to memory, being granted to arbitrary people on the Internet, with security only as strong as your video driver (a huge attack surface that has never been hardened against attack). And you thought Flash was a security risk?

The irony as I see it is that the problem of hostile WebGL shaders only exists in the first place because of my first point: namely, that the browsers using WebGL basically just added direct client bindings to canvas, including forcing developers to write, compile, and link shader programs. A 3D API that was designed to abstract OpenGL away from JavaScript developers could have emulated the old fixed-function pipeline through a set of built-in shaders, which would have been both more secure and dramatically easier for JavaScript coders to tackle.

Distraction via Abstraction

Most programming is a question of abstraction. I try to train my team members at a certain level to think about their coding as if they were writing an API for themselves: write small functions to encapsulate some piece of functionality, test them, then wrap them in slightly larger functions, test those, and repeat until you have a complete application. Programming languages themselves operate at a certain level of abstraction: JavaScript hides a number of operating details from the developer, such as the actual arrangement of memory or threads. That's part of what makes it great, because managing those things is often a huge pain that's irrelevant to making your web application work.

Ultimately, the problem of WebGL is one of proper abstraction level. I tend to agree with JavaScript developer Nicolas Zakas that a good browser API is mid-level: neither so low that the developer has to understand the actual implementation, nor so high that they make strong assumptions about usage patterns. I would argue that WebGL is too low--that it requires developers to effectively learn a C API in a language that's unsuited for writing C-style code, and that the result is a security and support quagmire.

In fact, I suspect that the reason WebGL seems so alien to me, even though I've written C and Java code that matched its style in the past, is that it's actually a lower-level API than the language hosting it. At the very minimum, a browser API should be aligned with the abstraction level of the browser scripting language. In my opinion, that means (at the very least) providing a fixed-function pipeline, using arrays of native JavaScript objects to represent vertex lists and their associated data, and providing methods for loading textures and data from standard image resources.

In Practice (or, this is why I'm still a Flash developer)

Let me give an example of why I find this entire situation frustrating--and why, in many ways, it's a microcosm of my feelings around developing for so-called "HTML5." Urban Artistry is working on updating our website, and one of the artistic directors suggested adding a spinning globe, with countries where we've done international classes or battles marked somehow. Without thinking too much I said sure, I could do that.

In Flash, this is a pretty straightforward assignment. Take a vector object, which the framework supports natively, color parts of it, then either project that onto the screen using a variation of raycasting, or actually load it as a texture for one of the Flash 3D engines, like PaperVision. All the pieces are right there for you, and the final size of the SWF file is probably about 100K, tops. But having a mobile-friendly site is a new and exciting idea for UA, so I thought it might be nice to see if it could be done without Flash.

In HTML, I discovered, fewer batteries come included. Loading a vector object is easy in browsers that support SVG--but for Android and IE, you need to emulate it with a JavaScript library. Then you need another library to emulate canvas in IE. Now if you want to use WebGL or 3D projection without tearing your hair out, you'd better load Three.js as well. And then you have to figure out how to get your recolored vector image over into texture data without tripping over the brower's incredibly paranoid security measures (hint: you probably can't). To sum up: now you've loaded about half a meg of JavaScript (plus vector files), all of which you have to debug in a series of different browsers, and which may not actually work anyway.

When faced with a situation like this, where a solution in much-hated Flash is orders of magnitude smaller and easier to code, it's hard to overstate just how much of a setback HTML development can be--and I say that as someone who has grown to like HTML development much more than he ever thought possible. The impression I consistently get is that neither the standards groups nor the browser vendors have actually studied the problems that developers like me commonly rely on plugins to solve. As a result, their solutions tend to be either underwhelming (canvas, the File APIs, new semantic elements) or wildly overcomplicated (WebGL, WebSQL, Web Sockets, pretty much anything with a Web in front of it).

And that's fine, I'll still work there. HTML applications are like democracy: they're the worst platform possible, except for most of the others. But every time I hear someone tell me that technologies like WebGL make plugins obsolete, my eyes roll so hard I can see my optic nerve. The replacements I'm being sold aren't anywhere near up to the tasks I need to perform: they're harder to use, offer me less functionality and lower compatibility, and require hefty downloads to work properly. Paranoid? Not if they're really out to get me, and the evidence looks pretty convincing.

August 17, 2010

Filed under: tech»web

The Web's Not Dead, It's RESTing

Oh, man. Where to start with Chris Anderson and Michael Wolff's dreadful "The Web Is Dead"? With the hilarious self-congratulatory tone, which treats a misguided 1997 article on push technology (by the equally-clueless Kevin Kelly) as some kind of hidden triumph? With the gimmicky, print-mimicking two-column layout? How about the eye-burning, white-on-red text treatment? Or should we begin with the obvious carnival-barker pitch: the fact that Anderson, who just launched a Wired iPad application that mimics his print publication, and who (according to the NY Times and former employees) has a bit of an ongoing feud with Wired.com, really wants you to stop thinking of the browser as a destination.

Yes, Anderson has an agenda. That doesn't make him automatically wrong. But it's going to take a lot more than this weaksauce article to make him right. As I noted in my long, exhausting look at Anderson's Free, his MO is to make a bold, headline-grabbing statement, then backpedal from it almost immediately. He does not abandon that strategy here, as this section from the end of the piece shows:

...what is actually emerging is not quite the bleak future of the Internet that Zittrain envisioned. It is only the future of the commercial content side of the digital economy. Ecommerce continues to thrive on the Web, and no company is going to shut its Web site as an information resource. More important, the great virtue of today's Web is that so much of it is noncommercial. The wide-open Web of peer production, the so-called generative Web where everyone is free to create what they want, continues to thrive, driven by the nonmonetary incentives of expression, attention, reputation, and the like. But the notion of the Web as the ultimate marketplace for digital delivery is now in doubt.
Right: so the web's not actually dead. It's just that you can't directly make money off of it, except for all the people who do. Pause for a second, if you will, to enjoy the irony: the man who wrote an entire book about how the web's economies of "attention, reputation, and the like" would pay for an entire real-world economy of free products is now bemoaning the lack of a direct payment option for web content.

Wolff's half of the article (it's the part in the glaring red column), meanwhile, is a protracted slap-fight with a straw man: it turns out that the web didn't change everything, and people will use it to sell traditional media in new ways, like streaming music and movies! Wolff doesn't mention anyone who actually claimed that the web would have "transformative effects," or how streaming is not in and of itself fairly transformative, or what those other transformative effects would be--probably because the hyperbole he's trying to counter was encouraged in no small part by (where else?) Wired magazine. It's a silly argument, and I don't see any reason to spend much time on it.

But let's take a moment to address Anderson's main point, such as it is: that the open web is being absorbed into a collection of "apps" and APIs which are, apparently, not open. This being Chris Anderson, he's rolled a lot of extraneous material into this argument (quality of service, voice over IP, an incredibly misleading graph of bandwidth usage, railroad monopolies), but they're padding at best (and disingenuous at worst: why, for example, are "e-mail" and VPNs grouped with closed, proprietary networks?). At the heart of his argument, however, is an artificial distinction between "the Web" and "the Internet."

At the application layer, the open Internet has always been a fiction. It was only because we confused the Web with the Net that we didn't see it. The rise of machine-to-machine communications - iPhone apps talking to Twitter APIs - is all about control. Every API comes with terms of service, and Twitter, Amazon.com, Google, or any other company can control the use as they will. We are choosing a new form of QoS: custom applications that just work, thanks to cached content and local code. Every time you pick an iPhone app instead of a Web site, you are voting with your finger: A better experience is worth paying for, either in cash or in implicit acceptance of a non-Web standard.
"We" confused the two? Who's this "we," Kemosabe? Anderson seems to think that the web never had Terms of Service, when they've been around on sites like Yahoo and Flickr for ages. He seems to think that the only APIs in existence are the commercial ones from Twitter or Amazon. And, strangest of all, he seems to be ignoring the foundation on which those APIs are built--the HTTP/JSON standards that came from (and continue to exist because of) the web browser. There's a reason, after all, that Twitter clients are not only built on the desktop, but through web portals like Seesmic and Brizzly--because they all speak the language of the web. The resurgence of native applications is not the death of the web app: it's part of a re-balancing process, as we learn what works in a browser, and what doesn't.

Ultimately, Anderson doesn't present a clear picture of what he thinks the "web" is, or why it's different from the Internet. It's not user content, because he admits that blogging and Facebook are doing just fine. He presents little evidence that browser apps are dying, or that the HTTP-based APIs used by mobile apps are somehow incompatible with them. He ignores the fact that many of those mobile apps are actually based around standard, open web services. And he seems to have utterly dismissed the real revolution in mobile operating systems like iPhone and Android: the inclusion of a serious, desktop-class browser. Oh, right--the browser, that program that launches when you click on a link from your Twitter application, or from your Facebook feed, or via Google Reader. How can the web be dead when it's interconnected with everything?

You can watch Anderson try to dodge around this in his debate with Tim O'Reilly and John Battelle. "It's all Internet," O'Reilly rightly says. "Advertising business models have always only been a small part of the picture, and have always gotten way too much attention." Generously, O'Reilly doesn't take the obvious jab: that one of the loudest voices pitching advertising as an industry savior has been Chris Anderson himself. Apparently, it didn't work out so well.

Is the web really a separate layer from the way we use the Internet? Is it really dead? No, far from it: we have more power than ever to collect and leverage the resources that the web makes available to us, whether in a browser, on a server, or via a native client. The most interesting development of "Web 2.0" has been to duplicate at the machine level what people did at the social level with static sites, webrings, and blogs: learn to interoperate, interlink, and synthesize from each other. That's how you end up with modern web services that can combine Google Maps, Twitter, and personal data into useful mashups like Ushahidi, Seesmic, and any number of one-off journalism projects. No, the web's not dead. Sadly, we can't say the same about Chris Anderson's writing career.

June 15, 2009

Filed under: tech»web

A Surprising Depth

This weekend, the total number of posts on Twitter exceeded the possible range of a 32-bit number--

...hang on a second, and let's marvel at the sheer size of that. It is easy to forget that a 32-bit number is actually mind-bogglingly huge, since hey, there's only 32 bits. Remember, however, that bits are like the pennies on the chessboard in that old mind-teaser: each one doubles the size of the digit before it. So in binary, you may start out counting 1, 2, 4, 8... but by the time you hit your 16th bit the total is 65,536 and it just keeps doubling from there. 32 binary digits is enough to encode more than 4 billion: 4,294,967,295, to be exact. Even in the signed integer format Twitter uses, which reserves one bit for negative numbers, it's still more than 2 billion. That's a lot of work for only 32 bits.

Anyway! So the service passed the 2,147,483,649 mark this weekend with, hilariously, a post claiming ungrammatically that "The Tweets must flow" and linking to a lolcat--

...sorry, I have to make another digression here regarding the terminology in question. There's a widespread idea, encouraged by Twitter itself, that updates should be referred to as "tweets." This is, pardon my curmudgeonliness, really stupid. First of all, Twitter is nothing more than a microblog, and we already have a term for the basic units of a blog: we call them posts. Where Twitter primarily diverges from something like Blogspot is only in the speed and hothouse intensity of its ecosystem, and you can even see examples of this in people who write both long-form blogging and Twitter. The kind of person, for example, who writes polished, slightly-pretentious management advice on his or her blog will also tend to write polished, highly pretentious posts on Twitter. In my own case, it's more of a sidechannel for links and petty commentary, but the voice is not radically different.

For another thing: just because it's the Internet, you don't have to leave all your dignity at the door. "Tweets?" Really? Do you know how embarrassing that sounds, like when you're in the middle of an editorial meeting, and a bunch of middle-aged journalists start talking about the tweets they've written lately? Because I do, and it'll turn your hair white.

Right! Back on topic: Twitter passed the 32-bit overflow mark this weekend. Doing so is not just a landmark number, it's also a potential bug for Twitter clients coded to use only a 32-bit integer in their data structures. Of course, such clients are relatively rare: modern high-level programming languages often express their numbers in 64-bit formats (the range of which I find almost incomprehensibly vast). But older languages, such as C++ and Java, may default to 32-bit integers unless told otherwise--I remember learning them as "long" integers, which says a lot about the progress that we've made. Coders these days should know better than to use the int type for something like a Twitter post ID, but it's an easy mistake to make.

Sure enough, a few clients did not handle the overflow well. On the iPhone, Twitterrific began to crash for people. My favorite Android client, Twit2Go, also threw exceptions when it went to retrieve posts. I like Twit2Go quite a bit (it's fast and acts like a real Android app, with good long-press and menu-button behavior), so this was annoying.

But it was also an interesting study in distribution methods. The developer of Twit2Go started working on the problem on Saturday morning, soon after the problem surfaced. Five hours later, he uploaded the fixed version to the Android market, and it was immediately available for users. The developers of Twitterrific, IconFactory, were actually on the job even earlier: a Friday post on the company blog noted the bug, including details about a previous update that, unfortunately, had not caught all the errors. At 6PM on Saturday (almost exactly the same time as Twit2Go), IconFactory submitted an update to the App Store that fixed the remaining bugs. As of this moment, the free version has only made it through to end users this morning, and the paid version is still in approval limbo. Drama ensued.

The problem overwhelmingly faced by open platform advocates is that abstract dilemmas are hard to transfer into mainstream, non-geek experience. Try discussing DRM with the average person, or explaining the "shallow bugs" principle to them, and watch eyes glaze over faster than Krispy Kreme. But this is a great, easy-to-translate example of the walled garden problem: because control is centralized and accountability is non-existent, paying customers have been unable to use updated software for two days now, for no other reason than the arbitrary whims of a large corporation. No appeals, no alternatives.

To sum up: "binary numbers are very large, think twice before coining a neologism, and make sure you own your hardware." Not a bad range of topics for a service with a 140-character limit, but I suspect it lacks flavor by comparison. As usual, it's more interesting to write about Twitter than to write something interesting using it.

April 14, 2009

Filed under: tech»web

All Relative

I have a solution for all the things that drive me crazy about HTML. At least, I think it's a decent solution. The bad news is that there's no chance whatsoever that anything like it would be implemented.

To restate the problem: HTML is a bad way of building an interface. Even discounting incompatibilities and rendering differences between browsers--and even well-behaved browsers can render differently--it's incredibly inefficient. I had another horror-show experience with it while working on another budget package for CQ.com. Normally, at the bottom of that page, there's a footer with CQ's information. Unfortunately, for simplicity's sake, I positioned the central content pane using "position: absolute," which is apparently a big mistake. It made the footer float up underneath the navigation menu and behind the content.

There is, no doubt, a solution for this, probably involving some combination of float, clear, and JavaScript. But it's missing the point. The fact that a footer even needs a clever solution--that there is, in fact, a 'sticky footer that just works'--is insane. Apparently they plan to solve this problem in HTML version 5 with new tags for headers and footers, which is well-intentioned but strikes me as bolting new and horrible combinations onto an already terrifying tag soup.

As is, I'm inclined to rely on either tables or Javascript for placing elements on the page. The former is crufty, and the latter is practically unmaintainable, but they do have the example of allowing me to lay out a page spatially in relation to its component elements. Javascript is particularly tempting, in fact: using tools like JQuery, I can easily find the various parts of a page and then reposition them in relation to each other. Sure, it'll probably break when the page resizes, on small screen sizes, and when confronted with non-dynamic HTML--but it's so much easier to move elements around that I almost don't care.

What we really need is a new model, one that combines the flexibility of CSS-based layout with the relational/visual model of tables and dynamic layout. Basically, when I'm putting a page together, I don't want to think about it in terms of elements floating around. I want to be able to say that this is 3em to the right of that (which is 1em below the other), containing a column of these. I want to be able to say that the footer is simply always below my content, instead of tricking the browser into setting that up for me. I want to be able to line elements up with other elements, or simply say that one should be next to another. Something like:

#container {
max-width: 50em;
margin: auto;
}

#header {
top: 2em;
}

#content {
position: relational(#header) below;
top: 1em;
left: 0em;
}

#sidebar {
position: relational(#content) right;
top: 0em;
left: 3em;
}

#footer {
position: relational(#content) below;
top: 3em;
}

There's even a model that I think we could use for this: Swing. For all the criticism heaped on Java's APIs (deservingly so, in many cases), Swing makes a lot of sense to me for building simple, reflowable layouts. My understanding is that XUL and XAML also implement similar container/layout strategies, which is also fine by me: anything's better than what we've got now, right?

I don't have a problem with new tags for semantic purposes. Being able to specify that something is an aside/nav/article element makes a lot of sense from an accessibility perspective, and that's important. But a single-minded focus on semantics at the expense of design and thin-client programming ignores a great deal of where the web has been going--and it imposes a top-down model on accessibility efforts that probably won't be able to keep up with innovation. I can't help think that we'd be better off with a global accessibility attribute that can be extended easily, while paying more attention to the glaring deficiencies in HTML as a presentation language.

February 13, 2009

Filed under: tech»web

The Browser Is The New X11

Since I'm not a GMail user, I didn't know about the new button design that Google implemented until I saw a reference to this post by their designer. As an exercise in HTML and CSS trickery, it's pretty impressive. As a look into the sausage-making for serious web application design, it fills me with abject horror.

To summarize: Google apparently wanted a button that would A) use no images for its appearance, and B) allow new kinds of interaction to go with their labeling functionality. In order to do this, they ended up creating a set of custom CSS classes applied to six nested DIV tags, as well as a large chunk of JavaScript, I'm sure. It's very clever, but it also makes me wonder just how far we're pushing HTML beyond where it was meant to go--and how much it's holding us back.

I've been writing HTML code, off and on, for more than ten years now, and I have hated every minute of it. I don't claim to be very good at it, of course, so maybe that's the problem. But it's always struck me as a technology stuck awkwardly between two worlds. On the one hand, a platform- and display-agnostic representation of textual content. On the other, the desire to build attractive, well-designed presentation layouts, including application interfaces. These are not, I think, entirely compatible with each other. Google's new buttons illustrate that tension, as they torturously beat text layout elements into paintbrushes (ones that will display across all the various browser quirks, no less).

There are new options to alleviate that, of course: the Canvas element gives Flash-like drawing tools to JavaScript and HTML developers (once it's more widely available--figure another couple years, at the rate things are going). And toolkits--jQuery UI, GWT, Dojo--have proliferated. But at some point, I think we have to stop, look at this situation, and realize that we're bludgeoning these tools into doing things that they fundamentally were not meant to do. As interface design languages go, HTML is terrible. I have a hard enough time getting a decent text layout to work reliably, much less trying to build interactive custom controls for anything more complicated than a basic form.

The interesting thing about computing trends, though, is that they're cyclical. Displaying information through a clumsy "semantic" thin client/fat server relationship? We've been there, and then most of us ran away to something better as fast as we possibly could. It's only a matter of time, I suspect, before something replaces HTML for doing UI (while maintaining the lessons we've learned about REST and open communication standards), and at that point we will look back in horror, and wonder how we managed for so long.

If you want to see how this is going to go, consider Twitter. All the basic functionality is available from twitter.com, but almost no-one I know uses that if they can help it. Invariably, you get a better experience from one of the clients (I use Twhirl and TinyTwitter for desktop and mobile, respectively). They're more reponsive, they take advantage of the native platform, and they don't require a browser to be open all day long. The communication with the server is still standard Web 2.0, but Twitter developers have largely abandoned the idea that they need to muck around with HTML, and everyone's better for it.

For the last few years, tech pundits have repeatedly predicted that the browser will take over the space currently occupied by the operating system: via solutions like Google Gears or Prism, or a custom shell like gOS, you'll run everything over the network via HTML/JS/CSS. It's failed to happen so far, and it'll continue to fail. The closer the browser comes to "real" applications, as with GMail, the more its shortcomings become apparent, and the more developers have to rebuild basic functionality in a system that's just not meant to handle it.

If anything, the future is in the middle ground: a heavyweight, native or bytecode platform that can be run in a distributed fashion over the web, splitting application programming back out from the browser and providing a real API for developers to leverage. Such a format addresses the weaknesses of modern binary applications, such as heavy installation and slow startup, without abandoning the advantages that a real operating system provides. AIR, Silverlight, and XUL (as well as Java, to a much lesser extent) are possibilities that could achieve this. HTML, if we're lucky, is not.

May 28, 2008

Filed under: tech»web

Twitter and the New Protest

Like every hip young person online, I've gotten myself a twitter account. My initial impressions are that I don't particularly care for the terminology: followers? Was "watchers" not creepy or sheep-like enough?

Anyway, if you are also on Twitter, I'm open to invitations. Additionally, I'm looking for suggestions of people who are interesting or innovative users of the service. I don't think I'll be broadcasting very much at the moment, but I'm interested in how other people are getting value from it.

To some extent, this is leading up to a low-priority project I'm starting: as anyone who attended college with me knows, I've been fascinated for a long time by what I call "guerrilla rhetoric"--rarely during my undergraduate career could anyone get me to shut up about Otpor, for example. But during the last few years, thanks in part to mobile phones and a much more flexible set of web standards, we've started to see examples of smarter protest and resistance movements using information and communciation technology to coordinate or publicize their work.

I've realized that I don't know as much as I'd like to about these developments, which I find fascinating. So I'm going to start reading up on the subject much more thoroughly, starting with Gene Sharp's work on nonviolent protest. Also, I've set up a del.icio.us linkstream where I'm going to start tagging my online research--there's not much there yet, just the Youtube videos from Anonymous and some stuff I remember from B-SPAN--but if anyone runs into anything, I'd appreciate a heads-up. Eventually this might be a subject that I'd be interested in exploring through grad school (he gazed enviously at Berkeley's doctoral program in Rhetoric), but that's probably a few years off.

April 19, 2007

Filed under: tech»web

Gollum, Gollum

Dotster just sent out an e-mail saying that .es and .cn domains are now available. I'm always tempted, when informed about new domains, to register a bunch just in case. Now I'm trying to think of clever uses of the suffix. I can't think of any for .cn, but .es is a goldmine, assuming they're not already taken (www.mistak.es, sadly, has already been reserved).

Or maybe I just really want elvs.es and its subdomain, tricksy.elvs.es (hence the title, my preciousssss).

Future - Present - Past