Hacker News new | past | comments | ask | show | jobs | submit login
The Average Font (iotic.com)
481 points by daleharvey on Apr 23, 2012 | hide | past | web | favorite | 63 comments

What a wonderful adventure! My favorite of all the recent HN posts.

This is the true spirit of hacking:

> So, this stumped me for a while. I decided I needed to get to know fonts better, so I built a simple web app to view the lines, curves and control points present in the fonts I had. On this basis, I started to consider the ways the features (vertices, curves, stems, serifs etc) might be matched up between fonts. However, this was a rabbit hole I might never get to the bottom of - particularly when considering some of the more unusual varieties of font. Perhaps there was a simpler idea that was evading me.

Of course, now what I'd like to see is the source code to generate the "average" font on a different machine. It would be interesting (for me at least!) to see the average font from a font designer's machine - or someone who collects different monospaced fonts - or my own machine.

I suppose it's not so much "source code" as it is a bunch of manual steps - but would be interesting to know more about those steps, maybe even enough to repeat them.

His final solution (500 equidistant points per glyph) is very clever though visually, it results in putting unnecessary emphasis in areas of variability. For example, look at the bottom of uppercase 'Q' or the middle of lowercase 'f' - notice how it appears to be a thick knot instead of being the same width as the rest of the letter. This is most certainly because averaging the perimeter points ends up enlarging the enclosed area. The more darts you throw at a dartboard, the larger the area you will cover. While he mentions that he solved the issue of excess variability (lowercase 'g') by selecting a subset of similarly styled glyphs, I don't think he did anything to shrink the knots.

Off the top of my head, one thing that could help solve the knot problem is treat the serifs and sans-serifs as two different subsets and make two Average typefaces. Additionally, he could calculate 'average distance to X nearest points in reverse direction'. By that I mean, a point on a curve pointing down should look at all the points that point up (meaning they are on the other side of the filled polygon or hole), and find the 5-10 closest points and take the average. This could tell you how thick the line or hole is at that point. Then use this as the weight to come up with a weighted average of all the other parameters for each point.

All-in-all, this is a fantastic project and the weeks and months of independent research is time well spent. Hacking for fun is wonderful.

> treat the serifs and sans-serifs as two different subsets and make two Average typefaces.

Read all the way to the end - that's what he did.

Do you mean footnote 2?

I think they meant

Avería Serif Family (ZIP, 323kB) OFLB Avería Sans Family (ZIP, 320kB) OFLB

There are also slabs and semi-serifs. Additionally there are also rounded varieties of respective primary designs, so I think his solution is probably Ok. The resulting font is surprisingly good as is.

This is really interesting. I think the result is very attractive and readable. Yet it's also difficult to recall. It reminds me of a face built of averages (http://www.uni-regensburg.de/Fakultaeten/phil_Fak_II/Psychol...) - attractive, but somehow lacking in character.

Great work in any case.

> attractive, but lacking in character

Oddly enough (bringing us full-circle back to fonts) that was one of the key design parameters for the ubiquitous Helvetica, the intention being that the font itself has no character so simply carries the message of the content without imparting any extraneous "meaning" (i.e. the font was designed to be as much "function" and as little "form" as possible).

It should be possible to develop technology to describe "eigenfonts" and automatically average them. Also, there is technology that can in-between outlines with different numbers of points.

The best part of this post was the dawning realisation about 2/3 of the way through the page that an actual font resulted from the experiment, and the page was displayed in it.

It's a really attractive font, actually. Regular enough that it coheres as a font, but just irregular enough to evoke the output of old movable-type printing presses.

Aside from some unfortunate smudginess here and there the end result is surprisingly good. It reminds me of 17th century texts I've seen: fairly wide, by modern standards, spaces between individual characters, and rounded serifs.

If you want you one, Essays 1743: http://www.thibault.org/fonts/essays/

Here's an off-topic legal question:

Are you allowed to copy intellectual property like fonts, perform a function like averaging on the intellectual property, and distribute the result of the function performed on the intellectual property?

The USA offers no copyright protection whatsoever for typeface designs. The only thing that can be copyrighted is the outline data of a particular typeface file. Those are considered to be like a "program" for generating a specific output. If I like the design of a typeface, I can make one that looks just like it from scratch, and sell it.[1] There are more exotic ways to protect fonts, such as "design patents", but these are rarely used.

So, in this case, he analyzes the original outlines, and produces new outlines, and then produces a derivative work based on many such derived outlines. I think a judge would just laugh it out of court.

If not, I think it would probably fall under fair use in the USA, specifically the "amount and substantiality" clause. The most relevant precedent might be visual collages. [2]

But, I don't believe algorithmic averaging has ever been tested as a derivative work. Personally I'd argue that "average" artworks are more like facts about the world, but I doubt a judge would be sympathetic.

Jason Salavon started doing similar artworks with photos more than a decade ago, for instance in "Every Playboy Centerfold: the Decades"[3] and many artists have done similar things since then. I once asked him if he'd ever had any legal issues, since I was doing a similar experiment, but he never replied to that.

[1] http://nwalsh.com/comp.fonts/FAQ/cf_13.htm

[2] http://en.wikipedia.org/wiki/Collage#Legal_issues

[3] http://www.salavon.com/work/EveryPlayboyCenterfoldDecades/gr...

Are you allowed to read intellectual property, analyze it, and distribute your summary of the intellectual property?


As I understand it, a font is a bit special, copyright wise. You only need to change it in very minor details to call it a completeley new font. See Arial vs. Helvetica.

That's right, if I recall correctly. You can't copyright a font. You can rip off an existing font and create a new one that looks strikingly similar, even visually identical. However, if you do that by reverse-engineering the font (e.g. extract the bezier curve out of the TTF) then it is illegal. There is a court case where Adobe (?) sued some ripoff (and won), with the argument that while you cannot copyright the font, the "program" that implements the font is still copyrightable. IANAL and my wordings and details may not be 100% correct, so please feel free to correct me.

On the other hand, I wonder... if I take an existing font. Print it to a very high resolution PNG (not vector graphic so all Bezier curves are lost), and use some font creation software that recreate the font by doing an approximation... whether this is still consider a copyright infringement. Just curious...

On the contrary; change is the word you must avoid at all costs. Change almost implies that there also is an unchanged part, and that would run the risk of copyright infringement (if the remaining part is small, it might be fair use). What you can do is design a font that is extremely similar to an existing one. And that is different (unique?) for font designs; for instance, you would have a hard time getting away with designing a cartoon character from scratch that is extremely similar to Mickey Mouse.

AFAIK (and IANAL) the design of a font is not protected by copyright. Instead the actual font files are.

Arial isn't Helvetica tweaked. It's a fairly similar font squashed so that it's metrically compatible (i.e. you can swap one for the other and if you squint from a distance it'll mostly look the same as the characters have the same dimensions).

There's an interesting story behind Arial; it was developed as part of a PostScript clone back in the days of Adobe's tight control over the Type 1 specification. Microsoft then threw gasoline on the Arial fire by bundling it into Windows 3.1, purportedly to save licensing costs.


Usually the topic of fair use is rather subjective, and even the four guidelines (roughly: is it transformative? what's the nature of the work, is it for-profit or not? how much of the original is used?) are subject to interpretation. This, however, looks like a strong case of fair use.

I wonder what if you did that and refused to disclose which works you have chosen? (assuming you used something which has stronger copyright protections than fonts)

fair use I would say.

It's interesting to see how lower-case g is the only letter left that is commonly expressed in fonts two ways, single- and double-story; one flipped left and one right.

Looking at the first average rendering, you can see that it isn't clearly defined like all of the other letters. It also has two very different versions in the serif and sans-serif fonts linked at the bottom.

I wonder if one of the gs will eventually be lost, similar how it's so rare to see an "a" represented in a font as a single-story "ɑ".

If 'g' is single-story, how is 'a' not?

This is really incredible.

I would love to see a professional designer "clean these up" -- use the exact same dimensions and curves, but standardize the stroke widths, curves, etc.

Then I wonder -- would this become the most legible, anonymous font of all time? The serif version could be spectacular for body copy that lets the content speak for itself.

Also, I imagine this could be a fantastic font to "design on top of" -- by overlaying your own designs, you can immediately see what is most distinctive about your own design.

Bruce Mau uses similar techniques to create hybrid typefaces. See the signage and branding for the Walt Disney Concert Hall (http://www.brucemaudesign.com/4817/97310/work/walt-disney-co...), and work for Zone Books (http://www.zonebooks.org/titles/CRAR_ZO6.html, http://books.google.com/books?id=LCEjVBHQBMkC&pg=PA103&#...).

I'd also love to see this process done for collections of typefaces from the same period -- humanist, transitional, modern, grotesque, and so on...

So, by copyright law, isn't this a "derived work" of all of those fonts.


IANAL but according to Wikipedia[1], typeface (and rasterization of the typeface) is not copyrightable although the font file do:

> Under U.S. law, typefaces and the characters they contain are considered to be utilitarian objects whose utility outweighs any merit that may exist in protecting their creative elements. As such, typefaces are exempt from copyright protection in the United States. However, this finding was limited in Adobe Systems, Inc. v. Southern Software, Inc., wherein it was held that scalable computer fonts, i.e., the instructions necessary to render a typeface, constitute a "computer program" for the purposes of copyright law and hence are subject to protection. Hence the computer file(s) associated with a scalable font will generally be protected even though the specific design of the characters is not. Furthermore, a rasterized representation (e.g. bitmap) of the characters in a scalable font is not protected by copyright in the United States.

According to this, the author will have to create his font by directly modifying the original font file to make it a derived work. Since his font is created from rasterized representation, the resulting font file is not considered a derived work. But again, IANAL.

[1]: http://en.wikipedia.org/wiki/Intellectual_property_protectio...

Interesting, but by that reasoning, couldn't I legally copy any font (and have it legally be my own work) simply be rasterizing it at a sufficiently large size and then vectorizing the result?

That's more or less how contemporary font clones are made. Rasterize, use auto-tracing software to produce new font curves, done. You can't directly copy any embedded programs from the original, such as hinting or kerning code, though. Kerning often ends up being tweaked manually (though with enough samples you could infer it from the original output), and then for quick-n-dirty clones hinting is just left to your font engine's autohinting algorithms.

There's a bit of angst about this in typography forums, and social pressure among typophiles and some subset of designers to avoid using "ripoff" fonts.

It would be an interesting project, if nothing else simply as a statement about copyright, to write a program that automates this process and automatically rips a font file this way. By producing samples with characters placed at different fractional positions, you should even be able to infer the hinting information without directly reading it.

I wonder about that too, I tried to find such information regarding this but couldn't found any.

I made exactly the same comment hours ago. Instead of answering it got downvoted way into negative territory.

That's a shame. Often it's hard for people to hear any idea without thinking that the person who is presenting it is advocating it. Frankly, I don't know if you were or not, but I think it is an interesting idea and, to me, an indication of how bizarre copyright has become.

I think the results are really interesting, for my money it puts me in mind of very old style printed text due to the letter shaping. It immediately feels, well, 'familiar' due to the way it appears.

Not sure if I'd use it for a project, but it's interesting none the less.

Nice.. I had the same idea bored at work using canvas/js a while back (windows XP, so should work with windows versions..). Cool he followed through and made a font with it!


*edit : copied his idea and used baseline center

Isn't the resulting font a derived work of the ones that made it up, and hence not his to freely license?

This is why Hackers can do anything. I love this. It's surprisingly readable as body text

I don't know a lot about web design. Can someone explain to me how my browser rendered that page with the new Averiá font, even though I don't have this font installed? Can web pages include an external font library or something?

Yeah. There's two ways to do it, of which this page uses the latter:

- CSS3's new font-face extension, supported by newer browsers, allows specifying custom fonts to be loaded for a page

- Cufon, a JavaScript program which runs in your browser, can download and render the fonts, replacing each word with a generated image (works in some older browsers too)

I'm guessing this is why you can't select or copy/paste any of the text.

I'm able to select text and copy/paste. I'm using the latest Chrome beta.

Thank you! I'm learning a lot about fonts on HN today.

Cool that he took it to the extreme and actually created a font based on his results ('Averia': http://openfontlibrary.org/font/averia/ )

The 'o' in 'computer' at the start of the third line of that page seems a little taller than the other letters. Other than that, seems interesting. I'd prefer to see a sans-serif version, though.

Why do you think the author is using Cufon?

I noticed that too, maybe because he is expecting non-hackers to view it? Or was unaware of font-face?

This looks a lot like print in old books.

Inspired by the idea of the "average font", I whipped up a quick scramble suit bookmarklet:

    javascript:/*ScrableSuit*/var __slice=Array.prototype.slice;var __hasProp=Object.prototype.hasOwnProperty;var __bind=function(fn,me){return function(){return fn.apply(me,arguments)}};var __extends=function(child,parent){for(var key in parent){if(__hasProp.call(parent,key))child[key]=parent[key]}function ctor(){this.constructor=child}ctor.prototype=parent.prototype;child.prototype=new ctor;child.__super__=parent.prototype;return child};var __indexOf=Array.prototype.indexOf||function(item){for(var i=0,l=this.length;i<l;i++){if(this[i]===item)return i}return-1};(function(){var Detector=function(){var baseFonts=['monospace','sans-serif','serif'];var testString="mmmmmmmmmmlli";var testSize='72px';var h=document.getElementsByTagName("body")[0];var s=document.createElement("span");s.style.fontSize=testSize;s.innerHTML=testString;var defaultWidth={};var defaultHeight={};for(var index in baseFonts){s.style.fontFamily=baseFonts[index];h.appendChild(s);defaultWidth[baseFonts[index]]=s.offsetWidth;defaultHeight[baseFonts[index]]=s.offsetHeight;h.removeChild(s)}function detect(font){var detected=false;for(var index in baseFonts){s.style.fontFamily=font+','+baseFonts[index];h.appendChild(s);var matched=(s.offsetWidth!=defaultWidth[baseFonts[index]]||s.offsetHeight!=defaultHeight[baseFonts[index]]);if(matched&&s.offsetHeight-defaultHeight[baseFonts[index]]>20)matched=false;h.removeChild(s);detected=detected||matched}return detected}this.detect=detect};var detector,font,fontFamilies,letterTags,randomFont,scramble,traverseElement,_i,_len,_ref;letterTags=[];fontFamilies=[];detector=new Detector;detector.checkFont=function(font){if(this.detect(font)){return fontFamilies.push(font)}};_ref="serif\nAdobe Jenson\nAdobe Text\nAlbertus\nAldus\nAlexandria\nAlgerian\nAmerican Typewriter\nAntiqua\nArno\nAster\nAurora\nNews 706\nBaskerville\nBell\nBembo\nBembo Schoolbook\nBenguiat\nBerkeley Old Style\nBernhard Modern\nBodoni\nBauer Bodoni\nBook Antiqua\nBookman\nBordeaux Roman\nCalifornian FB\nCalisto\nCalvert\nCapitals\nCambria\nCartier\nCaslon\nWyld\nCaslon Antique\nFifteenth Century\nCatull\nCentaur\nCentury Old Style\nCentury Schoolbook\nNew Century Schoolbook\nCentury Schoolbook Infant\nChaparral\nCharis SIL\nCheltenham\nClarendon\nClearface\nCochin\nColonna\nComputer Modern\nConcrete Roman\nConstantia\nCooper Black\nCorona\nNews 705\nDejaVu Serif\nEcotype\nElephant\nEspy Serif\nExcelsior\nNews 702\nFairfield\nFF Scala\nFolkard\nFootlight\nFreeSerif\nFriz Quadrata\nGaramond\nGentium\nGeorgia\nGloucester\nGoudy Old Style\nGoudy\nGoudy Schoolbook\nGoudy Pro Font\nGranjon\nHeather\nHercules\nHigh Tower Text\nHiroshige\nHoefler Text\nHumana Serif\nImprint\nIonic No. 5\nNews 701\nJanson\nJenson\nJoanna\nKorinna\nLegacy Serif\nLexicon\nLiberation Serif\nLinux Libertine\nLiteraturnaya\nLucida Bright\nMelior\nMemphis\nMiller\nMinion\nModern\nMona Lisa\nMrs Eaves\nMS Serif\nNew York\nNimbus Roman\nNPS Rawlinson Roadway\nOCR A Exteneded\nPalatino\nBook Antiqua\nPerpetua\nPlantin\nPlantin Schoolbook\nPlaybill\nPoor Richard\nRawlinson Roadway\nRenault\nRequiem\nRockwell\nRoman\nRotis Serif\nSabon\nScala\nSeagull\nSistina\nSouvenir\nSTIX, see also XITS\nStone Informal\nStone Serif\nSylfaen\nTimes New Roman\nTimes\nTrajan\nTrinité\nTrump Mediaeval\nUtopia\nVale Type\nVera Serif\nVersailles\nWanted\nWeiss\nWide Latin\nWindsor\nXITS\nSlab serif\nApex\nCity\nCholla Slab\nEgyptienne\nGuardian Egyptian\nMuseo Slab\nRockwell\nNilland\nSans serif\nAbadi\nAgency FB\nAkzidenz Grotesk\nAptifer\nArial\nArial Unicode MS\nAvant Garde Gothic\nAvenir\nBank Gothic\nBarmeno\nBauhaus\nBell Centennial\nBell Gothic\nBenguiat Gothic\nBerlin Sans\nBeteckna\nBlue Highway\nCafeteria\nCalibri\nCentury Gothic\nCharcoal\nChicago\nClearface Gothic\nClearview\nCo Headline\nCo Text\nCorbel\nCoolvetica\nDax\nDejaVu Sans\nDotum\nDroid\nEcofont\nEras\nEspy Sans\nNu Sans\nEurocrat\nEurostile\nSquare 721\nFF Meta\nFF Scala Sans\nFlama\nFormata\nFreeSans\nFranklin Gothic\nFrutiger\nFrutiger Next\nFutura\nGeneva\nGill Sans\nGill Sans Schoolbook\nGotham\nHandel Gothic\nDenmark\nHaettenschweiler\nHelvetica\nHelvetica Neue\nSwiss 721\nHighway Gothic\nHiroshige Sans\nHobo\nImpact\nIndustria\nInterstate\nJohnston\nNew Johnston\nKabel\nLegacy Sans\nLiberation Sans\nLucida Sans\nMeiryo\nMicrogramma\nModern\nMotorway\nMS Sans Serif\nMuseo Sans\nMyriad\nNeutraface\nNews Gothic\nNimbus Sans L\nNina\nOptima\nParisine\nPricedown\nPrima Sans\nPT Sans\nRail Alphabet\nRevue\nRotis Sans\nScala Sans\nSegoe UI\nSkia\nSouvenir Gothic\nStone Sans\nSyntax\nTahoma\nTiresias\nTrade Gothic\nTransport\nTrebuchet\nTrump Gothic\nTw Cen\nTwentieth Century\nUbuntu\nUnivers\nZurich\nVera Sans\nVerdana\nVirtue\nSemi-serif\nAmsterdam Old Style\nDivona\nNyala\nPortobello\nRotis Semi Serif\nTema Cantante\nMonospaced\nAndale Mono\nArial Monospaced\nBitstream Vera\nConsolas\nCourier\nCourierHP\nCourier New\nCourierPS\nFontcraft Courier\nDejaVu Sans Mono\nDroid Sans Mono\nEverson Mono \nEverson Mono Unicode\nFedra Mono\nFixed\nFixedsys\nFixedsys Excelsior\nInconsolata\nHyperFont\nLetter Gothic\nLiberation Mono\nLucida Console\nLucida Sans Typewriter\nLucida Typewriter\nMICR\nMenlo\nMiriam Fixed\nMonaco\nMonofur\nMonospace\nMS Gothic\nMS Mincho\nNimbus Mono L\nOCR-A\nOCR-B\nOrator\nOrmaxx\nPragmataPro\nPrestige Elite also known as Prestige\nProFont\nProggy Programming Fonts\nSmall Fonts\nSydnie\nTerminal\nTerminus\nTex Gyre Cursor\nUM Typewriter\nUbuntu Mono\nVera Sans Mono\nWilliam Monospace\nBrush Scripts\nBalloon\nBrush Script\nDragonwick\nChoc\nDom Casual\nMistral\nPapyrus\nSegoe Script\nTempus Sans\nUtopia\nYear Supply of Fairy Cakes\nCalligraphic\nAmazone\nAMS Euler\nApple Chancery\nAquiline\nAristocrat\nBickley Script\nCivitype\nCodex\nEdwardian Script\nForte\nFrench Script\nKuenstler Script\nMonotype Corsiva\nOld English Text MT\nPalace Script\nPark Avenue\nScriptina\nShelley Volante\nVivaldi\nVladimir Script\nZapf Chancery\nZapfino\nHandwriting\nAndy\nAshley Script\nChalkboard\nComic Sans\nCézanne\nDom Casual\nFontoon\nJefferson\nKristen\nLucida Handwriting\nRage Italic\nRufscript\nScribble\nSoupbone\nTekton\nOther script\nCinderella\nCupola\nCurlz\nMagnificat\nScript\nStone Informal\nBlackletter\nAmerican Text\nCloister Black\nFraktur\nGoudy Text\nLucida Blackletter\nDingbat Symbol fonts\nApple Symbols\nBookshelf Symbol 7\nCambria Math\nCommercial Pi\nComputer Modern\nCorel\nHM Phonetic\nLucida Math\nMathematical Pi\nOpenSymbol\nSymbol\nSymbolPS\nWingdings\nWingdings 2\nWingdings 3\nWebdings\nZapf Dingbats\nDisplay Decorative fonts\nAbracadabra\nAd Lib\nAllegro\nAndreas\nArnold Böcklin\nAstur\nBalloon Pop Outlaw Black\nBanco\nBauhaus\nBeat\nBraggadocio\nBroadway\nCaslon Antique\nChiller\nCooper Black\nCurlz\nEllington\nExocet\nFIG Script\nForte\nGigi\nHarlow Solid\nHarrington\nHorizon\nJim Crow\nJokerman\nJuice\nLo-Type\nMagneto\nMegadeth\nNeuland\nPeignot\nSimulation Mimicry fonts\nBagel\nLithos\nPapyrus\nSkia\nMiscellaneous\n3x3\n8514oem\nAshley Inline\nBraggadocio\nContinuum Medium\nFixedsys\nGrasset\nKahana\nLED\nPythagoras\nSystem\nTema Cantante\nTerminal\nWestminster".split('\n');for(_i=0,_len=_ref.length;_i<_len;_i++){font=_ref[_i];detector.checkFont(font)}traverseElement=function(parent){var child,letter,text,_j,_k,_len1,_len2,_ref1,_ref2,_results,_results1;if((_ref1=parent.tagName)==='SCRIPT'){}else if(parent.childElementCount>0){_ref2=parent.children;_results=[];for(_j=0,_len1=_ref2.length;_j<_len1;_j++){child=_ref2[_j];_results.push(traverseElement(child))}return _results}else if(parent.innerText.length>0){text=parent.innerText;parent.innerHTML='';_results1=[];for(_k=0,_len2=text.length;_k<_len2;_k++){letter=text[_k];child=document.createElement('span');child.innerText=letter;child.style.fontSize=parent.style.fontSize;parent.appendChild(child);_results1.push(letterTags.push(child))}return _results1}};traverseElement(document.body);randomFont=function(){return fontFamilies[Math.floor((Math.random()*1000000)%fontFamilies.length)]};scramble=function(){var tag,_j,_len1,_results;_results=[];for(_j=0,_len1=letterTags.length;_j<_len1;_j++){tag=letterTags[_j];_results.push(tag.style.fontFamily=randomFont())}return _results};return setInterval(scramble,100)}).call(this);
This splits the whole page up into 1-character <span>s, and randomizes the font on each one every 100ms. The result is surprisingly readable-- and not at all guaranteed not to crash your browser, I don't recommend trying it on any page more complex than the HN frontpage.

Original CoffeeScript source: https://gist.github.com/2473373

Beautifully soft and living! Like reading old typesetting! Thank you!

Looks better small and large more so than around the 14px-17px range.

I really wish people would quit writing "whilst."

It's equivalent to "while" and wholly correct, only more popular in the United Kingdom.

Equivalent except that 'whilst' can't be used as a noun.

Argh!!! This is precisely the problem when you give developers a designers' problems. It is not possible to engineer your way around every problem.

In this specific case, the font is blurry, unattractive, and lacking any character. It looks like someone tried to autotraced a photocopied fax of a carbon copy.

It's an interesting experiment to be sure – but this is not, in anyway, a solution to … anything.


The author doesn't imply that it's attractive or useful, just that it's the average of all the fonts on this system. He even jokes that the name meaning "mechanical breakdown or damage" is somehow appropriate.

This is, in some ways, the solution to... visualizing the average of all the fonts on this system.

(Although, I think the result is attractive. Probably not very readable, or useful other than for some sort of logotype. Almost makes me think of letters made out of the balls in world of goo.)

I think it's pretty.

Someone failed art class.

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact