<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;CkcNRX0yfip7ImA9WhBQGEQ.&quot;"><id>tag:blogger.com,1999:blog-15626356</id><updated>2013-03-21T11:21:34.396-07:00</updated><category term="ruby" /><category term="FireEagle" /><category term="emacs" /><category term="geocoding" /><category term="tools" /><category term="javascript" /><category term="AES" /><category term="CSS" /><category term="Google Maps API" /><category term="geomapping" /><category term="books" /><category term="Google Spreadsheets" /><category term="perl" /><category term="Opera" /><category term="SVG" /><category term="github" /><category term="bookmarks" /><category term="firefox extensions" /><category term="BOM" /><category term="getters" /><category term="OpenID" /><category term="EditGrid" /><category term="Greasemonkey" /><category term="chrome extensions" /><category term="Firefox" /><category term="Firebug" /><category term="opera extensions" /><category term="Chrome" /><category term="Exhibit" /><category term="extension" /><category term="reference" /><category term="mac" /><category term="xpath" /><category term="HTML" /><category term="design" /><category term="standards" /><category term="MD5" /><category term="JSON" /><category term="Google Gears" /><category term="user script" /><category term="Time zones" /><category term="google" /><title>ecmanaut</title><subtitle type="html">Webby thoughts, most about around interesting applications of ecmascript in relation to other open web standards. I live in Mountain View, California, and spend some of my spare time co-maintaining Greasemonkey together with Anthony Lieuallen.</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://ecmanaut.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://ecmanaut.blogspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/15626356/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Johan Sundström</name><uri>http://www.blogger.com/profile/04076097346172610543</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>250</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/blogspot/xxBcs" /><feedburner:info uri="blogspot/xxbcs" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;CUQHSHY7fyp7ImA9WhBSF04.&quot;"><id>tag:blogger.com,1999:blog-15626356.post-1591203835913406460</id><published>2013-02-21T05:27:00.000-08:00</published><updated>2013-02-24T11:15:39.807-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-02-24T11:15:39.807-08:00</app:edited><title>GroupOn</title><content type="html">&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2406 1059" width="520" height="229"&gt;
 &lt;path fill="#bcbec0" opacity=".2" stroke="#636466" stroke-width="6" d="m3 3h2400v815l-2223 238z"/&gt;
 &lt;linearGradient id="johan-grad-1" gradientUnits="userSpaceOnUse" x1="1135" x2="1313" y1="-364" y2="683"&gt;
  &lt;stop stop-color="#545757"/&gt;
  &lt;stop stop-color="#1f2323" offset="1"/&gt;
 &lt;/linearGradient&gt;
 &lt;path fill="url(#johan-grad-1)" d="m2337 758-2102 225-153-914 2255 1z"/&gt;
 &lt;path fill="#fff" opacity=".3" d="m116 643-108-637 855 1-859-4z"/&gt;
 &lt;linearGradient id="johan-grad-2" gradientUnits="userSpaceOnUse" x2="0" y1="297" y2="585"&gt;
  &lt;stop stop-color="#fff"/&gt;
  &lt;stop stop-color="#dcddde" offset="1"/&gt;
 &lt;/linearGradient&gt;
 &lt;g fill="url(#johan-grad-2)" stroke="#fff" stroke-width="2" transform="translate(241 281)"&gt;
  &lt;path d="m361 6 h 78 v 156 c 0 27 1 54 -2 76 c -3 23 -13 38 -27 51 c -13 12 -31 22 -52 26 c -23 5 -48 2 -68 -5 c -37 -14 -60 -45 -60 -96 h 83 c 1 12 2 23 8 30 c 7 8 27 7 33 -2 c 8 -11 6 -34 6 -54 v -181 c 0 0 0 -1 0 -1 z"/&gt;
  &lt;path d="m644 2a158 158 0 0 0 0 316 158 158 0 0 0 0-316m0 75a83 83 0 0 1 0 166 83 83 0 0 1 0-166"/&gt;
  &lt;path d="m847 6h78v115h100v-115h78v307h-78v-122h-100v122h-78"/&gt;
  &lt;path d="m 1259 6 h 61 c 41 102 81 204 122 306 c -28 1 -57 0 -85 0 c -5 -15 -10 -29 -15 -44 h -106 c -6 14 -11 30 -16 44 h -83 c 0 -2 1 -3 1 -5 c 40 -100 81 -201 121 -301 c 0 -1 0 -1 1 -1 z m 30 96 c 0 0 0 0 0 0 c -11 35 -21 70 -31 105 h 64"/&gt;
  &lt;path d="m1665 310l-116-173v173h-73v-304h66l114 172v-172h73v304z"/&gt;
 &lt;/g&gt;
&lt;/svg&gt;
&lt;br /&gt;
&lt;p&gt;&lt;a href="http://www.crunchbase.com/company/britely"&gt;My startup&lt;/a&gt; got acquired by GroupOn (where I shall be used for Good, not Evil :-).&lt;/p&gt;
&lt;p&gt;I started this Monday. So far, it is a little disorienting to work in what is best described as a huge confederation of startups. It should hopefully get better once chipping away at stuff to chip away at making stuff better.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/xxBcs/~4/nOJYHtja3QY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://ecmanaut.blogspot.com/feeds/1591203835913406460/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=15626356&amp;postID=1591203835913406460" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/15626356/posts/default/1591203835913406460?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/15626356/posts/default/1591203835913406460?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/xxBcs/~3/nOJYHtja3QY/groupon.html" title="GroupOn" /><author><name>Johan Sundström</name><uri>http://www.blogger.com/profile/04076097346172610543</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://ecmanaut.blogspot.com/2013/02/groupon.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DU4CQ3o9cSp7ImA9WhNbFEQ.&quot;"><id>tag:blogger.com,1999:blog-15626356.post-2915988919807237403</id><published>2013-01-18T00:32:00.001-08:00</published><updated>2013-01-18T00:32:42.469-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-01-18T00:32:42.469-08:00</app:edited><title>Beliefs as Era Indicators</title><content type="html">&lt;div class="separator" style="float: left;"&gt;
&lt;a href="http://upload.wikimedia.org/wikipedia/commons/1/1a/William_Ford_Gibson.jpg" imageanchor="1" style="margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://upload.wikimedia.org/wikipedia/commons/1/1a/William_Ford_Gibson.jpg" width="232" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;blockquote class="tr_bq"&gt;
&lt;a href="http://en.wikiquote.org/wiki/William_Gibson"&gt;The future is already here — it's just not very evenly distributed.&lt;/a&gt;&lt;/blockquote&gt;
A common Gibson quote, but have you reflected on how many levels it applies to? It is not just about technology, for instance – which might be a typical first understanding of the message. Let me portray how it applies to beliefs, and how it may be an even more useful picture to carry in your mind.&lt;br /&gt;
&lt;br /&gt;
If you were to travel back in time to the renaissance, Terminator style, not a thread on your body, you would be from the future. But almost nothing about you would set you apart much from anyone else of the era – your strange dialect and manneurisms, relative lack of calluses from not having done much as manual labour goes – but nothing that would place you in another time, rather than from some other place – except what is in your head.&lt;br /&gt;
&lt;br /&gt;
All sorts of things you believe (and more importantly &lt;i&gt;don't&lt;/i&gt; believe) set you apart as a member of a different age. &lt;i&gt;Some&lt;/i&gt; living in those days share &lt;i&gt;some&lt;/i&gt; of your beliefs about how the solar system is arranged, for instance (the future was unevenly distributed back then, too, after all), but most don't, and would find you a strange eccentric full of funny made-up ideas, uneducated about how things &lt;i&gt;are&lt;/i&gt;. You would probably find that it makes it easier to live peacefully by not insisting on convincing others about what you know and hold as true, and find people laughing at or dismissing you much less, the less you do, and the more you just blend in with the beliefs of the era. Getting on with life just takes precedence over distributing your ideas across the population of the era.&lt;br /&gt;
&lt;br /&gt;
It is nice to live peacefully; most people probably prefer it, both then and now. And much like what you would behave like, to live in the past, most people we ever meet in life&amp;nbsp;behave,&amp;nbsp;today, rather than taking every opportunity to challenge other people's beliefs you know or have reason to believe different from yours. And consequentially, we live in a patchwork of partially overlapping belief worlds, medieval to far future, every moment of every day of our lives – much more than we would see in technology, say.&lt;br /&gt;
&lt;br /&gt;
Discovering, exposing yourself to new beliefs (especially the high-impact&amp;nbsp;core beliefs that affect your perception of yourself and the world), and challenging and upgrading those you currently hold, is the quickest way from now to the future. It always has been, whatever time you live in. Since the future is not evenly distributed, your future is one different from everybody else's, so you can zoom right past all your peers without anyone even knowing or noticing. Many of the people you meet daily in life live in places you will never set foot in, both having solutions and problems of times long gone, times yet to come, or futures you will never reach, as seen from your own time line.&lt;br /&gt;
&lt;br /&gt;
While one might assume that most of our beliefs about ourselves and the world are derived from facts, they are generally not. More typically, they are based on other beliefs instilled by social upbringing and education, our perceptions or best guesses about experiences we have had and made – and very rarely subjected to any rigorous challenges. If I ask you how many senses you have, chances are very large you might come up with the number five without even for the briefest moment considering to make an inventory of your biosensory inputs – because someone taught you that, at some point. You would not challenge me if I remarked that you have a very good sense of balance stemming from an ingenious set of tubes in your inner ear, because this belief is a piece of trivia that is about &lt;i&gt;language&lt;/i&gt; – a (today) dated agreement about what constitutes a &lt;i&gt;sense&lt;/i&gt;, in the English language's traditional classification of nouns – not because you believe that your body lacks this sensory equipment. But unchallenged, it might never have occurred to you that this number five is a piece of random inherited baloney that we keep passing on to coming generations. Many – or hopefully most – of our beliefs are replaceable like this, when we realize they are incorrect, incomplete, irrelevant, just unhelpful, or worse, downright deceptive.&lt;br /&gt;
&lt;br /&gt;
When people talk about life-long learning, I think they mostly talk about new skill sets, and rarely new beliefs. I used to think of it that way, before pondering what things I have learned over the last decade of the greatest worth to me as a human, in my everyday life. While some of that is certainly life skills like&amp;nbsp;love&amp;nbsp;languages and how-to type knowledge, most of it are things like a revised understanding of nutrition, that sugar is a drug, high-fructose corn syrup (the main ingredient of soft drinks and typical candy) is technically a kind of poison and how they affect me and my perceptions of the world when ingested, how clothes confine&amp;nbsp;and isolate&amp;nbsp;people both from themselves and each other, notions about how to assess and change what I believe and why, the importance of being wrong, in order to discover what is right – and many, many more. Picking up new skill sets, in terms of life impact, rank way down on the scale, by comparison.&lt;br /&gt;
&lt;br /&gt;
Love and respect your teachers, and listen with indulgent curiosity to people expressing opinions you don't believe in. Because, apart from your imagination, that is your best source for new useful beliefs. And if you are more extrovert-wired, it may be the richer source of the two. And don't just listen for the substance of it, ask why and try to understand, as best you can, the motivations behind them, when it is better than "because someone told them". All learning worth having should come with explanations, and conversely, suspect all knowledge you hold that you can't derive from something. When you can't derive why something is true, you will rarely realize when that knowledge expires because of changes in the world, new discoveries and technologies with consequences to the old knowledge.&lt;br /&gt;
&lt;br /&gt;
I do not rank myself a great teacher, in part from having little patience to pick gentle language or stick mostly to neutral ground, which are great skills I appreciate in people I do rank as such. My own style of communication is largely weaned among slightly autist-leaning programmers that charge at things passionately and pick and choose selectively from what is flung around, narrowing in on beliefs via what proves useful, while rarely or never interchanging belief with identity. The best are often wrong, and often change their mind, as soon as they discover they were wrong, and in such a culture, charging on strongly and having people point out your errors when spotted narrows in on better ideas far quicker than stepping lightly and covering your trail in qualifiers and disclaimers. While strongly conflict averse myself, I find merit in this efficient way of&amp;nbsp;prestige-less&amp;nbsp;shortcuts to arrive at better truths, and will note that it immediately breaks down out of context, if applied in contexts where skins are less thick, people more married to their beliefs and less selective about their take-aways.&lt;br /&gt;
&lt;br /&gt;
If I note as one of my relative-future beliefs that I observe to be ill distributed around me (surveying my nearest grocery store's dairy section is more than enough data needed for that) that "light" products, for the most part, substitute healthy fat (that play a part in some pleasant&amp;nbsp;sought-after&amp;nbsp;taste or texture) with unhealthy processed sweeteners trying to replicate the same, to keep up with beliefs about fat that shot to the sky after some spectacularly bad science in the early 1980s, and causing more problems than they solve, I may be dispensing useful data, but not particularly good teaching. If I link to &lt;a href="http://www.youtube.com/watch?v=BhwLBKPtXG4"&gt;Robert Lustig talking about the same&lt;/a&gt;, I am somewhat better, but still not very good: I have not particularly rigged you to be interested in the subject, and chances are slim that his explanations seek you out at a time you are interested in them.&lt;br /&gt;&lt;br /&gt;Especially as my motives for raising the example is mostly to self-indulgently lament living in a future, steeped in a contemporary medieval world not yet based on said future. When, one or a few generations from now, everybody believing in today's common notion about dieting and counting non-qualified carbs, and everybody passing on such beliefs to future generations – once they have all died out, my future will likely slowly get more evenly distributed, but until then, I can only nurse, co-create and choose local clusters of future in a sea of past. The more you live in the future, the more everything that surrounds you is all locked in the past.&lt;br /&gt;
&lt;br /&gt;
While my tone may deceivingly marry "future" with value judgments as "good" and "past" as "bad", my intent is more in line with "more useful" and "less useful", to myself and other members of that world. You are more adapted to your surrounding era by holding its beliefs, however unaware of what might be incremental or radical improvements to its status quo by believing otherwise. I am fortunate to live in a time, with a mentality and income where, upon discovering that I don't see clearly as far as others, and diagnosing the cause as astigmatism, I could patch my lenses via some LASIK surgery in 2012, instead of changing my behaviour and wearing external optical patchwork every day of the rest of my life. Many either don't have that option, or worse, have, but never find out, even if they would have chosen it and been successful attempting it.&lt;br /&gt;
&lt;br /&gt;
The core point I have made above is that beliefs, more than most things, define who we are, what we do and what comes out of it, how we feel about ourselves, what paths we choose, what we aspire to, worry about, avoid, and why; whom we share what with and when, and that we are at choice about them to the extent we choose, and never more. They can be pliable or rigid, set in stone or actively eager to get replaced, iterated, and superseded. And they exist in a multidimensional soup of other beliefs, most unreflected upon by those holding on to them. Some are benign, many illicitly planted, some detected, many not. Lots of beliefs are comforting but disastrous, like denying climate change, choosing a set seeming to incur less responsibility. Some are chosen to have an easier time coping – and sometimes believing falsehoods can help you live with a higher quality of life than you would have with a greater awareness, if knowing makes you brood or get plagued by guilt.&lt;br /&gt;
&lt;br /&gt;
Life is a set of choices, but choices are downstream from beliefs. Upstreams from beliefs are whatever processes of multiplication and elimination you instill. Make them good ones. Live long, and prosper! :)&lt;img src="http://feeds.feedburner.com/~r/blogspot/xxBcs/~4/-Hjsiug3dCI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://ecmanaut.blogspot.com/feeds/2915988919807237403/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=15626356&amp;postID=2915988919807237403" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/15626356/posts/default/2915988919807237403?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/15626356/posts/default/2915988919807237403?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/xxBcs/~3/-Hjsiug3dCI/beliefs-as-era-indicators.html" title="Beliefs as Era Indicators" /><author><name>Johan Sundström</name><uri>http://www.blogger.com/profile/04076097346172610543</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://ecmanaut.blogspot.com/2013/01/beliefs-as-era-indicators.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUEDSH0-eyp7ImA9WhNUEU0.&quot;"><id>tag:blogger.com,1999:blog-15626356.post-4900535136963887943</id><published>2013-01-01T21:13:00.003-08:00</published><updated>2013-01-01T21:14:39.353-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-01-01T21:14:39.353-08:00</app:edited><title>iOS app search engine definitions</title><content type="html">To have chrome search for iOS apps from the url bar by typing "iapp app-name", add a search engine definition (Command-, type "search", click "Manage search engines", scroll to the bottom of the list and add a new entry) like this one:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;iOS apps     iapp     https://www.google.com/search?q=inurl%3Ahttps%3A%2F%2Fitunes.apple.com%2F&lt;u&gt;&lt;b&gt;us&lt;/b&gt;&lt;/u&gt;%2Fapp%2F%20%s&lt;/pre&gt;
&lt;br /&gt;
(after tweaking "&lt;b&gt;&lt;u&gt;us&lt;/u&gt;&lt;/b&gt;" to whatever country code your apps come from)&lt;br /&gt;
&lt;br /&gt;
It would be neat if the iOS app store had its own search page somewhere on the web so we didn't have to rely on Google's rather poor rendition of the search results, but I haven't found one.&lt;br /&gt;
&lt;br /&gt;
The more &lt;a href="http://json.org/"&gt;json&lt;/a&gt; minded of you might also add an accompanying "iappjs" version, for the heck of it:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;/pre&gt;
&lt;pre&gt;iOS apps json     iappjs     https://itunes.apple.com/search?country=us&amp;amp;media=software&amp;amp;limit=200&amp;amp;term=%s&lt;/pre&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;img src="http://feeds.feedburner.com/~r/blogspot/xxBcs/~4/M4Dj8gUlvBc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://ecmanaut.blogspot.com/feeds/4900535136963887943/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=15626356&amp;postID=4900535136963887943" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/15626356/posts/default/4900535136963887943?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/15626356/posts/default/4900535136963887943?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/xxBcs/~3/M4Dj8gUlvBc/ios-app-search-engine-definitions.html" title="iOS app search engine definitions" /><author><name>Johan Sundström</name><uri>http://www.blogger.com/profile/04076097346172610543</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://ecmanaut.blogspot.com/2013/01/ios-app-search-engine-definitions.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D08ERn08fSp7ImA9WhNVGUo.&quot;"><id>tag:blogger.com,1999:blog-15626356.post-8185718831827899084</id><published>2012-12-31T09:43:00.002-08:00</published><updated>2012-12-31T09:43:27.375-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-12-31T09:43:27.375-08:00</app:edited><title>Surprise is data</title><content type="html">&lt;div&gt;
One of the best ways to leverage subconscious data about myself, my experiences, assumptions and otherwise, is to notice and write down what I get surprised about – especially when traveling, or in&amp;nbsp;changing circumstances in&amp;nbsp;any other capacity.&amp;nbsp;I am fairly certain this idea comes from one of &lt;a href="http://paulgraham.com/articles.html"&gt;Paul Graham's essays&lt;/a&gt;&amp;nbsp;(though I &lt;a href="https://twitter.com/ecmanaut/status/281976811871666176"&gt;couldn't find which&lt;/a&gt;&amp;nbsp;– if you know, do say, and I'll link it; it's a great read).&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
I was visiting family in Sweden over Christmas, and what surprised me the most during those ten days, was how wonderfully quiet it is in over there. In a way this is old news to me, as the reverse was by far the biggest surprise about moving to the US three years ago – everything everywhere pollutes the audio spectrum with ambient noise. It is not just the traffic, but air-conditioning, refrigerators, dish-washers, washing machines, dryers, computers, and all the senseless amounts of &lt;i&gt;intentional&lt;/i&gt; noise that trains make, music playing everywhere in places of commerce, and so on. Being surrounded by it for so long, I have apparently become so steeped in the noise that my body equates it with an omni-present tax on human well-being. As quality of life goes, I much prefer paying Sweden's tax rate over this sensory tax.&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
It's a difference in engineering culture: in Sweden, low (or ideally no) noise emissions is an important and expected fitness criterion, for everything – and has been for at least two decades, probably more. Noise levels are one of the data points listed&amp;nbsp;(in dB(A)), when buying a new fridge or dish-washer, the governmental institution Arbetsmiljöverket (loosely translated "the work agency") offers a free&amp;nbsp;&lt;a href="https://itunes.apple.com/en/app/buller/id418022274?mt=8"&gt;iPhone&lt;/a&gt;&amp;nbsp;/ &lt;a href="https://play.google.com/store/apps/details?id=se.av.buller"&gt;Android&lt;/a&gt; app for measuring ambient noise, and both in the large (architecture, work place environment, city planning, et cetera) and small (tools, implements), fighting noise is not just a matter of engineering pride or regulations, but also pretty much taken for granted.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
In the US, it often feels like the noise aspect is a built-in proof that something is working properly, rather than the opposite. In the eighties, you could learn to hear that your C64 basic program was operating correctly via resonance frequencies from the CPU that&amp;nbsp;leaked out through the loudspeaker (due to improperly grounded circuits, I presume), and any car mechanic worth their salt can tell a lot about a car by the sounds it makes.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
I am surprised so little has changed here since those days.&lt;/div&gt;
&lt;img src="http://feeds.feedburner.com/~r/blogspot/xxBcs/~4/-dVrO1fOPvs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://ecmanaut.blogspot.com/feeds/8185718831827899084/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=15626356&amp;postID=8185718831827899084" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/15626356/posts/default/8185718831827899084?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/15626356/posts/default/8185718831827899084?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/xxBcs/~3/-dVrO1fOPvs/surprise-is-data.html" title="Surprise is data" /><author><name>Johan Sundström</name><uri>http://www.blogger.com/profile/04076097346172610543</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://ecmanaut.blogspot.com/2012/12/surprise-is-data.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0AAQXg_cSp7ImA9WhNQGUg.&quot;"><id>tag:blogger.com,1999:blog-15626356.post-5628980612511868908</id><published>2012-11-25T18:16:00.002-08:00</published><updated>2012-11-26T10:49:00.649-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-11-26T10:49:00.649-08:00</app:edited><title>View rendered source bookmarklet</title><content type="html">&lt;p&gt;I haven't made a bookmarklet from scratch in a long while, but after looking at &lt;a href="http://codepen.io/johan/pen/KLIeE"&gt;this codepen&lt;/a&gt; I wrote a while ago to demonstrate copying one javascript document into another, it occurred to me that it could easily become a modern "view rendered source" bookmarklet, that might even work on iOS devices and the like, where a view source feature is sorely missing.&lt;/p&gt;

&lt;p&gt;Here is the result: &lt;tt&gt;&lt;a href="javascript:(function()%7Bvar%20d%3Ddocument%2Cb%3Dd.body%2Co%3Db.style.overflow%2Ch%3D(new%20XMLSerializer).serializeToString(d)%2Cf%3Db.insertBefore(d.createElement('iframe')%2Cb.firstChild)%2CF%3Df.contentDocument%2Cs%3Dd.implementation.createHTMLDocument('')%3Bf.style.cssText%3D'z-index%3A2147483647%3Bdisplay%3Ablock%3Bopacity%3A1%3Bvisibility%3Avisible%3Bbackground%3A%23fff%3Bcolor%3A%23000%3Bposition%3Afixed%3Bheight%3A100%25%3Bwidth%3A100%25%3Bpadding%3A0%3Bborder%3A0%3Bmargin%3A0%3Bleft%3A0%3Btop%3A0'%3Bs.open()%3Bs.write('%3C!DOCTYPE%3E%3Chtml%3E%3Cpre%3E'%2Bh.replace(%2F%26%2Fg%2C'%26amp%3B').replace(%2F%3C%2Fg%2C'%26lt%3B')%2B'%3C%2Fpre%3E%3C%2Fhtml%3E')%3Bs.close()%3BF.replaceChild(F.importNode(s.documentElement%2C!0)%2CF.documentElement)%3Bb.style.overflow%3D'hidden'%3BF.onclick%3Dfunction()%7Bb.style.overflow%3Do%3Bb.removeChild(f)%3Bd%3Db%3Dh%3Df%3DF%3Df%3Ds%3D0%7D%7D)()"&gt;view rendered source&lt;/a&gt;&lt;/tt&gt;&lt;/p&gt;

&lt;p&gt;On clicking it, you get a "view source" iframe with the source of the current document, in whichever state it was when you clicked the button, and when you click (or tap) that it goes away again.&lt;/p&gt;

&lt;p&gt;I have yet to try it on an iDevice myself, but I have high hopes. To my surprise, manually entered bookmarklets like this one refuse to run in a modern Safari, though smaller ones that load their js payload over the wire instead seem to work, so I might make a gist of the code too, if that is what it takes.&lt;/p&gt;

&lt;p&gt;Enjoy!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/xxBcs/~4/k9BhJAvNkF0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://ecmanaut.blogspot.com/feeds/5628980612511868908/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=15626356&amp;postID=5628980612511868908" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/15626356/posts/default/5628980612511868908?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/15626356/posts/default/5628980612511868908?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/xxBcs/~3/k9BhJAvNkF0/view-rendered-source-bookmarklet.html" title="View rendered source bookmarklet" /><author><name>Johan Sundström</name><uri>http://www.blogger.com/profile/04076097346172610543</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://ecmanaut.blogspot.com/2012/11/view-rendered-source-bookmarklet.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEIMSXk7eSp7ImA9WhNTFk0.&quot;"><id>tag:blogger.com,1999:blog-15626356.post-8534217281455741511</id><published>2012-10-18T17:28:00.000-07:00</published><updated>2012-10-18T17:29:48.701-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-10-18T17:29:48.701-07:00</app:edited><title>Absolute url from a relative url and base_url</title><content type="html">&lt;p&gt;Today I needed a javascript url resolver to get absolute urls for urls mentioned in css files - resolved against the url of the stylesheet, not the current page. Fortunately, your browser already implements this natively, it's just not exposed in DOM APIs, so it needs a little DOM cleverness to coax out the functionality:&lt;/p&gt;

&lt;script src="https://gist.github.com/3915545.js"&gt;&lt;/script&gt;&lt;noscript&gt;&lt;pre&gt;function resolveURL(url, base_url) {
  var doc      = document
    , old_base = doc.getElementsByTagName('base')[0]
    , old_href = old_base &amp;&amp; old_base.href
    , doc_head = doc.head || doc.getElementsByTagName('head')[0]
    , our_base = old_base || doc_head.appendChild(doc.createElement('base'))
    , resolver = doc.createElement('a')
    , resolved_url
    ;
  our_base.href = base_url;
  resolver.href = url;
  resolved_url  = resolver.href; // browser magic at work here

  if (old_base) old_base.href = old_href;
  else doc_head.removeChild(our_base);

  return resolved_url;
}&lt;/pre&gt;&lt;/noscript&gt;

&lt;p&gt;You can play around with it a little here, to see that your browser supports it, too. You should even be able to use a relative URL as the &lt;code&gt;base_url&lt;/code&gt; parameter, which should get resolved against the page url -- which here is the jsfiddle url shown, as that demo is running in an embedded iframe, rather than on this blog itself:&lt;/p&gt;

&lt;iframe style="width: 100%; height: 180px" src="http://jsfiddle.net/ecmanaut/RHdnZ/embedded/result/" allowfullscreen="allowfullscreen" frameborder="0"&gt;&lt;/iframe&gt;

&lt;p&gt;It of course won't work in node.js, but hopefully it'll be useful to something you or &lt;a href="http://stackoverflow.com/a/12965135/1130377"&gt;others&lt;/a&gt; are doing, too. Use as you like; it's all public domain / MIT licensed goodness, whichever you fancy.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/xxBcs/~4/69EHR1TxvIg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://ecmanaut.blogspot.com/feeds/8534217281455741511/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=15626356&amp;postID=8534217281455741511" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/15626356/posts/default/8534217281455741511?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/15626356/posts/default/8534217281455741511?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/xxBcs/~3/69EHR1TxvIg/absolute-url-from-relative-url-and.html" title="Absolute url from a relative url and base_url" /><author><name>Johan Sundström</name><uri>http://www.blogger.com/profile/04076097346172610543</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://ecmanaut.blogspot.com/2012/10/absolute-url-from-relative-url-and.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUIFSHg-fSp7ImA9WhJSFUU.&quot;"><id>tag:blogger.com,1999:blog-15626356.post-8992525785597882185</id><published>2012-07-06T08:11:00.000-07:00</published><updated>2012-07-06T08:11:59.655-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-07-06T08:11:59.655-07:00</app:edited><title>Facebook and the Human Mind</title><content type="html">I am seeing more of Facebook these days, from an indirect angle, lending a point of view on the phenomenon that lets me observe the behaviour it is driving in its subjects at large, rather than participating, and observing the behaviours &lt;i&gt;I&lt;/i&gt; exhibit. &lt;span class="footnote"&gt;The latter is both significantly more challenging, due to perception bias, and a microscopically smaller data point, to a sea of data backdrop.&lt;/span&gt;&lt;br&gt;
&lt;br&gt;
Facebook has created a niche where its inputs are humans (expressing human behaviour) and where its outputs are &lt;i&gt;massive&lt;/i&gt; amounts of highly measurable data about said humans, and all the ways they affect, relate to and interconnect with each other, and other entities of the world. Both that data, and the behaviours that end up amassing the data, are highly profitable -- and exponentially more so, the larger its body of subjects. But let's look closer and deeper at the human behaviours it promotes, where it gets interesting:&lt;br&gt;
&lt;br&gt;
I think I see the fundamental component of life itself, as it applies to behaviour: any behaviour which increases the likelihood of recreating itself, increases the rate of repeating itself, and increases the accuracy of the reproduction of itself, is (from a natural selection point of view,) more &lt;i&gt;fit&lt;/i&gt;. Whenever this mechanism randomly shows up in nature (which only needs to happen once in a universe, as the seed mutates, and down the line reproduces the incredible wealth of complexity some unironically like to call "creation"), we call it &lt;i&gt;Life&lt;/i&gt;&lt;!--, and far downstream of it, things like sentience has developed in humans--&gt;. This behaviour, then, is a form of life that lives, reproduces and mutates in humans, a second order life form Richard Dawkins and others call memes. And Facebook operates as an incubation chamber for this life form and its hosts, a catalyst of the set of behaviours that drive the reaction. Facebook is an echo-chamber for memes -- creating, spreading and remixing memetic life, provisioning it with an ever increasing body of fertile human minds to live (and evolve) in.&lt;br&gt;
&lt;br&gt;
Let me establish some vocabulary to help clarify this post: a &lt;i&gt;Facebook operator&lt;/i&gt;, as I use the word in this post, refers neither to any Facebook employee or direct partner, but to anyone using Facebook's behaviour measurement tools monitoring what transpires in the system, what type of stimulus (under what circumstances) is how successful at driving engagement. I believe these tools are available to anyone creating or owning a Facebook Page, but otherwise for the most part invisible to everyday users of the Facebook medium itself. For reuse of already established Facebookian language, where I write "activity", you may think "meme", if you so prefer, or a Facebook Page post of some sort, be it a video, picture, link, or just a piece of text, as this is their chosen granularity of measurement / reporting.&lt;br&gt;
&lt;br&gt;
What a Facebook operator sees is essentially how successful they are at producing and catalyzing user behaviour that spreads, as expressed by per-activity virality and reach factors, measuring reproduction rate (fecundity), number of subjects (how many humans an activity got exposed to), and on aggregate what shape those flows took; if it funneled through a few people that caused large multiplication factors, or through a large number of people that each produced a tiny multiplication factor, say.&lt;br&gt;
&lt;br&gt;
Philosophically, I find the emerging picture telling a story of our culture's present state, and future direction, as the phenomenon seems strongly self-reinforcing. The story I see emerging behind and throughout the data is to drive humans to addictive-compulsory behaviour in general, and the dopamine cycle of attention-deficit disorder in particular. Dopamine is released in response to an action as a biochemical reward. Facebook, in a substantial way, operates like an enormous (human-focused) &lt;a href="http://en.wikipedia.org/wiki/Operant_conditioning_chamber"&gt;Skinner box&lt;/a&gt;, set on tightening the dopamine hit cycle, optimizing that loop to tighten it as much as possible, and delivering as successful stimulus as possible -- where the measure of success is to what extent each activity creates a dopamine blip in the body of people they get exposed to and to what extent they then choose to pass it on to their peers.&lt;br&gt;
&lt;br&gt;
This phenomenon is not isolated to Facebook in particular, they just happen to be at its leading edge. I am sure Google Plus, Twitter and others in this field very much want to do the same, but just don't yet have (or expose) the same refined measurement tools to its operators.&lt;br&gt;
&lt;br&gt;
We should not be surprised that Facebook, a company embracing "The Hacker Way" at its core, is first to deliver on this at scale; more than any profession I know, hackers embrace and understand the mechanics of tight cycles, and optimizing your development cycle (by adopting whatever tools, processes and mechanisms you can create, imagine, or buy for money, that shortens or streamlines it), and how massively it pays off in rate of progress. In Facebook's case, I see them doing the same to the smallest unit of activity in their Skinner box, and outsourcing the optimization to any external, willing, self-interested entity which helps them turn a profit for free. (Google is attempting to do the same to the web at large via Google Analytics, for that matter, but have a substantially lower degree of control, and higher granularity of measure.)&lt;br&gt;
&lt;br&gt;
I am less interested in (and would kindly discourage any comments to that effect) all sorts of judgmental aspects, condemning Facebook (or any other entity) or similar for its role in this. Facebook, Twitter, Google Plus and others are, for better or worse, a replacement for the mainstream media journalism of the past, and in all the above I believe I have outlined the same mechanisms it has been rehashing over the decades it has existed, only at a much higher pace, due to the now far tighter and more highly instrumented cycle. The tabloid genes that thrived in their old, leakier Skinner box, is thriving and evolving in and to this shiny new Skinner box and shows up in all its most pre-digested forms, following laws of least-common-denominatorialist journalism, largest-emotional-impact journalism and similar -- all far more attuned to impact-on-subject than any other measurement of fitness or higher order utility such as whether the content serves its recipient in some way, informing them, making them happier, or more successful, as opposed to just more entertained and engaged with the medium.&lt;br&gt;
&lt;br&gt;
I believe it's important to realize that it's somewhat useless to moralize over what transpires in the system or what people "ought" to be doing instead with their time, or what operators ought to be broadcasting into other people's spans of attention, as what we see emerge here is just a mirror image of what behaviours the human mind is conditioned for and dutifully reproduces, as evolution taught her, and which served her well in the few hundred thousand years to date, in the kind of circumstances she lived under throughout most of that period.&lt;br&gt;
&lt;br&gt;
More usefully, I think, is to think of how we choose to expose ourselves to these kinds of tools, knowing that we are humans with very similar biological underlying programming, and to assess what values we derive from their use, how much and in what formats, under which circumstances and in which company (online, here) we subject ourselves to these media. Especially, you might benefit from thinking of it as you would a recreational drug, as its impact on you at a biochemical level is similar, as implemented by your biological hardware and social software.&lt;br&gt;
&lt;br&gt;
And, much like our judgment is impaired by drugs and we do things that we at the time don't see the consequences of, down the line, our use of these online social systems, to varying (but substantial) degrees hides the future impact of our actions from us, as the visibility of our actions is multiplied million-fold from what they used to be in the pre-internet days of humanity, from which we still draw most of our genes and behaviours. Especially as this activity data trickles to places your typical drunken stupor was safely insulated from just a decade ago, and as power centers wielding all sorts of control over our lives, have started taking an interest in this data haven, and what bits of trivia about us they may draw upon to influence decisions concerning us. This is entirely invisible today, where we used to have at least the semblance of control in the age when the people we saw around us, were a decent hint to the reach of what transpired at any point in time.&lt;br&gt;
&lt;br&gt;
Mind your step, be wary of what values you derive from what you invest your time and attention in, and maybe occasionally stop for a moment to think about how you prefer to engage your mind and connect with yourself, other humans and the world of thoughts and ideas. You get to choose all of the above, as long as you actually do choose, as opposed to following your unthinking hard-wired programming.&lt;img src="http://feeds.feedburner.com/~r/blogspot/xxBcs/~4/h9qJAeXnsag" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://ecmanaut.blogspot.com/feeds/8992525785597882185/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=15626356&amp;postID=8992525785597882185" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/15626356/posts/default/8992525785597882185?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/15626356/posts/default/8992525785597882185?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/xxBcs/~3/h9qJAeXnsag/facebook-and-human-mind.html" title="Facebook and the Human Mind" /><author><name>Johan Sundström</name><uri>http://www.blogger.com/profile/04076097346172610543</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://ecmanaut.blogspot.com/2012/07/facebook-and-human-mind.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DU8NRHs7cSp7ImA9WhJTFUU.&quot;"><id>tag:blogger.com,1999:blog-15626356.post-2751895250433404290</id><published>2012-06-24T18:28:00.000-07:00</published><updated>2012-06-24T18:31:35.509-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-06-24T18:31:35.509-07:00</app:edited><title>Github TV ad</title><content type="html">&lt;p&gt;This is a transcript
of the Github TV ad.
If you haven't seen it,
think "Apple commercial",
Jonathan Ive's dreamy narrative,
British accent,
the whole jive,
and you'll have it
about right.
Okay, you're set;
cue soft music:&lt;/p&gt;

&lt;blockquote&gt;Here at Github,
we like to fork
the best ideas in the valley
and spin them a little different.
You might not have heard about
&lt;a href="//www.github.org/"&gt;our philantropic branch&lt;/a&gt;
(because we don't like to brag),
but it's actually the secret
behind some of our
most groundbreaking new innovations.&lt;/blockquote&gt;

&lt;blockquote&gt;&lt;a href="//biolabs.github.org/"&gt;Github Biolabs&lt;/a&gt;
is how Tom Preston-Werner,
in late 2007
and before we were even founded,
re-imagined Google's "20% time".
We started Github
as an incubator,
here at the
&lt;a href="http://mad-science.sf.gov/"&gt;San Francisco
asylum for mad scientists&lt;/a&gt;,
and
&lt;a href="https://speakerdeck.com/u/matthewmccullough"&gt;some&lt;/a&gt;
&lt;a href="https://speakerdeck.com/u/holman"&gt;of&lt;/a&gt;
&lt;a href="https://speakerdeck.com/u/schacon"&gt;our&lt;/a&gt;
&lt;a href="https://speakerdeck.com/u/kneath"&gt;most&lt;/a&gt;
&lt;a href="https://speakerdeck.com/u/jina"&gt;brilliant&lt;/a&gt;
&lt;a href="https://speakerdeck.com/u/jnunemaker"&gt;employees&lt;/a&gt;
began their career
doing 20% time with us,
as a precursor to their
first parole leave.
None has left us yet.&lt;/blockquote&gt;

&lt;p&gt;[Cut to a person
lying in the grass
under a huge tree
wearing a light visor,
skimming through
and tweaking its genome
via Minority Report style gestures.
Chromosomes fly by
in the air above,
zooming in and out,
as she unfolds, marks, cuts, re-folds, pans,
pulls, merges, rebases, pushes
and splices sequences into the tree.
She is wicked fast.]&lt;/p&gt;

&lt;blockquote&gt;&lt;a href="//github.com/images/modules/about_page/hubbernauts.jpg"
&gt;At Github Biolabs&lt;/a&gt;,
we have four saps on tap,
an expansive green-house,
and a
&lt;a href="//arboretum.github.org/"&gt;beautiful arboretum&lt;/a&gt;.
It is here that our scientists,
using recombinant DNA splicing techniques,
in this social open source setting,
literally Create New Apples.&lt;/blockquote&gt;

&lt;p&gt;[Cut back to narrator,
taking a bite out of one.
Fade to white. Fade to logo:]&lt;/p&gt;

&lt;svg width="520" height="353" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 10000 4419"&gt;
 &lt;defs&gt;&lt;font horiz-adv-x="535"&gt;
  &lt;font-face font-family="Futura Heavy" panose-1="2 11 9 2 2 2 4 2 2 3" ascent="1002" descent="-264" units-per-em="1000" alphabetic="0"/&gt;
  &lt;glyph unicode=" " horiz-adv-x="289"/&gt;
  &lt;glyph unicode="S" horiz-adv-x="526" d="m409 588q-21 29-48 45t-65 17q-18 0-34-6t-29-18-21-27-8-34q0-32 22-51t55-34 72-31 72-42 56-66 22-103q0-57-17-104t-49-81-78-54-104-19q-78 0-135 40t-97 107l95 93q7-22 20-42t32-35 39-24 45-9q22 0 40 9t31 24 19 34 7 42q0 29-12 49t-31 33-42 23-46 18q-36 15-67 32t-53 42-35 56-13 76q0 47 16 88t46 72 70 48 88 18q25 0 54-6t57-17 53-26 42-35l-69-102"/&gt;
  &lt;glyph unicode="O" horiz-adv-x="782" d="m764 378q0-83-26-155t-74-127-118-85-155-31q-86 0-155 31t-117 85-75 126-26 156q0 84 26 156t76 126 118 83 153 31q84 0 153-30t118-84 75-125 27-157zm-152 6q0 46-15 90t-43 78-70 56-93 21q-52 0-93-21t-69-55-44-79-15-90q0-44 11-89t38-84 69-62 103-24q61 0 103 24t68 62 38 83 12 90"/&gt;
  &lt;glyph unicode="C" horiz-adv-x="601" d="m558 554q-31 38-74 59t-92 21q-53 0-94-22t-69-59-44-83-15-96q0-48 15-93t44-81 70-58 92-22q48 0 92 22t75 58v-175q-42-20-83-32t-88-13q-80 0-147 32t-117 85-77 125-28 149q0 80 27 153t76 128 117 89 152 33q45 0 87-11t81-33"/&gt;
  &lt;glyph unicode="I" horiz-adv-x="254" d="m201 0h-147v754h147"/&gt;
  &lt;glyph unicode="A" horiz-adv-x="676" d="m208 159l-62-159h-155l294 774h114l286-774h-157l-58 159h-262zm127 394h-2l-83-274h179l-94 274"/&gt;
  &lt;glyph unicode="L" horiz-adv-x="402" d="m201 128h208v-128h-355v754h147"/&gt;
  &lt;glyph unicode="D" horiz-adv-x="646" d="m54 754h210q82 0 149-29t115-79 74-120 26-150q0-80-27-148t-75-119-115-80-148-29h-209v754zm147-626h24q68 0 115 18t78 50 44 79 14 102q0 124-62 186t-189 63h-24"/&gt;
  &lt;glyph unicode="N" horiz-adv-x="759" d="m54 774h106l397-527h2v507h147v-769h-106l-397 527h-2v-512h-147"/&gt;
  &lt;glyph unicode="G" horiz-adv-x="739" d="m720 401v-19q0-80-20-152t-63-128-107-89-153-33q-83 0-149 32t-113 87-72 125-25 150q0 81 26 153t74 127 116 87 152 33q97 0 175-46t123-134l-130-70q-23 51-68 85t-104 35q-53 0-93-24t-66-64-40-87-13-95q0-47 13-94t40-85 67-61 93-24q34 0 65 14t54 37 38 55 15 65h-160v120"/&gt;
  &lt;hkern u1="C" u2="O" k="6"/&gt;
 &lt;/font&gt;&lt;/defs&gt;
 &lt;g class="collegiate-regular"&gt;
  &lt;path d="m1281 1189c155 0 334-39 537-116v498c-45 16-110 34-193 53 26 74 39 143 39 208 0 206-62 386-186 539s-285 244-481 273c-129 19-193 89-193 208 0 42 21 84 63 126 55 61 135 100 242 116 461 71 691 263 691 575 0 500-298 749-894 749-245 0-447-44-604-131-200-109-300-282-300-517 0-271 150-456 450-556v-10c-110-68-164-171-164-310 0-181 52-293 155-338v-10c-103-35-195-116-276-242-90-135-135-281-135-435 0-232 82-426 247-580 158-145 347-218 566-218 158 0 305 39 440 116zm19 2543c0-164-135-247-406-247-261 0-392 85-392 256 0 168 142 251 426 251 248 0 372-87 372-261zm-745-1857c0 222 102 334 305 334 197 0 295-113 295-339 0-94-23-174-68-242-55-74-131-111-227-111-203 0-305 119-305 358"/&gt;
  &lt;circle cx="2331" cy="360" r="360"/&gt;
  &lt;path d="m2055 3244c6-65 10-174 10-329v-1504c0-152-3-256-10-314h546c-7 61-10 163-10 305v1484c0 164 3 284 10 358"/&gt;
  &lt;path d="m3602 1098h421v469c-16 0-46-2-90-5s-85-5-123-5h-208v899c0 216 71 324 213 324 100 0 190-27 271-82v484c-119 65-263 97-430 97-235 0-398-84-488-251-68-126-102-324-102-595v-865h5v-10l-73-5c-42 0-97 5-164 15v-469h237v-189c0-90-5-163-15-218h561c-10 61-15 131-15 208"/&gt;
  &lt;path d="m5300 1083c-139 0-284 48-435 145v-846c0-184 3-305 10-363h-551c10 52 15 172 15 363v2558c0 148-5 250-15 305h561c0-10-3-49-10-118-6-69-10-131-10-186v-1189c113-106 222-160 329-160 123 0 216 61 280 184 48 97 73 218 73 363l-5 653c0 110-8 261-24 455h585c-13-81-19-229-19-445v-662c0-280-63-519-189-716-142-226-340-339-594-339"/&gt;
  &lt;path d="m7012 3264c-255 0-443-113-566-339-97-184-145-424-145-720v-662c0-219-6-367-19-445h580c-10 71-16 222-19 455l-5 653c0 184 21 316 63 396 48 100 137 150 266 150 90 0 192-53 305-160v-1189c0-55-3-118-10-189s-10-110-10-116h561c-6 55-10 156-10 305v1480c0 190 3 311 10 363h-527v-174c-148 129-306 193-474 193"/&gt;
  &lt;path d="m9188 3259c-174 0-319-63-435-189v174h-513c10-55 15-156 15-305v-2558c0-190-5-311-15-363h551c-7 58-10 179-10 363v841c148-94 293-140 435-140 255 0 455 113 600 339 122 197 184 435 184 716 0 287-65 537-193 749-155 248-362 372-619 372zm-73-1668c-106 0-218 53-334 160v836c103 100 205 150 305 150 126 0 221-69 285-208 52-110 77-240 77-392 0-364-111-546-334-546"/&gt;
 &lt;/g&gt;
 &lt;text x="1984" y="4352" font-family="Futura Heavy" font-size="1096"&gt;SOCIAL CODING&lt;/text&gt;
&lt;/svg&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/xxBcs/~4/vV2WX6R-Qm8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://ecmanaut.blogspot.com/feeds/2751895250433404290/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=15626356&amp;postID=2751895250433404290" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/15626356/posts/default/2751895250433404290?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/15626356/posts/default/2751895250433404290?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/xxBcs/~3/vV2WX6R-Qm8/github-tv-ad.html" title="Github TV ad" /><author><name>Johan Sundström</name><uri>http://www.blogger.com/profile/04076097346172610543</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://ecmanaut.blogspot.com/2012/06/github-tv-ad.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUYARX4_cCp7ImA9WhdbEEQ.&quot;"><id>tag:blogger.com,1999:blog-15626356.post-7720472903000055531</id><published>2011-10-08T09:42:00.000-07:00</published><updated>2011-10-08T09:59:04.048-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-08T09:59:04.048-07:00</app:edited><title>Death and IE</title><content type="html">This post is a brief celebration of succession on the web. Not Mosaic begat Netscape begat Mozilla begat Firefox succession, but Firefox 4 begat Firefox 5 begat Firefox 6 begat Firefox 7 and Chrome N begate Chrome N+1 type succession. Google got it right with Chrome last decade, and not long thereafter, &lt;a href="http://blog.mozilla.com/webdev/2011/10/05/stay-hungry-stay-foolish/"&gt;Mozilla got it too&lt;/a&gt; this year.&lt;br /&gt;
&lt;br /&gt;
Quoting that post's quote of Steve Jobs' &lt;a href="http://www.youtube.com/watch?v=UF8uR6Z6KLc"&gt;2005 Stanford commencement address&lt;/a&gt; (worth watching, if you haven't),&lt;br /&gt;
&lt;blockquote&gt;Death is very likely the single best invention of Life. It is Life’s change agent. It clears out the old to make way for the new. Right now the new is you, but someday not too long from now, you will gradually become the old and be cleared away.&lt;/blockquote&gt;&lt;br /&gt;
This very strongly applies to web browsers, and as it turns out, the best thing a browser version can do (besides getting things right in the first place) is dying even more quickly than it came. I wonder if this enlightened insight might have sprung with Mozilla, if only Firefox could have kept its inaugural name, &lt;a href="http://en.wikipedia.org/wiki/History_of_Firefox#Naming"&gt;Phoenix&lt;/a&gt;, which it now fully embodies, but at least now, this gift has finally been given to web developers: &lt;br /&gt;
&lt;blockquote&gt;You need not bother writing applications (or perfecting layouts) to high-fidelity for old browsers, for their time is short and their better ancestors replace them quickly.&lt;/blockquote&gt;&lt;br /&gt;
Assuming your deployment domain is web pages. As browser add-ons go, if you still maintain one of the old style XPI design your work burden has shot through the roof instead, unless you have near zero UI footprint, happen to only need and use APIs that time proves to remain stable and host it on addons.mozilla.org, where they bump its maxVersion every few weeks for you when it still seems to work. Failing either, you have to manually update and test it seven times per year. In Chrome, this has premeditatedly been addressed by not promiscuously offering any APIs it can't support in the long run, at the cost of limiting how much add-ons can do. Firefox, in this regard, remains the only browser where add-on authors can innovate 100% of the browser, and in this regard it has filled an important need in the browser eco-system (and still does). It is both its greatest feature and its greatest burden. Hopefully this will be mitigated to some extent with Jetpack and the new add-on builder.&lt;br /&gt;
&lt;br /&gt;
Returning to the paramount topic of graceful, benevolent, rapid-evolution-supportive death, &lt;a href="http://paulirish.com/2011/browser-market-pollution-iex-is-the-new-ie6/"&gt;Microsoft's IE&lt;/a&gt; &lt;a href="http://geddesign.com/post/10775181893/microsofts-golden-ticket-ie10"&gt;does not yet get it&lt;/a&gt;. Like a third world nation befallen by sudden prosperity, it has doubled its reproduction rate while keeping its mortality rate constant. As noted in mentioned posts, this does not bring just better browsers faster, it brings over-population, and makes web development unsustainable. Or, as Paul Irish put it in the first post: it pollutes the browser market.&lt;br /&gt;
&lt;br /&gt;
In this respect, the conditional comments and many "backwards compatibility simulation" modes IE bring you are not mainly tools helping web developers make sites work on Internet Explorer, but a huge extra burden of work forced onto web developers, to cope with IE's broken release process. This is Microsoft's job, not ours, and we should be outraged with them for forcing it on us.&lt;br /&gt;
&lt;br /&gt;
It is not the rotting corpses of IE6, IE7, IE8 or IE9 that all need to die to give space to IE10, which still smells fresh, it is a broken release process that needs to get addressed and brought up to date with best browser practices of the decade. It is the reinvention of sudden death, not just the gift of new life, that must come to Redmond, too. I applaud the IE team for making it their business to get up to speed with the web's evolution, but it's less the whats than the hows that are important to get right now. SVG is great, but sort out the release process before taking on, say, webGL. It can wait. Fixing the world's hard problems like over-population is harder than running after the latest ooo-shiny! - but the alternative is systemic collapse.&lt;br /&gt;
&lt;br /&gt;
For a browser, it is better to live a great but short life and go out with a boom, than it is to burden its extended family with a never-ending old age in an insufferable early-set rigor mortis. However you feel about &lt;a href="http://www.apple.com/stevejobs/"&gt;Steve Jobs&lt;/a&gt; he lived and died in this way, never holding back, never growing stale of mind nor action, and the world was better off for it.&lt;img src="http://feeds.feedburner.com/~r/blogspot/xxBcs/~4/2GoClqf9ZPk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://ecmanaut.blogspot.com/feeds/7720472903000055531/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=15626356&amp;postID=7720472903000055531" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/15626356/posts/default/7720472903000055531?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/15626356/posts/default/7720472903000055531?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/xxBcs/~3/2GoClqf9ZPk/death-and-ie.html" title="Death and IE" /><author><name>Johan Sundström</name><uri>http://www.blogger.com/profile/04076097346172610543</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://ecmanaut.blogspot.com/2011/10/death-and-ie.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0QMQHg6fip7ImA9WhdUE08.&quot;"><id>tag:blogger.com,1999:blog-15626356.post-4621964446376871143</id><published>2011-09-29T12:36:00.000-07:00</published><updated>2011-09-29T12:43:01.616-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-09-29T12:43:01.616-07:00</app:edited><title>Running an old rails 2.3.8 with rvm</title><content type="html">I was helping set up a local (legacy) rails 2.3.8 server on a macbook today, autonomous from the system ruby installation. This was a bit messy, as modern versions of rubygems conflict with the old rails 2.3.8 environment to the tune of:&lt;br /&gt;
&lt;pre&gt;Uninitialized constant ActiveSupport::Dependencies::Mutex (NameError)&lt;/pre&gt;...when you try to start the server. Here's the recipe I came up with: &lt;ol&gt;&lt;li&gt;&lt;a href="http://beginrescueend.com/rvm/install/"&gt;Install rvm.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;pre&gt;&lt;code&gt;# Install ruby 1.8.7 and downgrade its rubygems to 1.5.3:
rvm install 1.8.7 &amp;amp;&amp;amp; \
  rvm use 1.8.7 &amp;amp;&amp;amp; \
  rvm gem install -v 1.4.2 rubygems-update &amp;amp;&amp;amp; \
  rvm gem update --system 1.4.2 &amp;amp;&amp;amp; \
  update_rubygems &amp;amp;&amp;amp; \
  echo 'Okay.'&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;pre&gt;&lt;code&gt;# Install all the gems you need, for instance:
rvm gem install -v 2.3.8 rails &amp;amp;&amp;amp; \
  rvm gem install -v 3.0 haml &amp;amp;&amp;amp; \
  rvm gem install -v 2.1 authlogic &amp;amp;&amp;amp; \
  rvm gem install -v 1.0 dalli &amp;amp;&amp;amp; \
  rvm gem install -v 0.2 omniauth &amp;amp;&amp;amp; \
  rvm gem install -v 2.7.0 erubis &amp;amp;&amp;amp; \
  rvm gem install -v 1.3.3 sqlite3 &amp;amp;&amp;amp; \
  echo 'Gems installed!'&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;If needed, run &lt;code&gt;rake db:setup&lt;/code&gt; in your rails tree to set up its databases.&lt;/li&gt;
&lt;li&gt;Done! &lt;code&gt;rails/script/server -p &lt;i&gt;your_port&lt;/i&gt;&lt;/code&gt; is ready for action.&lt;/li&gt;
&lt;/ol&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/xxBcs/~4/obhIe_AJxYA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://ecmanaut.blogspot.com/feeds/4621964446376871143/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=15626356&amp;postID=4621964446376871143" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/15626356/posts/default/4621964446376871143?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/15626356/posts/default/4621964446376871143?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/xxBcs/~3/obhIe_AJxYA/running-old-rails-238-with-rvm.html" title="Running an old rails 2.3.8 with rvm" /><author><name>Johan Sundström</name><uri>http://www.blogger.com/profile/04076097346172610543</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://ecmanaut.blogspot.com/2011/09/running-old-rails-238-with-rvm.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUQGQn4yfCp7ImA9WhdTEEo.&quot;"><id>tag:blogger.com,1999:blog-15626356.post-1635257323003270877</id><published>2011-07-05T23:46:00.000-07:00</published><updated>2011-07-07T14:15:23.094-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-07-07T14:15:23.094-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="user script" /><category scheme="http://www.blogger.com/atom/ns#" term="SVG" /><category scheme="http://www.blogger.com/atom/ns#" term="github" /><title>Optimized SVGs at gist.github.com</title><content type="html">Lately, I've been having a lot of fun hand optimizing SVG files for size, a bit like &lt;a href="http://intertwingly.net/"&gt;Sam Ruby&lt;/a&gt; does for his blog (it is highly instructive peeking at &lt;a href="http://intertwingly.net/svg/"&gt;his collection&lt;/a&gt;, as I think I have mentioned before). &lt;br /&gt;
&lt;br /&gt;
For me, SVG has something of the magical flair I first found in HTML in the nineties, back when it was the new bleeding edge New Thing, but I argue that it's even more fun than HTML was. The &lt;a href="http://www.w3.org/TR/SVG/"&gt;W3C SVG specs&lt;/a&gt; are not prohibitively difficult to read, and of course you have much greater graphical freedom than structured documents can afford you (duh!).&lt;br /&gt;
&lt;br /&gt;
Like Sam, I try for something presentable in a kilobyte or less (uncompressed, though modern good browsers are as happy to render SVG:s delivered with &lt;code&gt;content-encoding: gzip&lt;/code&gt;, of course, as long as they are otherwise correct and delivered with an &lt;code&gt;image/svg&lt;/code&gt; or &lt;code&gt;image/svg+xml&lt;/code&gt; content-type), and to never enforce a fix width in the svg tag itself – so they just beautifully grow to any size you want them to be, with no loss of quality.&lt;br /&gt;
&lt;br /&gt;
Which is the other main beauty of SVG, besides being fly-weight, standardized, widely supported and still growing broader support in all the main-stream browsers. Over the last few years, the SVG front has been progressing happily and now is very practically useful already, for at least those of us that care most about Chrome, Firefox and Opera (I get the perception that Opera's often rather exceptional lead on the SVG support front is largely or even solely the work of &lt;a href="http://my.opera.com/MacDev_ed/blog/"&gt;Erik Dahlström&lt;/a&gt;, but I might exaggerate a bit).&lt;br /&gt;
&lt;br /&gt;
&lt;svg style="float:left; width:360px; height:320px; margin:0 0.5em 0.5em 0" viewBox="-160 -160 360 320" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"&gt;&lt;path id="f" d="m123,0a123,123 0,0 1-246,0a123,123 0,0 1 246,0"/&gt;&lt;g fill="#057"&gt;&lt;circle r="160"/&gt;&lt;circle r="150" fill="#fff"/&gt;[&lt;text font-size="28" font-stretch="condensed" font-family="Impact"&gt;&lt;animatetransform type="rotate" from="360 0 0" to="0 0 0" dur="10s" attributeName="transform" repeatCount="indefinite"/&gt;&lt;textpath xlink:href="#f"&gt;I thought what I'd do was, I'd pretend I was one of those deaf-mutes&lt;/textPath&gt;&lt;/text&gt;] (&amp;lt;- this is text content in an inline SVG, if your browser or reader has stripped off the SVG or can't render such modernisms :-) &lt;circle r="115"/&gt;&lt;circle r="95" fill="#fff"/&gt;&lt;path d="m-8-119h16 l2,5h-20z"/&gt;&lt;circle cx="160" cy="0" r="40"/&gt;&lt;path d="m-95-20v-20h255a40,40 0,0 1 0,80h-55v-20z"/&gt;&lt;path d="m-85 0a85,85 0,0 0 170,0h-20a65,65 0,0 1-130,0z"/&gt;&lt;path d="m-65 20v20h140v-20z"/&gt;&lt;path d="m-115-20v10h25v30h250a20,20 0,0 0 0,-40z" fill="#fff"/&gt;&lt;path d="m-20 10c-17-14-27-14-44 0 6-25 37-25 44 0z"/&gt;&lt;path d="m60 10c-17-14-27-14-44 0 6-25 37-25 44 0z"/&gt;&lt;/g&gt;&lt;/svg&gt; Anyway, this weekend, I had fun turning the Laughing Man (from &lt;a href="http://en.wikipedia.org/wiki/Ghost_in_the_Shell:_Stand_Alone_Complex"&gt;Ghost in the Shell: Stand Alone Complex&lt;/a&gt;) that &lt;a href="http://www.ta-sa.org/projects/laughing_man_logo.html"&gt;@elmex&lt;/a&gt; vectorized at some point, into a 1000 byte version of my own, also featuring the gentle rotating text seen in the anime series (&lt;a href="http://www.youtube.com/watch?v=4nw9hooeZ_I"&gt;YouTube&lt;/a&gt;), via declarative animation (so there is no javascript involved here).&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Edit:&lt;/b&gt; I initially missed an excellent opportunity here to plug Jeff Schiller's &lt;a href="http://codedread.com/scour"&gt;scour&lt;/a&gt;, which is an ideal first step when you start from an SVG source file. Be sure to run with -p something-large, as its defaults are being lossy about precision, which cuts needed decimals from some input files. With -p 99 you'll be on the safe side. Experiment with low single-digit numbers if you like (the current default – 5 – is often good), but make sure things are still looking right, or you may just ruin your file, rather than optimizing it for tiny foot-print. Broken images don't get extra credit for also being small!&lt;br /&gt;
&lt;br /&gt;
The result is in &lt;a href="https://gist.github.com/1066590"&gt;this gist&lt;/a&gt; (if you install &lt;a href="https://github.com/johan/github-improved/raw/master/gist-svg.user.js"&gt;this user script&lt;/a&gt;, you can swap between &lt;code&gt;*.svg&lt;/code&gt; text/plain source code image/svg rendition) or to the left, if your browser renders inline SVG:s properly in HTML content (I recommend the gist over view source, as Blogger inserts linebreak HTML tags unless I strip out all newlines first).&lt;br /&gt;
&lt;br /&gt;
What surprised me, when I made this user script, is how far standards support has come in modern browsers: in order to inject the &lt;code&gt;&amp;lt;svg&amp;gt;&lt;/code&gt; tag I create for the rendered version, I had to feed the source through &lt;code&gt;DOMParser&lt;/code&gt; (as setting &lt;code&gt;.innerHTML&lt;/code&gt; is lossy from treating the SVG content as &lt;code&gt;text/html&lt;/code&gt;, not &lt;code&gt;text/xml&lt;/code&gt;), and the few lines doing that, just magically worked in all of Chrome, Firefox 4 and Opera 11 (de-jQuery:fied, to make more sense outside of the script's context) with no special extra effort on my part:&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;// turn the raw SVG source string into an XML document:
svg = (new DOMParser).parseFromString(svg, 'text/xml');

// import it into an SVGSVGElement in this document:
svg = document.importNode(svg.documentElement, true);

// and insert that element somewhere in the document:
document.body.appendChild(svg);&lt;/code&gt;&lt;/pre&gt;To me, that's a rather clear sign SVG is ready for prime time now.&lt;br /&gt;
&lt;br /&gt;
&lt;svg style="width:160px; height:160px; float:left; margin:0 0.5em 0.5em 0" xmlns="http://www.w3.org/2000/svg" viewBox="-0.2 -1 379 334"&gt;&lt;path id="puddle" fill="#9CDAF1" d="m296.94 295.43c0 20.533-47.56 37.176-106.22 37.176-58.67 0-106.23-16.643-106.23-37.176s47.558-37.18 106.23-37.18c58.66 0 106.22 16.65 106.22 37.18z"/&gt;&lt;g id="shadow-legs" fill="#7DBBE6"&gt;&lt;path d="m161.85 331.22v-26.5c0-3.422-.619-6.284-1.653-8.701 6.853 5.322 7.316 18.695 7.316 18.695v17.004c6.166.481 12.534.773 19.053.861l-.172-16.92c-.944-23.13-20.769-25.961-20.769-25.961-7.245-1.645-7.137 1.991-6.409 4.34-7.108-12.122-26.158-10.556-26.158-10.556-6.611 2.357-.475 6.607-.475 6.607 10.387 3.775 11.33 15.105 11.33 15.105v23.622c5.72.98 11.71 1.79 17.94 2.4z"/&gt;&lt;path d="m245.4 283.48s-19.053-1.566-26.16 10.559c.728-2.35.839-5.989-6.408-4.343 0 0-19.824 2.832-20.768 25.961l-.174 16.946c6.509-.025 12.876-.254 19.054-.671v-17.219s.465-13.373 7.316-18.695c-1.034 2.417-1.653 5.278-1.653 8.701v26.775c6.214-.544 12.211-1.279 17.937-2.188v-24.113s.944-11.33 11.33-15.105c0-.01 6.13-4.26-.48-6.62z"/&gt;&lt;/g&gt;&lt;path id="cat" d="m378.18 141.32l.28-1.389c-31.162-6.231-63.141-6.294-82.487-5.49 3.178-11.451 4.134-24.627 4.134-39.32 0-21.073-7.917-37.931-20.77-50.759 2.246-7.25 5.246-23.351-2.996-43.963 0 0-14.541-4.617-47.431 17.396-12.884-3.22-26.596-4.81-40.328-4.81-15.109 0-30.376 1.924-44.615 5.83-33.94-23.154-48.923-18.411-48.923-18.411-9.78 24.457-3.733 42.566-1.896 47.063-11.495 12.406-18.513 28.243-18.513 47.659 0 14.658 1.669 27.808 5.745 39.237-19.511-.71-50.323-.437-80.373 5.572l.276 1.389c30.231-6.046 61.237-6.256 80.629-5.522.898 2.366 1.899 4.661 3.021 6.879-19.177.618-51.922 3.062-83.303 11.915l.387 1.36c31.629-8.918 64.658-11.301 83.649-11.882 11.458 21.358 34.048 35.152 74.236 39.484-5.704 3.833-11.523 10.349-13.881 21.374-7.773 3.718-32.379 12.793-47.142-12.599 0 0-8.264-15.109-24.082-16.292 0 0-15.344-.235-1.059 9.562 0 0 10.267 4.838 17.351 23.019 0 0 9.241 31.01 53.835 21.061v32.032s-.943 11.33-11.33 15.105c0 0-6.137 4.249.475 6.606 0 0 28.792 2.361 28.792-21.238v-34.929s-1.142-13.852 5.663-18.667v57.371s-.47 13.688-7.551 18.881c0 0-4.723 8.494 5.663 6.137 0 0 19.824-2.832 20.769-25.961l.449-58.06h4.765l.453 58.06c.943 23.129 20.768 25.961 20.768 25.961 10.383 2.357 5.663-6.137 5.663-6.137-7.08-5.193-7.551-18.881-7.551-18.881v-56.876c6.801 5.296 5.663 18.171 5.663 18.171v34.929c0 23.6 28.793 21.238 28.793 21.238 6.606-2.357.474-6.606.474-6.606-10.386-3.775-11.33-15.105-11.33-15.105v-45.786c0-17.854-7.518-27.309-14.87-32.3 42.859-4.25 63.426-18.089 72.903-39.591 18.773.516 52.557 2.803 84.873 11.919l.384-1.36c-32.131-9.063-65.692-11.408-84.655-11.96.898-2.172 1.682-4.431 2.378-6.755 19.25-.80 51.38-.79 82.66 5.46z"/&gt;&lt;path id="face" fill="#F4CBB2" d="m258.19 94.132c9.231 8.363 14.631 18.462 14.631 29.343 0 50.804-37.872 52.181-84.585 52.181-46.721 0-84.589-7.035-84.589-52.181 0-10.809 5.324-20.845 14.441-29.174 15.208-13.881 40.946-6.531 70.147-6.531 29.07-.004 54.72-7.429 69.95 6.357z"/&gt;&lt;path id="eyes" fill="#FFF" d="m160.1 126.06 c0 13.994-7.88 25.336-17.6 25.336-9.72 0-17.6-11.342-17.6-25.336 0-13.992 7.88-25.33 17.6-25.33 9.72.01 17.6 11.34 17.6 25.33z m94.43 0 c0 13.994-7.88 25.336-17.6 25.336-9.72 0-17.6-11.342-17.6-25.336 0-13.992 7.88-25.33 17.6-25.33 9.72.01 17.6 11.34 17.6 25.33z"/&gt;&lt;g fill="#AD5C51"&gt;&lt;path id="pupils" d="m154.46 126.38 c0 9.328-5.26 16.887-11.734 16.887s-11.733-7.559-11.733-16.887c0-9.331 5.255-16.894 11.733-16.894 6.47 0 11.73 7.56 11.73 16.89z m94.42 0 c0 9.328-5.26 16.887-11.734 16.887s-11.733-7.559-11.733-16.887c0-9.331 5.255-16.894 11.733-16.894 6.47 0 11.73 7.56 11.73 16.89z"/&gt;&lt;circle id="nose" cx="188.5" cy="148.56" r="4.401"/&gt;&lt;path id="mouth" d="m178.23 159.69c-.26-.738.128-1.545.861-1.805.737-.26 1.546.128 1.805.861 1.134 3.198 4.167 5.346 7.551 5.346s6.417-2.147 7.551-5.346c.26-.738 1.067-1.121 1.805-.861s1.121 1.067.862 1.805c-1.529 4.324-5.639 7.229-10.218 7.229s-8.68-2.89-10.21-7.22z"/&gt;&lt;/g&gt;&lt;path id="octo" fill="#C3E4D8" d="m80.641 179.82 c0 1.174-1.376 2.122-3.07 2.122-1.693 0-3.07-.948-3.07-2.122 0-1.175 1.377-2.127 3.07-2.127 1.694 0 3.07.95 3.07 2.13z m8.5 4.72 c0 1.174-1.376 2.122-3.07 2.122-1.693 0-3.07-.948-3.07-2.122 0-1.175 1.377-2.127 3.07-2.127 1.694 0 3.07.95 3.07 2.13z m5.193 6.14 c0 1.174-1.376 2.122-3.07 2.122-1.693 0-3.07-.948-3.07-2.122 0-1.175 1.377-2.127 3.07-2.127 1.694 0 3.07.95 3.07 2.13z m4.72 7.08 c0 1.174-1.376 2.122-3.07 2.122-1.693 0-3.07-.948-3.07-2.122 0-1.175 1.377-2.127 3.07-2.127 1.694 0 3.07.95 3.07 2.13z m5.188 6.61 c0 1.174-1.376 2.122-3.07 2.122-1.693 0-3.07-.948-3.07-2.122 0-1.175 1.377-2.127 3.07-2.127 1.694 0 3.07.95 3.07 2.13z m7.09 5.66 c0 1.174-1.376 2.122-3.07 2.122-1.693 0-3.07-.948-3.07-2.122 0-1.175 1.377-2.127 3.07-2.127 1.694 0 3.07.95 3.07 2.13z m9.91 3.78 c0 1.174-1.376 2.122-3.07 2.122-1.693 0-3.07-.948-3.07-2.122 0-1.175 1.377-2.127 3.07-2.127 1.694 0 3.07.95 3.07 2.13z m9.87 0 c0 1.174-1.376 2.122-3.07 2.122-1.693 0-3.07-.948-3.07-2.122 0-1.175 1.377-2.127 3.07-2.127 1.694 0 3.07.95 3.07 2.13z m10.01 -1.64 c0 1.174-1.376 2.122-3.07 2.122-1.693 0-3.07-.948-3.07-2.122 0-1.175 1.377-2.127 3.07-2.127 1.694 0 3.07.95 3.07 2.13z"/&gt;&lt;path id="drop" fill="#9CDAF1" d="m69.369 186.12l-3.066 10.683s-.8 3.861 2.84 4.546c3.8-.074 3.486-3.627 3.223-4.781z"/&gt;&lt;/svg&gt; While github reports having no plans on serving &lt;code&gt;*.svg&lt;/code&gt; gists with an image content-type (they don't want people using gists for image hosting, I guess, even though it's sad you can't easily preview without saving to disk or using my hack above) I still think the light-weight gist community oriented sharing is good for this kind of thing. Others happily forked the &lt;a href="https://gist.github.com/1007813"&gt;octocat&lt;/a&gt; SVG I &lt;a href="https://github.com/blog/868-who-is-github-anyway#comment-12368"&gt;similarly format converted&lt;/a&gt; a while ago from the github About page, and &lt;a href="https://gist.github.com/milligramme"&gt;milligramme&lt;/a&gt; made &lt;a href="https://gist.github.com/1058563"&gt;this much spacier version&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
I gather all my SVG play in a &lt;a href="https://github.com/johan/svg-cleanups/"&gt;svg-cleanups&lt;/a&gt; repository on github, if anyone wants to get inspired the fork or follow way, and occasionally &lt;a href="http://twitter.com/ecmanaut/"&gt;tweet&lt;/a&gt; about it. If you find this kind of exercise as much fun, I love hearing about it; here, on Twitter, github, or elsewhere. I believe it's good teaching and learning for the web as a whole, too. Any logos, trademarks and the like above are property of their respective owners.&lt;img src="http://feeds.feedburner.com/~r/blogspot/xxBcs/~4/OX6IcEb8bNs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://ecmanaut.blogspot.com/feeds/1635257323003270877/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=15626356&amp;postID=1635257323003270877" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/15626356/posts/default/1635257323003270877?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/15626356/posts/default/1635257323003270877?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/xxBcs/~3/OX6IcEb8bNs/optimized-svgs-at-gistgithubcom.html" title="Optimized SVGs at gist.github.com" /><author><name>Johan Sundström</name><uri>http://www.blogger.com/profile/04076097346172610543</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://ecmanaut.blogspot.com/2011/07/optimized-svgs-at-gistgithubcom.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkMAQns4eSp7ImA9WhZUEUU.&quot;"><id>tag:blogger.com,1999:blog-15626356.post-2482992080593249833</id><published>2011-06-04T04:28:00.000-07:00</published><updated>2011-06-04T04:54:03.531-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-04T04:54:03.531-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="SVG" /><category scheme="http://www.blogger.com/atom/ns#" term="github" /><title>Draw your own Github SVGs, step by step</title><content type="html">I SVG:ified and played a little further with the logo material from the recently published &lt;a href="https://github.com/blog/868-who-is-github-anyway"&gt;Github about page&lt;/a&gt;, and then tonight I figured it would be fun to visualize the elegant process by which a raw SVG image is built up, piece by piece, by rather basic building blocks. With just a little bit of javascript magic to help you, here is how you piece together your own github schwag from scratch (works like a charm in Chrome, Firefox 4, and presumably any other modern browser that can handle inline SVG images&lt;noscript&gt; - if you do not see them in your feed reader despite a modern browser, or want to try the interactive behaviour, &lt;a href="http://ecmanaut.blogspot.com/2011/06/draw-your-own-github-svgs-step-by-step.html"&gt;head over to the blog post itself&lt;/a&gt;&lt;/noscript&gt;):&lt;div style="max-width: 90%; margin: 0 auto;"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="-0.2 -1 379 334" height="70%"&gt;&lt;path id="puddle" fill="#9CDAF1" d="m296.94 295.43c0 20.533-47.56 37.176-106.22 37.176-58.67 0-106.23-16.643-106.23-37.176s47.558-37.18 106.23-37.18c58.66 0 106.22 16.65 106.22 37.18z"/&gt;&lt;g id="shadow-legs" fill="#7DBBE6"&gt;&lt;path d="m161.85 331.22v-26.5c0-3.422-.619-6.284-1.653-8.701 6.853 5.322 7.316 18.695 7.316 18.695v17.004c6.166.481 12.534.773 19.053.861l-.172-16.92c-.944-23.13-20.769-25.961-20.769-25.961-7.245-1.645-7.137 1.991-6.409 4.34-7.108-12.122-26.158-10.556-26.158-10.556-6.611 2.357-.475 6.607-.475 6.607 10.387 3.775 11.33 15.105 11.33 15.105v23.622c5.72.98 11.71 1.79 17.94 2.4z"/&gt;&lt;path d="m245.4 283.48s-19.053-1.566-26.16 10.559c.728-2.35.839-5.989-6.408-4.343 0 0-19.824 2.832-20.768 25.961l-.174 16.946c6.509-.025 12.876-.254 19.054-.671v-17.219s.465-13.373 7.316-18.695c-1.034 2.417-1.653 5.278-1.653 8.701v26.775c6.214-.544 12.211-1.279 17.937-2.188v-24.113s.944-11.33 11.33-15.105c0-.01 6.13-4.26-.48-6.62z"/&gt;&lt;/g&gt;&lt;path id="cat" d="m378.18 141.32l.28-1.389c-31.162-6.231-63.141-6.294-82.487-5.49 3.178-11.451 4.134-24.627 4.134-39.32 0-21.073-7.917-37.931-20.77-50.759 2.246-7.25 5.246-23.351-2.996-43.963 0 0-14.541-4.617-47.431 17.396-12.884-3.22-26.596-4.81-40.328-4.81-15.109 0-30.376 1.924-44.615 5.83-33.94-23.154-48.923-18.411-48.923-18.411-9.78 24.457-3.733 42.566-1.896 47.063-11.495 12.406-18.513 28.243-18.513 47.659 0 14.658 1.669 27.808 5.745 39.237-19.511-.71-50.323-.437-80.373 5.572l.276 1.389c30.231-6.046 61.237-6.256 80.629-5.522.898 2.366 1.899 4.661 3.021 6.879-19.177.618-51.922 3.062-83.303 11.915l.387 1.36c31.629-8.918 64.658-11.301 83.649-11.882 11.458 21.358 34.048 35.152 74.236 39.484-5.704 3.833-11.523 10.349-13.881 21.374-7.773 3.718-32.379 12.793-47.142-12.599 0 0-8.264-15.109-24.082-16.292 0 0-15.344-.235-1.059 9.562 0 0 10.267 4.838 17.351 23.019 0 0 9.241 31.01 53.835 21.061v32.032s-.943 11.33-11.33 15.105c0 0-6.137 4.249.475 6.606 0 0 28.792 2.361 28.792-21.238v-34.929s-1.142-13.852 5.663-18.667v57.371s-.47 13.688-7.551 18.881c0 0-4.723 8.494 5.663 6.137 0 0 19.824-2.832 20.769-25.961l.449-58.06h4.765l.453 58.06c.943 23.129 20.768 25.961 20.768 25.961 10.383 2.357 5.663-6.137 5.663-6.137-7.08-5.193-7.551-18.881-7.551-18.881v-56.876c6.801 5.296 5.663 18.171 5.663 18.171v34.929c0 23.6 28.793 21.238 28.793 21.238 6.606-2.357.474-6.606.474-6.606-10.386-3.775-11.33-15.105-11.33-15.105v-45.786c0-17.854-7.518-27.309-14.87-32.3 42.859-4.25 63.426-18.089 72.903-39.591 18.773.516 52.557 2.803 84.873 11.919l.384-1.36c-32.131-9.063-65.692-11.408-84.655-11.96.898-2.172 1.682-4.431 2.378-6.755 19.25-.80 51.38-.79 82.66 5.46z"/&gt;&lt;path id="face" fill="#F4CBB2" d="m258.19 94.132c9.231 8.363 14.631 18.462 14.631 29.343 0 50.804-37.872 52.181-84.585 52.181-46.721 0-84.589-7.035-84.589-52.181 0-10.809 5.324-20.845 14.441-29.174 15.208-13.881 40.946-6.531 70.147-6.531 29.07-.004 54.72-7.429 69.95 6.357z"/&gt;&lt;path id="eyes" fill="#FFF" d="m160.1 126.06 c0 13.994-7.88 25.336-17.6 25.336-9.72 0-17.6-11.342-17.6-25.336 0-13.992 7.88-25.33 17.6-25.33 9.72.01 17.6 11.34 17.6 25.33z m94.43 0 c0 13.994-7.88 25.336-17.6 25.336-9.72 0-17.6-11.342-17.6-25.336 0-13.992 7.88-25.33 17.6-25.33 9.72.01 17.6 11.34 17.6 25.33z"/&gt;&lt;g fill="#AD5C51"&gt;&lt;path id="pupils" d="m154.46 126.38 c0 9.328-5.26 16.887-11.734 16.887s-11.733-7.559-11.733-16.887c0-9.331 5.255-16.894 11.733-16.894 6.47 0 11.73 7.56 11.73 16.89z m94.42 0 c0 9.328-5.26 16.887-11.734 16.887s-11.733-7.559-11.733-16.887c0-9.331 5.255-16.894 11.733-16.894 6.47 0 11.73 7.56 11.73 16.89z"/&gt;&lt;circle id="nose" cx="188.5" cy="148.56" r="4.401"/&gt;&lt;path id="mouth" d="m178.23 159.69c-.26-.738.128-1.545.861-1.805.737-.26 1.546.128 1.805.861 1.134 3.198 4.167 5.346 7.551 5.346s6.417-2.147 7.551-5.346c.26-.738 1.067-1.121 1.805-.861s1.121 1.067.862 1.805c-1.529 4.324-5.639 7.229-10.218 7.229s-8.68-2.89-10.21-7.22z"/&gt;&lt;/g&gt;&lt;path id="octo" fill="#C3E4D8" d="m80.641 179.82 c0 1.174-1.376 2.122-3.07 2.122-1.693 0-3.07-.948-3.07-2.122 0-1.175 1.377-2.127 3.07-2.127 1.694 0 3.07.95 3.07 2.13z m8.5 4.72 c0 1.174-1.376 2.122-3.07 2.122-1.693 0-3.07-.948-3.07-2.122 0-1.175 1.377-2.127 3.07-2.127 1.694 0 3.07.95 3.07 2.13z m5.193 6.14 c0 1.174-1.376 2.122-3.07 2.122-1.693 0-3.07-.948-3.07-2.122 0-1.175 1.377-2.127 3.07-2.127 1.694 0 3.07.95 3.07 2.13z m4.72 7.08 c0 1.174-1.376 2.122-3.07 2.122-1.693 0-3.07-.948-3.07-2.122 0-1.175 1.377-2.127 3.07-2.127 1.694 0 3.07.95 3.07 2.13z m5.188 6.61 c0 1.174-1.376 2.122-3.07 2.122-1.693 0-3.07-.948-3.07-2.122 0-1.175 1.377-2.127 3.07-2.127 1.694 0 3.07.95 3.07 2.13z m7.09 5.66 c0 1.174-1.376 2.122-3.07 2.122-1.693 0-3.07-.948-3.07-2.122 0-1.175 1.377-2.127 3.07-2.127 1.694 0 3.07.95 3.07 2.13z m9.91 3.78 c0 1.174-1.376 2.122-3.07 2.122-1.693 0-3.07-.948-3.07-2.122 0-1.175 1.377-2.127 3.07-2.127 1.694 0 3.07.95 3.07 2.13z m9.87 0 c0 1.174-1.376 2.122-3.07 2.122-1.693 0-3.07-.948-3.07-2.122 0-1.175 1.377-2.127 3.07-2.127 1.694 0 3.07.95 3.07 2.13z m10.01 -1.64 c0 1.174-1.376 2.122-3.07 2.122-1.693 0-3.07-.948-3.07-2.122 0-1.175 1.377-2.127 3.07-2.127 1.694 0 3.07.95 3.07 2.13z"/&gt;&lt;path id="drop" fill="#9CDAF1" d="m69.369 186.12l-3.066 10.683s-.8 3.861 2.84 4.546c3.8-.074 3.486-3.627 3.223-4.781z"/&gt;&lt;/svg&gt;&lt;center&gt;&lt;button id="step" onclick="step(this)" style="margin: 1em 0 1em"&gt;Redraw the octocat SVG image step by step&lt;/button&gt;&lt;div id="next_step" style="margin: 0 0 1em"&gt;&amp;nbsp;&lt;/div&gt;&lt;/center&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" viewBox="-0.147 -0.544 242 108" height="20%"&gt;&lt;g id="github" class="collegiate-regular"&gt;&lt;path d="m30.908 28.692c3.732 0 8.047-.933 12.946-2.799v12.013c-1.089.389-2.644.816-4.666 1.283.622 1.788.933 3.46.933 5.015 0 4.977-1.497 9.311-4.49 13.004s-6.862 5.891-11.605 6.59c-3.11.467-4.665 2.139-4.665 5.016 0 1.011.505 2.021 1.516 3.032 1.322 1.478 3.266 2.411 5.832 2.8 11.12 1.71 16.679 6.337 16.679 13.879 0 12.053-7.192 18.079-21.577 18.079-5.91 0-10.77-1.05-14.579-3.149-4.822-2.64-7.232-6.799-7.232-12.475 0-6.531 3.616-11.002 10.847-13.412v-.233c-2.644-1.633-3.965-4.121-3.965-7.465 0-4.354 1.244-7.076 3.732-8.164v-.233c-2.488-.855-4.705-2.8-6.648-5.832-2.178-3.267-3.266-6.766-3.266-10.498 0-5.599 1.983-10.264 5.948-13.996 3.81-3.499 8.359-5.249 13.646-5.249 3.81 0 7.348.933 10.614 2.799zm.467 61.35c0-3.966-3.266-5.948-9.797-5.948-6.298 0-9.447 2.061-9.447 6.182 0 4.043 3.421 6.064 10.264 6.064 5.986 0 8.98-2.099 8.98-6.298zm-17.962-44.788c0 5.365 2.449 8.048 7.348 8.048 4.743 0 7.115-2.722 7.115-8.165 0-2.255-.544-4.199-1.633-5.832-1.322-1.788-3.149-2.683-5.482-2.683-4.899.001-7.348 2.878-7.348 8.632z"/&gt;&lt;path d="m56.222 17.378c-2.255 0-4.179-.855-5.773-2.566-1.594-1.71-2.391-3.732-2.391-6.065 0-2.411.797-4.471 2.391-6.182 1.594-1.71 3.518-2.565 5.773-2.565 2.177 0 4.063.855 5.657 2.566s2.391 3.771 2.391 6.182c0 2.333-.797 4.354-2.391 6.065-1.594 1.71-3.48 2.565-5.657 2.565z"/&gt;&lt;path d="m49.574 78.262c.155-1.555.233-4.198.233-7.931v-36.274c0-3.654-.078-6.182-.233-7.581h13.18c-.156 1.478-.233 3.927-.233 7.348v35.807c0 3.966.078 6.843.233 8.631h-13.18z"/&gt;&lt;path d="m86.888 26.476h10.147v11.314c-.389 0-1.108-.039-2.158-.117s-2.041-.117-2.974-.117h-5.015v21.694c0 5.21 1.71 7.814 5.132 7.814 2.411 0 4.587-.66 6.532-1.982v11.663c-2.877 1.556-6.337 2.333-10.381 2.333-5.676 0-9.603-2.021-11.78-6.064-1.633-3.033-2.45-7.814-2.45-14.347v-20.877h.117v-.233l-1.75-.116c-1.011 0-2.333.116-3.965.35v-11.315h5.715v-4.549c0-2.177-.117-3.927-.35-5.249h13.529c-.233 1.478-.35 3.149-.35 5.015v4.783z"/&gt;&lt;path d="m127.86 26.126c-3.343 0-6.842 1.167-10.497 3.499v-20.411c0-4.432.078-7.348.233-8.748h-13.296c.233 1.244.35 4.16.35 8.748v61.7c0 3.576-.117 6.026-.35 7.348h13.53c0-.233-.078-1.186-.233-2.857-.155-1.672-.233-3.169-.233-4.49v-28.693c2.722-2.566 5.365-3.849 7.931-3.849 2.955 0 5.21 1.477 6.765 4.432 1.166 2.333 1.75 5.249 1.75 8.748l-.117 15.745c0 2.645-.194 6.299-.583 10.964h14.112c-.311-1.943-.466-5.521-.466-10.73v-15.979c0-6.765-1.516-12.519-4.549-17.262-3.42-5.443-8.2-8.165-14.34-8.165z"/&gt;&lt;path d="m169.15 78.729c-6.143 0-10.691-2.722-13.646-8.165-2.333-4.432-3.499-10.225-3.499-17.378v-15.979c0-5.288-.155-8.864-.466-10.73h13.996c-.233 1.71-.389 5.365-.467 10.964l-.116 15.746c0 4.432.505 7.62 1.516 9.563 1.167 2.411 3.305 3.616 6.415 3.616 2.177 0 4.626-1.283 7.348-3.849v-28.693c0-1.322-.078-2.838-.233-4.549-.156-1.711-.233-2.644-.233-2.799h13.529c-.155 1.322-.233 3.771-.233 7.348v35.69c0 4.587.078 7.503.233 8.747h-12.72v-4.198c-3.58 3.11-7.39 4.666-11.43 4.666z"/&gt;&lt;path d="m221.64 78.611c-4.198 0-7.697-1.516-10.497-4.548v4.198h-12.363c.233-1.321.351-3.771.351-7.348v-61.7c0-4.588-.117-7.503-.351-8.748h13.297c-.156 1.399-.233 4.315-.233 8.748v20.294c3.576-2.255 7.076-3.383 10.497-3.383 6.143 0 10.964 2.722 14.463 8.165 2.954 4.743 4.432 10.497 4.432 17.262 0 6.92-1.555 12.946-4.665 18.078-3.74 5.989-8.72 8.982-14.94 8.982zm-1.75-40.238c-2.566 0-5.249 1.283-8.048 3.849v20.178c2.488 2.41 4.938 3.616 7.348 3.616 3.032 0 5.326-1.672 6.882-5.016 1.244-2.644 1.866-5.793 1.866-9.447 0-8.787-2.68-13.18-8.05-13.18z"/&gt;&lt;/g&gt;&lt;g id="social" class="futura-heavy"&gt;&lt;path d="m58.661 89.441c-.74-1.004-1.691-1.639-2.986-1.639-1.242 0-2.431.952-2.431 2.247 0 3.356 7.902 1.955 7.902 8.642 0 3.991-2.484 6.818-6.554 6.818-2.749 0-4.757-1.585-6.131-3.885l2.511-2.458c.528 1.533 1.929 2.907 3.594 2.907 1.585 0 2.563-1.348 2.563-2.881 0-2.062-1.903-2.643-3.462-3.25-2.564-1.058-4.44-2.353-4.44-5.444 0-3.304 2.458-5.973 5.814-5.973 1.771 0 4.229.872 5.444 2.22l-1.824 2.699z"/&gt;&lt;path d="m72.083 105.51c-6.079 0-9.858-4.651-9.858-10.519 0-5.92 3.912-10.465 9.858-10.465s9.858 4.545 9.858 10.465c0 5.869-3.779 10.519-9.858 10.519zm0-17.152c-3.673 0-5.841 3.25-5.841 6.475 0 3.065 1.533 6.845 5.841 6.845s5.84-3.779 5.84-6.845c.001-3.227-2.166-6.477-5.84-6.477z"/&gt;&lt;path d="m97.16 90.34c-1.083-1.321-2.722-2.114-4.387-2.114-3.727 0-5.867 3.436-5.867 6.872 0 3.356 2.22 6.712 5.841 6.712 1.665 0 3.33-.872 4.414-2.113v4.624c-1.454.688-2.907 1.189-4.52 1.189-5.603 0-9.752-4.836-9.752-10.333 0-5.656 3.991-10.65 9.832-10.65 1.559 0 3.092.423 4.44 1.162v4.651z"/&gt;&lt;path d="m103.61 104.98h-3.885v-19.925h3.885v19.925z"/&gt;&lt;path d="m110.5 100.78l-1.639 4.202h-4.096l7.77-20.455h3.013l7.559 20.455h-4.149l-1.533-4.202h-6.92zm3.36-10.414h-.053l-2.194 7.242h4.731l-2.49-7.242z"/&gt;&lt;path d="m128.18 101.6h5.497v3.383h-9.382v-19.925h3.885v16.545z"/&gt;&lt;/g&gt;&lt;g id="coding" class="futura-heavy"&gt;&lt;path d="m155.87 90.34c-1.083-1.321-2.722-2.114-4.387-2.114-3.727 0-5.867 3.436-5.867 6.872 0 3.356 2.22 6.712 5.841 6.712 1.665 0 3.33-.872 4.414-2.113v4.624c-1.454.688-2.907 1.189-4.52 1.189-5.603 0-9.752-4.836-9.752-10.333 0-5.656 3.991-10.65 9.832-10.65 1.559 0 3.092.423 4.44 1.162v4.651z"/&gt;&lt;path d="m167.34 105.51c-6.079 0-9.858-4.651-9.858-10.519 0-5.92 3.912-10.465 9.858-10.465s9.857 4.545 9.857 10.465c0 5.869-3.78 10.519-9.86 10.519zm0-17.152c-3.674 0-5.841 3.25-5.841 6.475 0 3.065 1.533 6.845 5.841 6.845s5.841-3.779 5.841-6.845c0-3.227-2.17-6.477-5.84-6.477z"/&gt;&lt;path d="m179.1 85.055h5.551c5.761 0 9.619 4.308 9.619 9.989 0 5.604-3.964 9.938-9.646 9.938h-5.523v-19.925zm3.88 16.545h.634c4.783 0 6.634-2.643 6.634-6.581 0-4.334-2.22-6.58-6.634-6.58h-.634v13.161z"/&gt;&lt;path d="m200.05 104.98h-3.886v-19.925h3.886v19.925z"/&gt;&lt;path d="m202.88 84.526h2.802l10.492 13.928h.053v-13.399h3.885v20.323h-2.801l-10.48-13.93h-.053v13.531h-3.886v-20.454z"/&gt;&lt;path d="m240.53 94.384v.502c0 5.629-2.881 10.624-9.064 10.624-5.814 0-9.488-4.915-9.488-10.412 0-5.683 3.779-10.571 9.726-10.571 3.383 0 6.343 1.718 7.876 4.757l-3.436 1.85c-.793-1.797-2.484-3.171-4.546-3.171-3.753 0-5.603 3.832-5.603 7.136 0 3.303 1.876 6.977 5.629 6.977 2.432 0 4.467-2.114 4.546-4.52h-4.229v-3.171h8.58z"/&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/div&gt;&lt;script src="https://gist.github.com/raw/1007786/bd7ec322d9215edf08d5792149551a975f5b44bf/draw-svg.js"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
If all you see is a button and the description of each step, that just means your browser doesn't natively handle inline SVG, which of course is a bit of a shame. Another reason I was curious to try this is for seeing how inline SVG:s fare in feed readers. (Google Reader seems to fail.)&lt;br /&gt;
&lt;br /&gt;
Nicer source code for the images than in the page (Blogger insisted on filling all the whitespace with html junk) in these gists: &lt;a href="https://gist.github.com/raw/1007812/a97732f233379d2b39e1216adc61bd9ee553b0bf/github-logo.svg"&gt;github-logo.svg&lt;/a&gt;, &lt;a href="https://gist.github.com/raw/1007813/1f883261b243111b00d932d6033a8b538b1ecae7/octocat.svg"&gt;octocat.svg&lt;/a&gt;. gist.github.com currently doesn't serve .svg files as &lt;code&gt;image/svg&lt;/code&gt;, so you'll have to save them locally first to see them rendered.&lt;br /&gt;
&lt;br /&gt;
Source code for the step-by-step drawing is &lt;a href="https://gist.github.com/1007786"&gt;in this gist&lt;/a&gt;; MIT licensed, if you want to fork away, adopt, adapt or whatnot. Have fun! I did. :-)&lt;img src="http://feeds.feedburner.com/~r/blogspot/xxBcs/~4/uO1yX3r87N8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://ecmanaut.blogspot.com/feeds/2482992080593249833/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=15626356&amp;postID=2482992080593249833" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/15626356/posts/default/2482992080593249833?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/15626356/posts/default/2482992080593249833?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/xxBcs/~3/uO1yX3r87N8/draw-your-own-github-svgs-step-by-step.html" title="Draw your own Github SVGs, step by step" /><author><name>Johan Sundström</name><uri>http://www.blogger.com/profile/04076097346172610543</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://ecmanaut.blogspot.com/2011/06/draw-your-own-github-svgs-step-by-step.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkMBSX09fyp7ImA9WhZVF0U.&quot;"><id>tag:blogger.com,1999:blog-15626356.post-7764322370965799632</id><published>2011-05-29T23:18:00.000-07:00</published><updated>2011-05-30T12:40:58.367-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-30T12:40:58.367-07:00</app:edited><title>Add-on hosting: Mozilla vs Google vs Opera</title><content type="html">I habitually develop browser user scripts to stream-line things for myself (and others) on the web – and a half random scattering of them tends to end up proper add-ons, when I think the benefit of them being easy to find, install and reuse by others merits the added work for myself of packaging them and submitting them to an add-ons gallery.&lt;br /&gt;
&lt;br /&gt;
This happens rarely enough for me to forget some details of the process (yet often enough to be annoying), hence this post to document salient parts of it, applaud parts of where hosts worked things out really well, and note where there are holes to patch up. (I don't cover Safari since I have not made any Safari add-ons.)&lt;br /&gt;
&lt;br /&gt;
&lt;hr&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-oCAXDQdo0CY/TeMUNTWtQII/AAAAAAAAAOQ/lprF0rJcldY/s1600/public-greasemonkey-panel-ff.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="176" width="320" alt="Firefox add-on page" src="http://4.bp.blogspot.com/-oCAXDQdo0CY/TeMUNTWtQII/AAAAAAAAAOQ/lprF0rJcldY/s320/public-greasemonkey-panel-ff.png" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
(&lt;a href="https://addons.mozilla.org/en-US/firefox/addon/greasemonkey/"&gt;screenshot taken here&lt;/a&gt;)&lt;/div&gt;&lt;br /&gt;
&lt;h4&gt;Firefox add-ons: &lt;a href="http://addons.mozilla.org/"&gt;addons.mozilla.org&lt;/a&gt;, a k a AMO&lt;/h4&gt;&lt;br /&gt;
&lt;b&gt;&lt;i&gt;Your&lt;/i&gt; add-ons are listed here:&lt;/b&gt; &lt;a href="https://addons.mozilla.org/en-US/developers/addons"&gt;addons.mozilla.org/en-US/developers/addons&lt;/a&gt;&lt;br /&gt;
&lt;b&gt;Add-on URL:&lt;/b&gt; addons.mozilla.org/en-US/firefox/addon/&lt;i&gt;your-configurable-addon-slug&lt;/i&gt;&lt;br /&gt;
&lt;b&gt;Public data:&lt;/b&gt; current version, last update time, compatible browser versions, website and, optionally: &lt;b&gt;all add-on detail metrics, if the developer wants to share them&lt;/b&gt; (excellent!)&lt;br /&gt;
&lt;b&gt;Public metrics:&lt;/b&gt; total download count, average rating, number of ratings&lt;br /&gt;
&lt;b&gt;Detail metrics:&lt;/b&gt; TONS: mainly installation rate and active installed user base over time, broken down by all sorts of interesting properties or in aggregate, graphed and downloadable in csv format. Notable omission: add-on page traffic stats. Public example: &lt;a href="https://addons.mozilla.org/en-US/statistics/addon/748"&gt;Greasemonkey stats&lt;/a&gt;&lt;br /&gt;
&lt;b&gt;Developer page linked from the public add-on page when you're logged in:&lt;/b&gt; NO&lt;br /&gt;
&lt;b&gt;Release process:&lt;/b&gt; Manual review process that can take a really long time, as AMO often is under-staffed, and hasn't successfully incentivized developer participation in the process to an extent as to make it not so.&lt;br /&gt;
&lt;br /&gt;
Summary: great stats and an ambition to make information public and transparent.&lt;br /&gt;
&lt;br /&gt;
&lt;hr&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-4XNd-LPWcEA/TeMWDJ0pnZI/AAAAAAAAAOY/1lhbCJWux3U/s1600/public-github-improved-panel-cr.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="154" width="320" alt="Chrome add-on page" src="http://3.bp.blogspot.com/-4XNd-LPWcEA/TeMWDJ0pnZI/AAAAAAAAAOY/1lhbCJWux3U/s320/public-github-improved-panel-cr.png" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
(&lt;a href="https://chrome.google.com/webstore/detail/nkbnmpfpclijlllipmfbkkednidgngaa"&gt;screenshot taken here&lt;/a&gt;)&lt;/div&gt;&lt;br /&gt;
&lt;h4&gt;Chrome add-ons: &lt;a href="https://chrome.google.com/webstore/"&gt;chrome.google.com/webstore&lt;/a&gt;, or the Chrome Web Store&lt;br /&gt;
Previously lived at &lt;a href="https://chrome.google.com/extensions"&gt;chrome.google.com/extensions&lt;/a&gt;, the Chrome extensions gallery&lt;/h4&gt;&lt;br /&gt;
&lt;b&gt;&lt;i&gt;Your&lt;/i&gt; add-ons are listed here:&lt;/b&gt; &lt;a href="https://chrome.google.com/webstore/developer/dashboard"&gt;chrome.google.com/webstore/developer/dashboard&lt;/a&gt;&lt;br /&gt;
&lt;b&gt;Add-on URL:&lt;/b&gt; chrome.google.com/webstore/detail/&lt;i&gt;your-addon-signature&lt;/i&gt;[/optional-add-on-slug]&lt;br /&gt;
&lt;b&gt;Public data:&lt;/b&gt; current version, last update time, &lt;b&gt;if installed: a checkmark and the sign "Installed", instead of the "Install" button&lt;/b&gt; (excellent!)&lt;br /&gt;
&lt;b&gt;Public metrics:&lt;/b&gt; total download count, average rating, number of ratings&lt;br /&gt;
&lt;b&gt;Detail metrics:&lt;/b&gt; If you jump through the relatively tiny hoop of creating and tying a new Google Analytics account to your add-on, you get detailed add-on page traffic stats, over in Google Analytics. Notabe omission: all metrics about your installed user base :-/&lt;br /&gt;
&lt;b&gt;Developer page linked from the public add-on page when you're logged in:&lt;/b&gt; NO&lt;br /&gt;
&lt;b&gt;Release process:&lt;/b&gt; Automated review process, making yourself the only release blocker, in practice. This is bloody awesome!&lt;br /&gt;
&lt;br /&gt;
In summary: A really delightful release process that doesn't waste your time. The metrics part is really disappointingly missing the most interesting data; I hope that will improve with time. There are other essential missing docs too: to find out that you can self host your add-on AND publish it in the chrome web store, with the same add-on id, you need excellent Google fu, or this secret knowledge:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;first (before your initial web store submission) build your add-on locally&lt;/li&gt;
&lt;li&gt;store the .pem file in some good location&lt;/li&gt;
&lt;li&gt;rename it &lt;tt&gt;key.pem&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;copy that .pem file into the add-on directory&lt;/li&gt;
&lt;li&gt;zip up that directory (so the top level of the zip file only has one directory)&lt;/li&gt;
&lt;li&gt;NOW (and for all later versions, IIRC) upload this zip file to the Chrome Web Store&lt;/li&gt;
&lt;li&gt;…and it will use your add-on signature, instead of that of Google's secret .pem&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;hr&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-SUFo9AQoNxk/TeMmY2UmRFI/AAAAAAAAAOg/E1LmXjpQlFM/s1600/pubilc-github-improved-op.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="47" width="320" alt="Opera add-on page" src="http://3.bp.blogspot.com/-SUFo9AQoNxk/TeMmY2UmRFI/AAAAAAAAAOg/E1LmXjpQlFM/s320/pubilc-github-improved-op.png" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
(slightly de-horizontalized &lt;a href="https://addons.opera.com/addons/extensions/details/github-improved/"&gt;screenshot taken here&lt;/a&gt;)&lt;/div&gt;&lt;br /&gt;
&lt;h4&gt;Opera add-ons: &lt;a href="https://addons.opera.com/addons/extensions/"&gt;addons.opera.com/addons/extensions&lt;/a&gt;&lt;/h4&gt;&lt;br /&gt;
&lt;b&gt;&lt;i&gt;Your&lt;/i&gt; add-ons are listed here:&lt;/b&gt; &lt;a href="https://addons.opera.com/developer/"&gt;addons.opera.com/developer&lt;/a&gt; (this page is near &lt;i&gt;impossible&lt;/i&gt; to find by navigation, and was the reason I created this blog post :-)&lt;br /&gt;
&lt;b&gt;Add-on public URL:&lt;/b&gt; addons.opera.com/addons/extensions/details/&lt;i&gt;addon-slug&lt;/i&gt;[/&lt;i&gt;version&lt;/i&gt; (redirects visitors here)]&lt;br /&gt;
&lt;b&gt;Add-on developer URL:&lt;/b&gt; addons.opera.com/developer/extensions/details/&lt;i&gt;addon-slug&lt;/i&gt;/&lt;i&gt;version&lt;/i&gt; (no redirect help, but links to all other versions)]&lt;br /&gt;
&lt;b&gt;Public data:&lt;/b&gt; current version, last update time, &lt;b&gt;add-on size&lt;/b&gt; (excellent!)&lt;br /&gt;
&lt;b&gt;Public metrics:&lt;/b&gt; total download count, average rating, number of ratings&lt;br /&gt;
&lt;b&gt;Detail metrics:&lt;/b&gt; NONE. Notabe omission: all data about your installed user base, AND add-on page traffic :-(&lt;br /&gt;
&lt;b&gt;Developer page linked from the public add-on page when you're logged in:&lt;/b&gt; NO&lt;br /&gt;
&lt;b&gt;Release process:&lt;/b&gt; Manual review process, rewarding the behaviour of publishing as little data about your add-on as possible, since each bit of data is a plausible blocker. (Example: it is a bad thing to link to your development site on github, unless it is a repository that only has Opera-addon-centric stuff in it, and not, say, covers the source code used to build add-ons all browsers it caters.)&lt;br /&gt;
&lt;br /&gt;
Summary: young; still a far cry from easy to find your way around. I accidentally managed to log in via my email address (after having reset the password), which had gotten the same password as the account nickname I had published from before, but was otherwise treated as another account, with its own (empty) list of add-ons. So I first found no way to upgrade my existing add-on and just uploaded a new one. When I found the mistake, there was no way to abort the review process I had started (but I could edit it to add some reviewer notes for the probably equally confused reviewer). What probably looks like a really well integrated set of connected Opera sites to an Opera employee is a huge maze of web pages, none related to publishing your add-on, to an add-on developer.&lt;br /&gt;
&lt;br /&gt;
All of these hosting sites have developer log-in of some sort, yet fail to link the developer's admin view from the public add-on page. For Opera, this hurts really badly, as there is so much Opera noise around, which does not try to help you publish your add-on; for the others, it's a smaller nuisance (it's also entirely possible that I learned where to find the "Developer Hub" and "Developer Dashboard" links long ago enough to now find them near intuitive).&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Update:&lt;/b&gt; I just found Opera's dashboard link! Your logged-in name is the link that takes you to your dashboard of add-ons. And it only took knowing the wanted url, opening a web console and typing &lt;code&gt;[].slice.call(document.links).filter(function(a){ return a.href == "https://addons.opera.com/developer/"; })&lt;/code&gt; in it. What do you know? :-)&lt;img src="http://feeds.feedburner.com/~r/blogspot/xxBcs/~4/Sa1s3IyPmHQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://ecmanaut.blogspot.com/feeds/7764322370965799632/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=15626356&amp;postID=7764322370965799632" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/15626356/posts/default/7764322370965799632?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/15626356/posts/default/7764322370965799632?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/xxBcs/~3/Sa1s3IyPmHQ/add-on-hosting-mozilla-vs-google-vs.html" title="Add-on hosting: Mozilla vs Google vs Opera" /><author><name>Johan Sundström</name><uri>http://www.blogger.com/profile/04076097346172610543</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-oCAXDQdo0CY/TeMUNTWtQII/AAAAAAAAAOQ/lprF0rJcldY/s72-c/public-greasemonkey-panel-ff.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://ecmanaut.blogspot.com/2011/05/add-on-hosting-mozilla-vs-google-vs.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUEASHkyeyp7ImA9WhZUEUU.&quot;"><id>tag:blogger.com,1999:blog-15626356.post-2391817911746825560</id><published>2011-05-28T02:47:00.000-07:00</published><updated>2011-06-04T04:40:49.793-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-04T04:40:49.793-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="extension" /><category scheme="http://www.blogger.com/atom/ns#" term="github" /><category scheme="http://www.blogger.com/atom/ns#" term="Chrome" /><category scheme="http://www.blogger.com/atom/ns#" term="Opera" /><title>Github Improved 1.7</title><content type="html">After a whole year in development as a user script (&lt;a href="http://ecmanaut.blogspot.com/2010/08/friendlier-github-commits-pages.html"&gt;initial mention&lt;/a&gt;, formerly known as "Github: unfold commit history"), a brief test-drive as an &lt;a href="https://addons.opera.com/addons/extensions/details/github-improved/"&gt;Opera extension&lt;/a&gt; at &lt;a href="http://ecmanaut.blogspot.com/2010/12/opera-11-extensions-add-on-con.html"&gt;the 2010 add-on con&lt;/a&gt;, I finished up the missing bits and pieces to make today's &lt;a href="https://chrome.google.com/webstore/detail/nkbnmpfpclijlllipmfbkkednidgngaa"&gt;Github Improved! chrome extension&lt;/a&gt; available in the Chrome Gallery / Web Store (1.7 now also available in the &lt;a href="https://addons.opera.com/addons/extensions/details/github-improved/"&gt;Opera extension gallery&lt;/a&gt;).&lt;br /&gt;
&lt;br /&gt;
New since last release is the little tag delta (&amp;Delta;) links that let you instantly see what happened between, say, &lt;a href="https://github.com/greasemonkey/greasemonkey/commits/0.9.5"&gt;Greasemonkey 0.9.5&lt;/a&gt; and the previous release tag (it recognizes anything where the only thing differing between tags are their numeric parts, which also means it's not going to handle fancy 1.6rc1 type tag names littered with semantic non-numeric parts):&lt;br /&gt;
&lt;br /&gt;
&lt;img src="https://lh3.googleusercontent.com/JCJFUNc-0dwcDX2VyOjMWz8shFzBQTnm_jhiM6Wew8uAIz9xb1yo5GmBqbstKaY3t_oAmtM6Pw=s400-e365-h275" width="400" height="275" style="display: block; margin: 0 auto; text-align: center;"&gt;&lt;br /&gt;
&lt;br /&gt;
And, as prior users may find even more importantly, that it doesn't hog any shifted keyboard shortcuts, which for some reason had the side effect of making arrow up pull in a pageful of diffs.&lt;br /&gt;
&lt;br /&gt;
Full documentation of all features, and a few screenshots, is available on the &lt;a href="https://chrome.google.com/webstore/detail/nkbnmpfpclijlllipmfbkkednidgngaa"&gt;Chrome Web Store page&lt;/a&gt;. I also take every opportunity to mention that it really shines best together with the &lt;a href="https://chrome.google.com/webstore/detail/aeolcjbaammbkgaiagooljfdepnjmkfd"&gt;AutoPatchWork&lt;/a&gt; extension, or something equivalent which unfolds the commit history pagination as you scroll off page. Enjoy!&lt;img src="http://feeds.feedburner.com/~r/blogspot/xxBcs/~4/hQMEDpHMQsY" height="1" width="1"/&gt;</content><link rel="related" href="https://chrome.google.com/webstore/detail/nkbnmpfpclijlllipmfbkkednidgngaa" title="Github Improved 1.7" /><link rel="replies" type="application/atom+xml" href="http://ecmanaut.blogspot.com/feeds/2391817911746825560/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=15626356&amp;postID=2391817911746825560" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/15626356/posts/default/2391817911746825560?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/15626356/posts/default/2391817911746825560?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/xxBcs/~3/hQMEDpHMQsY/github-improved-17.html" title="Github Improved 1.7" /><author><name>Johan Sundström</name><uri>http://www.blogger.com/profile/04076097346172610543</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://ecmanaut.blogspot.com/2011/05/github-improved-17.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0UFQnY9fip7ImA9WhZVEE4.&quot;"><id>tag:blogger.com,1999:blog-15626356.post-2168912183907757919</id><published>2011-05-21T20:33:00.000-07:00</published><updated>2011-05-21T20:33:33.866-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-21T20:33:33.866-07:00</app:edited><title>Google Closure Library bookmarklet</title><content type="html">Any self-respecting javascript library should have a debug bookmarklet that lets you load it into a page, so you can tinker with it (the library, or the page, for that matter) without any messy overhead like downloading the most recent version, building it with the specific flags and sub-components you want, saving the current page, adding library setup code to it, and reloading that page before you can do squat. I found &lt;a href="http://code.google.com/closure/library/"&gt;Google Closure Library&lt;/a&gt; a bit lacking in that regard, so here's my take on it:&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/985137.js?file=google-closure-library.js"&gt;&lt;/script&gt;&lt;noscript&gt;&lt;a href="https://gist.github.com/985137"&gt;gist.github.com/985137&lt;/a&gt;&lt;/noscript&gt;&lt;br /&gt;
It has two modes of operation; if all you want to do is load the &lt;code&gt;goog&lt;/code&gt; object into the current page (or overwrite the one you already have with one that has a different set of &lt;code&gt;goog.require()&lt;/code&gt;s), just customize which those requires should be, and you're set; it creates an iframe, in which it loads the library (&lt;code&gt;goog.require&lt;/code&gt; only works during page parsing time, as it uses &lt;code&gt;document.write()&lt;/code&gt; to load its dependencies), and then overwrites the top window's &lt;code&gt;goog&lt;/code&gt; identifier.&lt;br /&gt;
&lt;br /&gt;
The second mode is good for writing your own bookmarklets making use of some Closure Library tools; provide your own function, and it will instead get called with the freshly loaded &lt;code&gt;goog&lt;/code&gt; object, once it's ready. At the moment, I have only played with this in Google Chrome, but feel free to fork away on github, if you tinker in additional improvements for other browsers.&lt;br /&gt;
&lt;br /&gt;
Finally, here's a bookmarklet version to save or play with, which will prompt you for just which closure dependencies you want to load: &lt;a href="javascript:(function(f){var q=prompt('Please name your goog.require:s','goog.ui.TableSorter, goog.net.XhrIo'),r=q&amp;amp;&amp;amp;q.split(/,\s*/),i=r.length&amp;amp;&amp;amp;document.body.appendChild(document.createElement('iframe'));if(i){i.src='about:blank';i.style.display='none';i.contentWindow.f=f;i.contentDocument.write('&amp;lt;script src=http://closure-library.googlecode.com/svn/trunk/closure/goog/base.js&amp;gt;&amp;lt;/script&amp;gt;&amp;lt;script src=http://closure-library.googlecode.com/svn/trunk/closure/goog/deps.js&amp;gt;&amp;lt;/script&amp;gt;&amp;lt;script&amp;gt;'+JSON.stringify(r)+'.forEach(goog.require);&amp;lt;/script&amp;gt;&amp;lt;script&amp;gt;'+(f?'f.call(parent,goog)':'parent.goog=goog')+';&amp;lt;/script&amp;gt;');}})();"&gt;closure&lt;/a&gt; – drag it to your bookmarks toolbar or equivalent if you want to keep it around. Enjoy!&lt;img src="http://feeds.feedburner.com/~r/blogspot/xxBcs/~4/Tgbhm5mHg8M" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://ecmanaut.blogspot.com/feeds/2168912183907757919/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=15626356&amp;postID=2168912183907757919" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/15626356/posts/default/2168912183907757919?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/15626356/posts/default/2168912183907757919?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/xxBcs/~3/Tgbhm5mHg8M/google-closure-library-bookmarklet.html" title="Google Closure Library bookmarklet" /><author><name>Johan Sundström</name><uri>http://www.blogger.com/profile/04076097346172610543</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://ecmanaut.blogspot.com/2011/05/google-closure-library-bookmarklet.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEQMQXo7eSp7ImA9WhZVEE0.&quot;"><id>tag:blogger.com,1999:blog-15626356.post-42494361135222072</id><published>2011-05-21T12:15:00.000-07:00</published><updated>2011-05-21T12:33:00.401-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-21T12:33:00.401-07:00</app:edited><title>A "No News is Good News" Tsunami Feed</title><content type="html">I have subscribed to the &lt;a href="http://wcatwc.arh.noaa.gov/"&gt;NOAA/NWS/West Coast and Alaska Tsunami Warning Center&lt;/a&gt;'s &lt;a href="http://wcatwc.arh.noaa.gov/rss/tsunamirss.xml"&gt;feed of ahead-of-time tsunami warnings&lt;/a&gt; for the U.S. West Coast, Alaska, and British Columbia coastal regions (&lt;a href="http://wcatwc.arh.noaa.gov/2011/05/21/lljefm/01/messagelljefm-01.htm"&gt;example information statement&lt;/a&gt;) for some time. Most, like this one, are "wolf-cry" statements stemming from some seismic activity somewhere that &lt;i&gt;won't&lt;/i&gt; generate any tsunami, marked with the all-important body phrase "The magnitude is such that a tsunami &lt;strong&gt;WILL NOT&lt;/strong&gt; be generated" - meaning I don't really care about them.&lt;br /&gt;
&lt;br /&gt;
Today I made a &lt;a href="http://pipes.yahoo.com/pipes/pipe.info?_id=25e365289cdbcf9c639d6b05854fc5d6"&gt;Yahoo pipe&lt;/a&gt;, filtering away those from the feed. Here is the resulting feed, containing only &lt;a href="http://pipes.yahoo.com/pipes/pipe.run?_id=25e365289cdbcf9c639d6b05854fc5d6&amp;_render=rss"&gt;positive tsunami warning statements&lt;/a&gt;. Behind the scenes, it's created by the simple YQL statement &lt;code&gt;select * from rss where url="http://wcatwc.arh.noaa.gov/rss/tsunamirss.xml" and description  like "%tsunami &amp;lt;strong&amp;gt;WILL NOT&amp;lt;/strong&amp;gt; be%"&lt;/code&gt; (there's some newline or similar after "be" in the original feed, and it doesn't seem like YQL does any whitespace normalization, but this matches well enough to filter the stuff).&lt;br /&gt;
&lt;br /&gt;
The resulting feed is my enrapturing contribution to today's supposed end of the world. You may note that the feed is currently (and hopefully still, by the time you read this :-) empty - which is, of course, good news. Enjoy!&lt;br /&gt;
&lt;br /&gt;
On a related hacker's note, it would be really handy to extend Google Reader with a "filter this feed" feature that created these more on the fly, without mucking about for an hour in the Yahoo Pipes interface, and then changed the old subscription to the new feed.&lt;img src="http://feeds.feedburner.com/~r/blogspot/xxBcs/~4/PcVyyaL0bk0" height="1" width="1"/&gt;</content><link rel="related" href="http://pipes.yahoo.com/pipes/pipe.run?_id=25e365289cdbcf9c639d6b05854fc5d6&amp;_render=rss" title="A &quot;No News is Good News&quot; Tsunami Feed" /><link rel="replies" type="application/atom+xml" href="http://ecmanaut.blogspot.com/feeds/42494361135222072/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=15626356&amp;postID=42494361135222072" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/15626356/posts/default/42494361135222072?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/15626356/posts/default/42494361135222072?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/xxBcs/~3/PcVyyaL0bk0/no-news-is-good-news-tsunami-feed.html" title="A &quot;No News is Good News&quot; Tsunami Feed" /><author><name>Johan Sundström</name><uri>http://www.blogger.com/profile/04076097346172610543</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://ecmanaut.blogspot.com/2011/05/no-news-is-good-news-tsunami-feed.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkQHQHgycCp7ImA9WhZWFUs.&quot;"><id>tag:blogger.com,1999:blog-15626356.post-7074935802337298378</id><published>2011-05-16T00:59:00.000-07:00</published><updated>2011-05-16T08:38:51.698-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-16T08:38:51.698-07:00</app:edited><title>Chrome + NaCl + libmodplug + ... = tracker modules on the web</title><content type="html">Some notes I took while looking into how to build a &lt;tt&gt;libmikmod_x86_32.nexe&lt;/tt&gt; and &lt;tt&gt;libmikmod_x86_64.nexe&lt;/tt&gt; to get Chrome tracker module playing support from javascript (the work seems to be done already in naclports) via NativeClient, for all the MOD, S3M, XM, IT, 669, AMF, AMS, DBM, DMF, DSM, FAR, MDL, MED, MTM, OKT, PTM, STM, ULT, UMX, MT2 and PSM formats:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;In a Chrome 11 profile, go to &lt;tt&gt;about:flags&lt;/tt&gt;, and click &lt;b&gt;Enable&lt;/b&gt; under "Native Client", and then the "Relaunch Now" button at the bottom (alternatively: start the session with the &lt;tt&gt;--enable-nacl&lt;/tt&gt; command-line flag)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://code.google.com/chrome/nativeclient/docs/download.html"&gt;Download the NaCl SDK&lt;/a&gt; (for Chrome 11, in my case; eventually the ABI will supposedly freeze and cover a wider range of versions)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dev.chromium.org/developers/how-tos/install-depot-tools"&gt;Download &lt;tt&gt;depot_tools&lt;/tt&gt;&lt;/a&gt;, extract it and &lt;tt&gt;export NACL_SDK_ROOT=$PWD&lt;/tt&gt; in that directory (&lt;a href="http://code.google.com/chrome/nativeclient/docs/technical_overview.html"&gt;technical overview here&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://code.google.com/p/naclports/wiki/HowTo_Checkout?tm=4"&gt;Check out &lt;tt&gt;naclports&lt;/tt&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Probably optional: comment out all the &lt;tt&gt;RunInstallScript&lt;/tt&gt; lines in &lt;tt&gt;naclports/src/packages/nacl-install-all-bitsize.sh&lt;/tt&gt; except the one you're interested in (in my case: &lt;tt&gt;RunInstallScript libmodplug-0.8.7 nacl-libmodplug-0.8.7.sh&lt;/tt&gt;)&lt;/li&gt;
&lt;li&gt;Run &lt;tt&gt;nacl-install-all-bitsize.sh 64&lt;/tt&gt; (or 32 for a 32-bit build), which, in my case, built &lt;tt&gt;$NACL_SDK_ROOT/toolchain/mac_x86/nacl64/usr/lib/libmodplug.a&lt;/tt&gt;&lt;!--

If you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the `-LLIBDIR'
flag during linking and do at least one of the following:
   - add LIBDIR to the `LD_RUN_PATH' environment variable
     during linking
   - use the `-Wl,--rpath -Wl,LIBDIR' linker flag

See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.

--&gt;&lt;/li&gt;
&lt;li&gt;About here my research petered out, as I found &lt;a href="http://www.enoie.net/nacltest/xm_player.html"&gt;this smaller hack for XM-only playback&lt;/a&gt; by some forthcoming Japanese fellow (&lt;a href="http://git.sourceforge.jp/view?p=nacltest/xmplayer.git"&gt;git repository here&lt;/a&gt;; &lt;a href="http://translate.google.com/translate?js=n&amp;prev=_t&amp;hl=en&amp;ie=UTF-8&amp;layout=2&amp;eotf=1&amp;sl=ja&amp;tl=en&amp;u=http%3A%2F%2Fgit.sourceforge.jp%2Fview%3Fp%3Dnacltest%2Fxmplayer.git"&gt;English translation of same page&lt;/a&gt; c/o Google Translate), which has basic functionality&lt;/li&gt;
&lt;li&gt;If you got curious about my original venue and proceeded further, I'd love to hear about it, especially if you managed to build the final nexe:s; do post a comment!&lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/xxBcs/~4/acqjrcizrgQ" height="1" width="1"/&gt;</content><link rel="related" href="http://www.enoie.net/nacltest/xm_player.html" title="Chrome + NaCl + libmodplug + ... = tracker modules on the web" /><link rel="replies" type="application/atom+xml" href="http://ecmanaut.blogspot.com/feeds/7074935802337298378/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=15626356&amp;postID=7074935802337298378" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/15626356/posts/default/7074935802337298378?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/15626356/posts/default/7074935802337298378?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/xxBcs/~3/acqjrcizrgQ/chrome-nacl-libmodplug-tracker-modules.html" title="Chrome + NaCl + libmodplug + ... = tracker modules on the web" /><author><name>Johan Sundström</name><uri>http://www.blogger.com/profile/04076097346172610543</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://ecmanaut.blogspot.com/2011/05/chrome-nacl-libmodplug-tracker-modules.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkUAR387fyp7ImA9WhZXFU0.&quot;"><id>tag:blogger.com,1999:blog-15626356.post-1066629977208526497</id><published>2011-05-04T02:03:00.000-07:00</published><updated>2011-05-04T02:10:46.107-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-04T02:10:46.107-07:00</app:edited><title>Github tag and branch labels</title><content type="html">I just made a little update to my &lt;a href="https://github.com/johan/github-improved/raw/master/unfold_commit_history.user.js"&gt;github improved!&lt;/a&gt; user script; now it shows you branch and tag labels in the commits view, like this:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-V9t9csi4e_s/TcEPv6usolI/AAAAAAAAAM8/cVz7nPEyjO8/s1600/Screen%2Bshot%2B2011-05-04%2Bat%2B00.14.20.png" imageanchor="1" style="clear: both; margin:0 auto 1em;"&gt;&lt;img border="0" height="162" width="200" src="http://3.bp.blogspot.com/-V9t9csi4e_s/TcEPv6usolI/AAAAAAAAAM8/cVz7nPEyjO8/s200/Screen%2Bshot%2B2011-05-04%2Bat%2B00.14.20.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
There's been some more mystery meat features slipping in there too somewhat unannounced; if you click a committer icon a little filter panel opens on top that lets you see how many commits in the view were by whom, and if you click one of those, hide those commits. I got the idea when I was playing with &lt;a href="https://chrome.google.com/extensions/detail/aeolcjbaammbkgaiagooljfdepnjmkfd"&gt;Autopatchwork&lt;/a&gt; at some point, unpaginating a whole repository's worth of commits and wanted to slice and dice the view a bit, get aggregate stats and the like. This is what Greasemonkey's early history (from &lt;a href="https://github.com/greasemonkey/greasemonkey/commits/0.8"&gt;0.8&lt;/a&gt; and back) looks like, in terms of authors (not committers) involved, for example:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-eEHfX71W8AU/TcEXnRkz5PI/AAAAAAAAANE/_VBwIEHlJ1U/s1600/gm-0.8.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="86" width="200" src="http://4.bp.blogspot.com/-eEHfX71W8AU/TcEXnRkz5PI/AAAAAAAAANE/_VBwIEHlJ1U/s200/gm-0.8.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Autopatchwork could use some more coverage on the English-speaking web, by the way, because of its neat way of aggregating user data from contributors. Instead of a dedicated backend server someone maintains for the script to work, it's using a wiki-like JSON database for public domain content: &lt;a href="service"&gt;Wedata.net&lt;/a&gt;; define your json schema and let anyone that wants to fill in, edit and co-maintain the data (here: unpagination url regexps and node xpaths). The editing process looks a bit &lt;a href="http://userscripts.org/topics/69730"&gt;like this&lt;/a&gt;. I am especially glad to have found it, as I've been wanting a service like that for a long time but not really wanted to host it, and having a public cloud sync point for mini-applications like this to update their localStorage copies of the data from is a neat trick.&lt;br /&gt;
&lt;br /&gt;
Anyway, happy githubbing! As with so many little features before it, I already can't fathom going back to a github without this feature (and I've only been using it since yesternight). It helps a lot seeing what went into which release at a glance, without doing all sorts of manual work. It would be nice for it to &lt;a href="https://github.com/johan/github-improved/issues/1"&gt;mark branch-off points&lt;/a&gt; too, but it would require some kind of merge-base type api end-point, for digging up where a branch's closest common ancestor is to all other branches. Maybe time for devising a neat response format and crafting a little api feature request.&lt;img src="http://feeds.feedburner.com/~r/blogspot/xxBcs/~4/8oB99c5Xe8Y" height="1" width="1"/&gt;</content><link rel="related" href="https://github.com/johan/github-improved/raw/master/unfold_commit_history.user.js" title="Github tag and branch labels" /><link rel="replies" type="application/atom+xml" href="http://ecmanaut.blogspot.com/feeds/1066629977208526497/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=15626356&amp;postID=1066629977208526497" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/15626356/posts/default/1066629977208526497?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/15626356/posts/default/1066629977208526497?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/xxBcs/~3/8oB99c5Xe8Y/github-tag-and-branch-labels.html" title="Github tag and branch labels" /><author><name>Johan Sundström</name><uri>http://www.blogger.com/profile/04076097346172610543</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-V9t9csi4e_s/TcEPv6usolI/AAAAAAAAAM8/cVz7nPEyjO8/s72-c/Screen%2Bshot%2B2011-05-04%2Bat%2B00.14.20.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://ecmanaut.blogspot.com/2011/05/github-tag-and-branch-labels.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DU8DQ30zfip7ImA9WhZSGU8.&quot;"><id>tag:blogger.com,1999:blog-15626356.post-3994444714320320130</id><published>2011-04-03T02:22:00.000-07:00</published><updated>2011-04-04T07:37:52.386-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-04T07:37:52.386-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="ruby" /><category scheme="http://www.blogger.com/atom/ns#" term="tools" /><title>gravatar.rb</title><content type="html">I made myself a little command-line tool &lt;a href="https://gist.github.com/raw/900312/c2ae65d0b3362e42cf3524084fc740d8027b3ef9/gravatar.rb"&gt;gravatar.rb&lt;/a&gt; today, which eats email addresses and outputs "gravatar-url email@address" lines, for all email addresses that has a customized gravatar created.&lt;br /&gt;
&lt;br /&gt;
It's fun to run &lt;code&gt;git log|gravatar&lt;/code&gt; for projects you've got checked out; here's &lt;a href="https://github.com/yui/yui3"&gt;yui3&lt;/a&gt;:&lt;br /&gt;
&lt;img style="margin: 0.5em; float: left;" src="https://secure.gravatar.com/avatar/05243ae612fb4dcfb151e08489f334b0?s=80" width="80" height="80" title="davglass / gmail.com"&gt;&lt;img style="margin: 0.5em; float: left;" src="https://secure.gravatar.com/avatar/683e9380d7cc0724a35dadfb4eeb142b?s=80" width="80" height="80" title="ryan / wonko.com"&gt;&lt;img style="margin: 0.5em; float: left;" src="https://secure.gravatar.com/avatar/4479397d42c17503323ae88bf8932e42?s=80" width="80" height="80" title="adamoore / yahoo-inc.com"&gt;&lt;img style="margin: 0.5em; float: left;" src="https://secure.gravatar.com/avatar/fc2ccaa63b7dd76df705d48b5468a45e?s=80" width="80" height="80" title="lsmith / yahoo-inc.com"&gt;&lt;img style="margin: 0.5em; float: left;" src="https://secure.gravatar.com/avatar/f3f746d4b8201c3692001cb8922fff98?s=80" width="80" height="80" title="matt.sweeney / yahoo.com"&gt;&lt;img style="margin: 0.5em; float: left;" src="https://secure.gravatar.com/avatar/45926e3669f5a09802a52e86529d5514?s=80" width="80" height="80" title="allenrabinovich / yahoo.com"&gt;&lt;img style="margin: 0.5em; float: left;" src="https://secure.gravatar.com/avatar/42327de520e674a6d1686845b30778d0?s=80" width="80" height="80" title="eduardo.lundgren / liferay.com"&gt;&lt;img style="margin: 0.5em; float: left;" src="https://secure.gravatar.com/avatar/e16471e70e174182f5db53cea5c572c6?s=80" width="80" height="80" title="pcavit / gmail.com"&gt;&lt;img style="margin: 0.5em; float: left;" src="https://secure.gravatar.com/avatar/c5e59f67101f60459b52161284605b9a?s=80" width="80" height="80" title="foxxtrot / foxxtrot.net"&gt;&lt;img style="margin: 0.5em; float: left;" src="https://secure.gravatar.com/avatar/27690fd3101effe494907ee7f30bbf81?s=80" width="80" height="80" title="eduardolundgren / gmail.com"&gt;&lt;img style="margin: 0.5em; float: left;" src="https://secure.gravatar.com/avatar/05a8346601d9cdd6a8b62a91f29cd771?s=80" width="80" height="80" title="me / reidburke.com"&gt;&lt;img style="margin: 0.5em; float: left;" src="https://secure.gravatar.com/avatar/af34a0de54b2b7a34cc6d7196ef12fc0?s=80" width="80" height="80" title="build / yuilibrary.com"&gt;&lt;img style="margin: 0.5em; float: left;" src="https://secure.gravatar.com/avatar/6960eab88e6e00020d2751e48019cd59?s=80" width="80" height="80" title="gmoothart / gmail.com"&gt;&lt;img style="margin: 0.5em; float: left;" src="https://secure.gravatar.com/avatar/e2da054104d4992438195d8bb02f431c?s=80" width="80" height="80" title="curtis / curtisharvey.com"&gt;&lt;img style="margin: 0.5em; float: left;" src="https://secure.gravatar.com/avatar/f071cb9c72c08020c83a0838b192145a?s=80" width="80" height="80" title="nzakas / yahoo-inc.com"&gt;&lt;img style="margin: 0.5em; float: left;" src="https://secure.gravatar.com/avatar/f9c6936e3a1c4e3d7995817d1f9baf9e?s=80" width="80" height="80" title="ericmiraglia / yahoo.com"&gt;&lt;img style="margin: 0.5em; float: left;" src="https://secure.gravatar.com/avatar/2e54bc99b92e95d0f56da3a7e7aa0e6d?s=80" width="80" height="80" title="ryan / ryancannon.com"&gt;&lt;img style="margin: 0.5em; float: left;" src="https://secure.gravatar.com/avatar/cf33841918d90fe941f522dde5ee4ff0?s=80" width="80" height="80" title="eferraiuolo / gmail.com"&gt;&lt;img style="margin: 0.5em; float: left;" src="https://secure.gravatar.com/avatar/8fa21a16e24905fba4413501e3afb36e?s=80" width="80" height="80" title="erikvvold / gmail.com"&gt;&lt;img style="margin: 0.5em; float: left;" src="https://secure.gravatar.com/avatar/b16b03a19c743c89c573b0af67d06ed1?s=80" width="80" height="80" title="floydian / phphorizons.com"&gt;&lt;img style="margin: 0.5em; float: left;" src="https://secure.gravatar.com/avatar/df4fd1f9aa463884decd65f5ea9d9584?s=80" width="80" height="80" title="kloots / yahoo-inc.com"&gt;&lt;img style="margin: 0.5em; float: left;" src="https://secure.gravatar.com/avatar/dea8cffd5294dcd41e75fdec4c2e604e?s=80" width="80" height="80" title="i / foohack.com"&gt;&lt;img style="margin: 0.5em; float: left;" src="https://secure.gravatar.com/avatar/ea69517363a0aabf9bf09ed7ce1c5ea3?s=80" width="80" height="80" title="mattesnider / gmail.com"&gt;&lt;img style="margin: 0.5em; float: left;" src="https://secure.gravatar.com/avatar/8233cc93c34d23ce58c0096fb07375c0?s=80" width="80" height="80" title="julien.lecomte / gmail.com"&gt;&lt;img style="margin: 0.5em; float: left;" src="https://secure.gravatar.com/avatar/ea077fdc95c2959ca28b052853b4175e?s=80" width="80" height="80" title="nicholas.c.zakas / nczonline.net"&gt;&lt;img style="margin: 0.5em; float: left;" src="https://secure.gravatar.com/avatar/fef48709416e18e4ccb263b248fd88e1?s=80" width="80" height="80" title="caridy / gmail.com"&gt;&lt;img style="margin: 0.5em; float: left;" src="https://secure.gravatar.com/avatar/a96c9331b6ebb3aa112aa7b5e9dad912?s=80" width="80" height="80" title="philip / bluesmoon.info"&gt;&lt;img style="margin: 0.5em; float: left;" src="https://secure.gravatar.com/avatar/cb952c516490d47a3946a5a7889e713d?s=80" width="80" height="80" title="natek / yahoo-inc.com"&gt;&lt;img style="margin: 0.5em; float: left;" src="https://secure.gravatar.com/avatar/d5c18055c50c5b34b0163e0bf0dbf59f?s=80" width="80" height="80" title="dav.glass / yahoo.com"&gt;&lt;img style="margin: 0.5em; float: left;" src="https://secure.gravatar.com/avatar/119d3c7cbf44bd80c473688ad63591b1?s=80" width="80" height="80" title="msweeney / yahoo-inc.com"&gt;&lt;br /&gt;
&lt;br /&gt;
(People showing up more than once either have multiple email addresses registered with gravatar that they commit via or borrow someone else's picture. :-)&lt;img src="http://feeds.feedburner.com/~r/blogspot/xxBcs/~4/EphO9XZbWx4" height="1" width="1"/&gt;</content><link rel="related" href="https://gist.github.com/raw/900312/c2ae65d0b3362e42cf3524084fc740d8027b3ef9/gravatar.rb" title="gravatar.rb" /><link rel="replies" type="application/atom+xml" href="http://ecmanaut.blogspot.com/feeds/3994444714320320130/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=15626356&amp;postID=3994444714320320130" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/15626356/posts/default/3994444714320320130?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/15626356/posts/default/3994444714320320130?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/xxBcs/~3/EphO9XZbWx4/gravatarrb.html" title="gravatar.rb" /><author><name>Johan Sundström</name><uri>http://www.blogger.com/profile/04076097346172610543</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://ecmanaut.blogspot.com/2011/04/gravatarrb.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DU4FQ3czcSp7ImA9WhZSGU8.&quot;"><id>tag:blogger.com,1999:blog-15626356.post-7223986581350964714</id><published>2011-03-29T00:46:00.001-07:00</published><updated>2011-04-04T07:38:32.989-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-04T07:38:32.989-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="mac" /><category scheme="http://www.blogger.com/atom/ns#" term="perl" /><title>Installing perl modules on Snow Leopard and Homebrew</title><content type="html">&lt;b&gt;Preamble:&lt;/b&gt; this post is a great read if you really want to have your Perl stuff in &lt;code&gt;/usr/local&lt;/code&gt;, instead of in &lt;code&gt;/Library/Perl&lt;/code&gt;, the &lt;a href="https://github.com/mxcl/homebrew/wiki/Gems%2C-Eggs-and-Perl-Modules"&gt;MacOS X way&lt;/a&gt;. Otherwise, maybe not so much! (The error I had stumbled on, which made me think cpan didn't just work was, apparently, that I at some point had used sudo cpan, and gotten permissions on things out of whack. If cpan was a little bit more helpful, chances are I would have figured it out sooner -- but let's not toss a blog post that was fun to write and still has a few useful nuggets, despite being built on an otherwise shoddy fundament. :-)&lt;br /&gt;
&lt;br /&gt;
First up: this isn't any more &lt;a href="http://mxcl.github.com/homebrew/"&gt;Homebrew&lt;/a&gt; specific than that I use the perl Apple ships with Snow Leopard (5.10 at this time of writing, for 10.6.7 - I'm on a Macbook Air myself), with all its built-in &lt;a href="http://www.manpagez.com/man/1/perlmacosx/"&gt;DTrace and MacOS integration goodness&lt;/a&gt;. Read that fine page for authoritative data; I neither am not pretend to be a perl savant.&lt;br /&gt;
&lt;br /&gt;
Using the system perl is how Homebrew prefers it – unlike some other packaging systems I shall not mention here, as a service to other fine people trying to google for "perl mac snow leopard -this -that". Should you for any reason wish to mention those in comments on this post, you may call them "Funk" and "Warts" (or "MacWarts"). I may delete your comment if you don't. (Nothing personal; just sayin'. And you might as well not, anyway, I am unlikely to be able to help you.)&lt;br /&gt;
&lt;br /&gt;
Anyway, so I want my perl modules installed in &lt;code&gt;/usr/local&lt;/code&gt;, and I want them in my &lt;code&gt;@INC&lt;/code&gt; when I run &lt;code&gt;/usr/bin/perl&lt;/code&gt; and it's a shame that the system perl only looks in any of these, right?&lt;br /&gt;
&lt;pre&gt;/Library/Perl/Updates/5.10.0/darwin-thread-multi-2level
/Library/Perl/Updates/5.10.0
/System/Library/Perl/5.10.0/darwin-thread-multi-2level
/System/Library/Perl/5.10.0
/Library/Perl/5.10.0/darwin-thread-multi-2level
/Library/Perl/5.10.0
/Network/Library/Perl/5.10.0/darwin-thread-multi-2level
/Network/Library/Perl/5.10.0
/Network/Library/Perl
/System/Library/Perl/Extras/5.10.0/darwin-thread-multi-2level
/System/Library/Perl/Extras/5.10.0&lt;/pre&gt;&lt;br /&gt;
Wrong! (I &lt;i&gt;told&lt;/i&gt; you: read &lt;a href="http://www.manpagez.com/man/1/perlmacosx/"&gt;this fine manual written by knowledgeable people&lt;/a&gt;!) Still, a neat thing they describe is that the MacOS X perl installation will happily read &lt;code&gt;/Library/Perl/5.10.0/AppendToPath&lt;/code&gt; and &lt;code&gt;/Library/Perl/5.10.0/PrependToPath&lt;/code&gt; and append / prepend any directories they list (one line per path, normal unix style) to &lt;code&gt;@INC&lt;/code&gt;. Or, of course, any other version than 5.10.0 – &lt;code&gt;perl -v&lt;/code&gt; will tell you what you've got installed. So, as root, I appended &lt;code&gt;/usr/local/lib/perl5/site_perl/&lt;/code&gt; to my &lt;code&gt;AppendToPath&lt;/code&gt;.&lt;br /&gt;
&lt;br /&gt;
Next up, assuming you've already made a mess trying to install stuff with cpan (I had), you may want to do what I did, which is &lt;code&gt;rm -rf ~/.cpan&lt;/code&gt; (which permanently nukes it; should you want to be able to undo that, you of course instead move it aside somewhere – you're solely responsible for your actions here, as always). Then run &lt;code&gt;cpan&lt;/code&gt;. It'll ask you tons of questions you might not know the answer to any better than I did if you say no, or give slightly okay defaults if you say yes. Some frustrating experimentation later, I came down with this recipe, which worked for me; first yes it, and then when you get the prompt, type &lt;code&gt;o conf&lt;/code&gt;. It'll probably look a bit like this, if the defaults remain about the same:&lt;br /&gt;
&lt;pre&gt;cpan[1]&amp;gt; o conf
$CPAN::Config options from '/Users/jhs/.cpan/CPAN/MyConfig.pm':
    commit             [Commit changes to disk]
    defaults           [Reload defaults from disk]
    help               [Short help about 'o conf' usage]
    init               [Interactive setting of all options]

    applypatch         []
    auto_commit        [0]
    build_cache        [100]
    build_dir          [/Users/jhs/.cpan/build]
    build_dir_reuse    [1]
    build_requires_install_policy [ask/yes]
    bzip2              [/usr/bin/bzip2]
    cache_metadata     [1]
    check_sigs         [0]
    colorize_debug     undef
    colorize_output    undef
    colorize_print     undef
    colorize_warn      undef
    commandnumber_in_prompt [1]
    commands_quote     undef
    cpan_home          [/Users/jhs/.cpan]
    curl               [/usr/bin/curl]
    dontload_hash      undef
    dontload_list      undef
    ftp                [/usr/bin/ftp]
    ftp_passive        [1]
    ftp_proxy          []
    getcwd             [cwd]
    gpg                []
    gzip               [/usr/bin/gzip]
    histfile           [/Users/jhs/.cpan/histfile]
    histsize           [100]
    http_proxy         []
    inactivity_timeout [0]
    index_expire       [1]
    inhibit_startup_message [0]
    keep_source_where  [/Users/jhs/.cpan/sources]
    load_module_verbosity [v]
    lynx               []
    make               [/usr/bin/make]
    make_arg           []
    make_install_arg   []
    make_install_make_command [/usr/bin/make]
    makepl_arg         []
    mbuild_arg         []
    mbuild_install_arg []
    mbuild_install_build_command [./Build]
    mbuildpl_arg       []
    ncftp              []
    ncftpget           []
    no_proxy           []
    pager              [/usr/bin/less]
    password           undef
    patch              [/usr/bin/patch]
    prefer_installer   [MB]
    prefs_dir          [/Users/jhs/.cpan/prefs]
    prerequisites_policy [ask]
    proxy_pass         undef
    proxy_user         undef
    randomize_urllist  undef
    scan_cache         [atstart]
    shell              [/bin/zsh]
    show_unparsable_versions [0]
    show_upload_date   [0]
    show_zero_versions [0]
    tar                [/usr/bin/tar]
    tar_verbosity      [v]
    term_is_latin      [1]
    term_ornaments     [1]
    test_report        [0]
    unzip              [/usr/bin/unzip]
    urllist           
    use_sqlite         [0]
    username           undef
    wait_list          undef
    wget               [/usr/local/bin/wget]
    yaml_load_code     [0]
    yaml_module        [YAML]


cpan[2]&amp;gt;&lt;/pre&gt;&lt;br /&gt;
Then paste this little snippet, which sets most things right (it's a good decade to use a UTF-8 terminal):&lt;br /&gt;
&lt;pre&gt;o conf term_is_latin 0
o conf check_sigs 1
o conf make_arg -j3
o conf make_install_arg -j3
o conf makepl_arg PREFIX=/usr/local
o conf mbuildpl_arg --install_base /usr/local
o conf commit&lt;/pre&gt;&lt;br /&gt;
This will have perl use two cores when compiling modules, and use &lt;code&gt;Module::Signature&lt;/code&gt; if you install it, which seemed like a nice enough idea (at least if you have gpg installed; you may want to skip the check_sigs part, or install it first, if not -- via &lt;code&gt;brew install gpgme&lt;/code&gt; for instance). And, most importantly, it'll put stuff in &lt;code&gt;/usr/local&lt;/code&gt; at installation time, so perl will find it at invocation time. (Some day, that might just work right out of the box, in MacOS too.)&lt;br /&gt;
&lt;br /&gt;
And that's it. Try it with &lt;code&gt;cpan Module::Signature&lt;/code&gt; for instance, if you enabled that and you'll eventually end up with a fatter &lt;code&gt;/usr/local/lib/perl5/site_perl&lt;/code&gt;. You are encouraged to drop other helpful tips here, especially if you know a thing or two about perl or cpan that I totally should have mentioned. Happy hacking! :-)&lt;img src="http://feeds.feedburner.com/~r/blogspot/xxBcs/~4/Z9X7Mb-7R_o" height="1" width="1"/&gt;</content><link rel="related" href="http://www.manpagez.com/man/1/perlmacosx/" title="Installing perl modules on Snow Leopard and Homebrew" /><link rel="replies" type="application/atom+xml" href="http://ecmanaut.blogspot.com/feeds/7223986581350964714/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=15626356&amp;postID=7223986581350964714" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/15626356/posts/default/7223986581350964714?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/15626356/posts/default/7223986581350964714?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/xxBcs/~3/Z9X7Mb-7R_o/installing-perl-modules-on-snow-leopard.html" title="Installing perl modules on Snow Leopard and Homebrew" /><author><name>Johan Sundström</name><uri>http://www.blogger.com/profile/04076097346172610543</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://ecmanaut.blogspot.com/2011/03/installing-perl-modules-on-snow-leopard.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkQFR38ycSp7ImA9Wx9WEE4.&quot;"><id>tag:blogger.com,1999:blog-15626356.post-1340572036312610847</id><published>2011-01-14T00:50:00.000-08:00</published><updated>2011-01-14T10:38:36.199-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-01-14T10:38:36.199-08:00</app:edited><title>Musings on DNA, code and otherwise</title><content type="html">From college days, I recall microbiology as one of the more fascinating fields I never opted to pursue, but still developed a latent interest in. The evolved, highly complex and cross-connected execution context of biology, at the deepest levels where it meets (or indeed &lt;i&gt;is&lt;/i&gt;) the realities of chemistry and physics speaks to my geek genes. There are so many levels of exciting, beautiful and interesting stories, events and developments woven together and buried in genome! Not to mention it is open source!&lt;br /&gt;
&lt;br /&gt;
You want to grok something? &lt;abbr title="Use the source, Luke"&gt;UTSL&lt;/abbr&gt;! If you don't yet understand it, it's because you are not knowledgeable enough. Go learn! Experiment. Think hard. Figure it out. And then share what you learned, so others can reach longer, make it do more, be more efficient, go faster, taste better, or what have you. I think choosing mad computer science over mad genetics was more of a cultural thing gut draw towards openness; away from the lock-ins of lawyers of looming heavy corporations protecting the intellectual off-spring stemming from the money invested into powering their geeks' forays into the unknown, and toward the almost open eco system of what today amounts to the web and places like github, where people promiscuously and chaotically spin off of each others' work making stuff better together, for fun and profit.&lt;br /&gt;
&lt;br /&gt;
But back to genetic code, as inspired by a read of an article on &lt;a href="http://discovermagazine.com/2010/jun/03-the-insanity-virus"&gt;MS, schizophrenia and bipolar disorder as related to endogenous retroviruses&lt;/a&gt; (meaning stuff we all carry as common heritage, though not activated in most of us). One of the things we were taught in my classes was about the huge amount of introns (DNA between genes that is seemingly not active, as it isn't observed to ever get transcripted into proteins -- which is essentially how microbiological code execution happens) observed in all living organisms (about 98% of human DNA is &lt;a href="http://en.wikipedia.org/wiki/Noncoding_DNA"&gt;non-coding DNA&lt;/a&gt;). Of course the depth level of the insights we absorbed were rather meagre, and although omnipresent easy-access Wikipedia was not yet around, it felt fairly obvious that the rest, at the very least, would end up having all sorts of other functions or effects under conditions and circumstances that would relate to it somehow. If you have ever researched (or exploited) a buffer overflow in some program, you probably know that wherever the program pointer accidentally ends up, whatever junk or data happens to be in that memory region is suddenly, for all intents and purposes (or despite them :-), is now code! Maybe it will do something interesting. Or nefarious. Probably nefarious, really.&lt;br /&gt;
&lt;br /&gt;
Biology, chemistry and physics, of course, just add a gazillion more dimensions to "functions and effects of things", while also imposing a bus-load of peculiar constraints, and introducing still more environmental conditions from the rather chaotic virtual machine of physics, chemistry and biology (being three different zoom levels at which things happen to shoot your code in the foot) combined.&lt;br /&gt;
&lt;br /&gt;
If you thought debugging code is hard, it's actually a delightful walk in the park, for the most part -- free of all sorts of concerns like the ethics of feeding useful test arrays into your debugger, that your test subjects can't keep dying all the time until you figure it out, and so on, and that we're probably not debugging software that co-evolved on a planetary scale, over a couple of billion years, but was probably caused by, at the very most, a couple of decades worth of ingenuity from probably less than thousands (or at most millions) of humans, all more or less acting with actual intents, often worthy of words like "design" and "intent". We're kind of lucky, that way! And oftentimes, the whole code base is even your very own damn fault! And you could even know full well what every line of your code is supposed to do, even though you might not yet have discovered all the things it should probably also do to work under the conditions it'll be subject to when unforgiving users run it. (Even yourself!)&lt;br /&gt;
&lt;br /&gt;
I wonder how far into the future we have to go to see iLife speaking to the creative class doing justice to its name, providing us with the tools to be creative with the workings of micro- (or, for that matter, even macro-)organisms, in the same manner it's letting today's happy amateurs go wild with arts like graphics, music and video. Lots of people have rather rigid ideas about what amounts to art, science, work, life style, communication and so many other arbitrary things you can do for whichever reasons propel you, based, among other things, on rules, rulers or methods used in each field, motivations behind them, et cetera. Try breaking a few; you end up in far more interesting places. And make and bring friends, along the way!&lt;img src="http://feeds.feedburner.com/~r/blogspot/xxBcs/~4/PiOUPgvqRTU" height="1" width="1"/&gt;</content><link rel="related" href="http://discovermagazine.com/2010/jun/03-the-insanity-virus" title="Musings on DNA, code and otherwise" /><link rel="replies" type="application/atom+xml" href="http://ecmanaut.blogspot.com/feeds/1340572036312610847/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=15626356&amp;postID=1340572036312610847" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/15626356/posts/default/1340572036312610847?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/15626356/posts/default/1340572036312610847?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/xxBcs/~3/PiOUPgvqRTU/musings-on-dna-code-and-otherwise.html" title="Musings on DNA, code and otherwise" /><author><name>Johan Sundström</name><uri>http://www.blogger.com/profile/04076097346172610543</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://ecmanaut.blogspot.com/2011/01/musings-on-dna-code-and-otherwise.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkcFQ3g4eyp7ImA9WhZSGU8.&quot;"><id>tag:blogger.com,1999:blog-15626356.post-3334980042714149346</id><published>2011-01-09T01:06:00.001-08:00</published><updated>2011-04-04T07:40:12.633-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-04T07:40:12.633-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="opera extensions" /><category scheme="http://www.blogger.com/atom/ns#" term="chrome extensions" /><category scheme="http://www.blogger.com/atom/ns#" term="emacs" /><category scheme="http://www.blogger.com/atom/ns#" term="firefox extensions" /><title>Reading Chrome, Firefox and Opera extensions in Emacs</title><content type="html">If you're a fan of emacs' archive-mode that lets you load &lt;a href="http://en.wikipedia.org/wiki/ZIP_(file_format)"&gt;zip files&lt;/a&gt; and the like as it lets you load regular directories, and know that Firefox xpi, Chrome crx and Opera oex extensions are really just thinly wrapped zip files under the hood, you might expect Emacs to grok them, just the same. I did, and was a little surprised when it didn't plain work. (So maybe I'm running an old Emacs build?)&lt;br /&gt;
&lt;br /&gt;
Anyway, I looked into the matter and did a little poking about to see what setup would do the trick. In the case of Firefox and Opera, it's really easy, as the xpi and oex "formats" only amount to changing the filename extension and making sure you have the right files in there -- so all you have to do is make sure that &lt;code&gt;("\\.xpi\\'" . archive-mode)&lt;/code&gt; exists in your &lt;code&gt;auto-mode-alist&lt;/code&gt;, and &lt;code&gt;("\\.xpi\\'" . no-conversion)&lt;/code&gt; in your &lt;code&gt;auto-coding-alist&lt;/code&gt; (there is a little snippet for your &lt;code&gt;.emacs&lt;/code&gt; at the end of this post), and the corresponding oex variant.&lt;br /&gt;
&lt;br /&gt;
In the Chrome case (which prepends a &lt;a href="http://code.google.com/chrome/extensions/crx.html"&gt;Chrome header&lt;/a&gt; with a format version, an RSA public key and signature from the extension author), besides the corresponding crx change for same variables, I also had to patch the &lt;code&gt;lisp/arc-mode.el&lt;/code&gt; file lightly:&lt;br /&gt;
&lt;br /&gt;
&lt;iframe src="http://pastebin.com/embed_iframe.php?i=h2TUYMxC" style="border: none; width: 100%"&gt;&lt;a href="http://pastebin.com/h2TUYMxC"&gt;arc-mode.el.patch at pastebin&lt;/a&gt;&lt;/iframe&gt;&lt;br /&gt;
&lt;br /&gt;
If you try loading a crx and find it already works, someone upstream already applied the same or a better patch than mine to your installation, but otherwise, read on. To find where it is on your system, type &lt;code&gt;C-h archive-mode &amp;lt;return&amp;gt;&lt;/code&gt; and follow the &lt;code&gt;archive-mode is a compiled Lisp function in `&lt;b&gt;arc-mode.el&lt;/b&gt;'.&lt;/code&gt; link, apply the patch and &lt;code&gt;M-x byte-compile-file&lt;/code&gt; the result again.&lt;br /&gt;
&lt;br /&gt;
The &lt;code&gt;.emacs&lt;/code&gt; snippet that makes it all kick in automagically:&lt;br /&gt;
&lt;br /&gt;
&lt;iframe src="http://pastebin.com/embed_iframe.php?i=NajyvP9w" style="border: none; width: 100%"&gt;&lt;a href="http://pastebin.com/NajyvP9w"&gt;.emacs snippet at pastebin&lt;/a&gt;&lt;/iframe&gt;&lt;br /&gt;
&lt;br /&gt;
Note that for the Chrome extension case, you won't be able to edit and save any of the contents in place, as you can with plain zip (xpi, oex) files; the magic to remove/re-add public keys and signatures will be somebody else's late Saturday hack to complete. :) Enjoy!&lt;img src="http://feeds.feedburner.com/~r/blogspot/xxBcs/~4/uSV5YPtXNiE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://ecmanaut.blogspot.com/feeds/3334980042714149346/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=15626356&amp;postID=3334980042714149346" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/15626356/posts/default/3334980042714149346?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/15626356/posts/default/3334980042714149346?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/xxBcs/~3/uSV5YPtXNiE/reading-chrome-firefox-and-opera.html" title="Reading Chrome, Firefox and Opera extensions in Emacs" /><author><name>Johan Sundström</name><uri>http://www.blogger.com/profile/04076097346172610543</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://ecmanaut.blogspot.com/2011/01/reading-chrome-firefox-and-opera.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkcDRXk-fip7ImA9WhZSGU8.&quot;"><id>tag:blogger.com,1999:blog-15626356.post-9030700602642742326</id><published>2010-12-26T16:13:00.000-08:00</published><updated>2011-04-04T07:41:14.756-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-04T07:41:14.756-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="reference" /><category scheme="http://www.blogger.com/atom/ns#" term="Firebug" /><title>Vintage Firefox</title><content type="html">When I occasionally need to check how far back a feature was introduced in Firefox, it usually turns out I only have the last few versions installed, and takes a while before I find where mozilla.org hit them, so here goes: a complete archive of the latest (mac -- tweak the urls or browse yourself for Linux, Windows or otherwise) release of every major version of Firefox from 0.8 to date (at current time of writing, 3.6.13 is the most recent Firefox released) off of &lt;a href="ftp://ftp.mozilla.org/pub/mozilla.org/firefox/releases/"&gt;ftp://ftp.mozilla.org/pub/mozilla.org/firefox/releases/&lt;/a&gt;, where mozilla.org hosts them, and the Firebug releases you need to do any useful web development work with them:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="ftp://ftp.mozilla.org/pub/mozilla.org/firefox/releases/4.0b8/mac/en-US/Firefox%204.0%20Beta%208.dmg"&gt;Firefox 4.0 beta 8&lt;/a&gt; (Gecko 2 / &lt;a href="http://getfirebug.com/releases/firebug/1.7X/firebug-1.7X.0a7.xpi" title="Firefox 3.6 .. 4.0.* | any Toolkit 1.9.2 .. 2.0.0.* application"&gt;Firebug 1.7X.0a7&lt;/a&gt;)&lt;br /&gt;
Note: as neither of is released yet, consider both links outdated when you read this (the Firebug xpi especially is in development, as hinted by the X)&lt;/li&gt;
&lt;li&gt;&lt;a href="ftp://ftp.mozilla.org/pub/mozilla.org/firefox/releases/3.6.13/mac/en-US/Firefox%203.6.13.dmg"&gt;Firefox 3.6.13&lt;/a&gt; (Gecko 1.9.2 / &lt;a href="http://getfirebug.com/releases/firebug/1.6/firebug-1.6.0.xpi" title="Firefox 3.6 .. 3.6.*"&gt;Firebug 1.6.0&lt;/a&gt; or &lt;a href="http://getfirebug.com/releases/firebug/1.5/firebug-1.5.4.xpi" title="Firefox 3.5 .. 3.6.* | any Toolkit 1.9.1 .. 1.9.2.* application"&gt;1.5.4&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href="ftp://ftp.mozilla.org/pub/mozilla.org/firefox/releases/3.5.16/mac/en-US/Firefox%203.5.16.dmg"&gt;Firefox 3.5.16&lt;/a&gt; (Gecko 1.9.1 / &lt;a href="http://getfirebug.com/releases/firebug/1.5/firebug-1.5.4.xpi" title="Firefox 3.5 .. 3.6.* | any Toolkit 1.9.1 .. 1.9.2.* application"&gt;Firebug 1.5.4&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href="ftp://ftp.mozilla.org/pub/mozilla.org/firefox/releases/3.0.19-real-real/mac/en-US/Firefox%203.0.19.dmg"&gt;Firefox 3.0.19&lt;/a&gt; (Gecko 1.9 / &lt;a href="http://getfirebug.com/releases/firebug/1.4/firebug-1.4.5.xpi" title="Firefox 3.0 .. 3.6.*"&gt;Firebug 1.4.5&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href="ftp://ftp.mozilla.org/pub/mozilla.org/firefox/releases/2.0.0.20/mac/en-US/Firefox%202.0.0.20.dmg"&gt;Firefox 2.0.0.20&lt;/a&gt; (Gecko 1.8.1 / &lt;a href="http://getfirebug.com/releases/firebug/1.3/firebug-1.3.4b2.xpi" title="Firefox 1.5 .. 3.9"&gt;Firebug 1.3.4b2&lt;/a&gt;, &lt;a href="http://getfirebug.com/releases/firebug/1.2/firebug-1.2.0.xpi" title="Firefox 1.5 .. 3.0.*"&gt;1.2.0&lt;/a&gt; or &lt;a href="Firefox 1.5 .. 2.0.0.*; last Joe Hewitt release"&gt;Firebug 1.0.5&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href="ftp://ftp.mozilla.org/pub/mozilla.org/firefox/releases/1.5.0.12/mac/en-US/Firefox%201.5.0.12.dmg"&gt;Firefox 1.5.0.12&lt;/a&gt; (Gecko 1.8 / &lt;a href="http://getfirebug.com/releases/firebug1.05.xpi" title="Firefox 1.5 .. 2.0.0.*; last Joe Hewitt release"&gt;Firebug 1.05&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href="ftp://ftp.mozilla.org/pub/mozilla.org/firefox/releases/1.0.8/mac/en-US/Firefox%201.0.8.dmg"&gt;Firefox 1.0.8&lt;/a&gt; (Gecko 1.7)&lt;/li&gt;
&lt;li&gt;&lt;a href="ftp://ftp.mozilla.org/pub/mozilla.org/firefox/releases/0.9.3/firefox-0.9.3-mac.dmg.gz"&gt;Firefox 0.9.3&lt;/a&gt; (Gecko 0.9)&lt;/li&gt;
&lt;li&gt;&lt;a href="ftp://ftp.mozilla.org/pub/mozilla.org/firefox/releases/0.8/firefox-0.8-mac.dmg.gz"&gt;Firefox 0.8&lt;/a&gt; (Gecko 0.8)&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
(Corresponding Gecko and Firebug versions, the second and third most messy to find Firefox entity, from the &lt;a href="https://developer.mozilla.org/en/Gecko"&gt;Gecko page on MDC&lt;/a&gt; and the install.rdf of the corresponding Firebug xpi:s archived at &lt;a href="http://getfirebug.com/"&gt;getfirebug.com&lt;/a&gt;.)&lt;br /&gt;
&lt;br /&gt;
Never ever download and install Firefox from any other site! There is a huge, shady "pay per install" market of people bundling other people's software with malware (bot nets, typically); read all about it from &lt;a href="http://www.symantec.com/content/en/us/enterprise/media/security_response/whitepapers/pay_per_install.pdf"&gt;Symantec&lt;/a&gt; (pdf) or &lt;a href="http://www.blackhat.com/presentations/bh-dc-10/Stevens_Kevin/BlackHat-DC-2010-Stevens-Underground-wp.pdf" title="The Underground Economy of the Pay-Per-Install (PPI) Business"&gt;Kevin Stevens&lt;/a&gt; (also pdf, the latter from &lt;a href="http://www.blackhat.com/html/bh-dc-10/bh-dc-10-briefings.html"&gt;Black Hat DC 2010&lt;/a&gt;). This goes for all executable programs you download and install on your machine; if you have no reason to trust the source, get it from a source you do trust.&lt;img src="http://feeds.feedburner.com/~r/blogspot/xxBcs/~4/S5lj0w7q9Ps" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://ecmanaut.blogspot.com/feeds/9030700602642742326/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=15626356&amp;postID=9030700602642742326" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/15626356/posts/default/9030700602642742326?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/15626356/posts/default/9030700602642742326?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/xxBcs/~3/S5lj0w7q9Ps/vintage-firefox.html" title="Vintage Firefox" /><author><name>Johan Sundström</name><uri>http://www.blogger.com/profile/04076097346172610543</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://ecmanaut.blogspot.com/2010/12/vintage-firefox.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkcASXs_fSp7ImA9WhZSGU8.&quot;"><id>tag:blogger.com,1999:blog-15626356.post-7125742892016250691</id><published>2010-12-12T00:40:00.000-08:00</published><updated>2011-04-04T07:40:48.545-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-04T07:40:48.545-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="opera extensions" /><title>Opera 11 extensions @ Add-on-Con</title><content type="html">I attended &lt;a href="http://add-on-con.com/"&gt;Add-on-Con&lt;/a&gt; this year again (I think I missed last year's), and figured I should sum up some of the interesting and/or useful stuff I picked up on while there. What I found most gratifying was the upcoming &lt;a href="http://www.opera.com/addons/extensions/develop/"&gt;Opera (11) add-on API&lt;/a&gt;, which takes on the same approach as the Chrome and Safari herd, with the clean, HTML5 / postMessage / content script based design we have grown to expect, with optional background and popup pages. (Mozilla kind of wants to get there too, but does not expect to have anything remotely near it for at least another year, and I don't think it's even on any road maps yet.)&lt;br /&gt;
&lt;br /&gt;
In Opera's current version, they don't go quite as far as does Chrome with its process separation, so an extension's popup can actually read from and write to &lt;code&gt;localStorage&lt;/code&gt; from the same origin as its background page (which lets you simplify the message passing a little if you're not aiming for easy porting). Your content script runs in its own global object, but it has a &lt;code&gt;window&lt;/code&gt; reference to the current window object, as the page sees it, and in the interest of not automatically leaking your script's guts into the page's global scope, it is not in the inheritance chain, so you actually have to use long references like &lt;code&gt;window.document&lt;/code&gt; and &lt;code&gt;window.localStorage&lt;/code&gt; to access them. (I tried assigning &lt;code&gt;this.__proto__ = window;&lt;/code&gt;, which in theory should import all window properties in my content script's scope, and while that seemed to allow the former, it still failed on the latter, so I guess I hit unsupported stuff or beta bugs.)&lt;br /&gt;
&lt;br /&gt;
To try it out, I made my &lt;a href="https://github.com/johan/github-improved/"&gt;github improved&lt;/a&gt; user script an &lt;a href="https://addons.opera.com/addons/extensions/details/github-improved/"&gt;Opera 11 extension&lt;/a&gt;. Run &lt;code&gt;rake&lt;/code&gt; to build the zipped-up oex from the content script if you &lt;a href="https://github.com/johan/github-improved/"&gt;check out or fork the codebase&lt;/a&gt;, which puts the content script in &lt;code&gt;includes/&lt;/code&gt; (all scripts in &lt;code&gt;includes/&lt;/code&gt; with a &lt;code&gt;// ==UserScript==&lt;/code&gt; block with Greasemonkey-style &lt;code&gt;@include&lt;/code&gt; / &lt;code&gt;@exclude&lt;/code&gt; rules run, not at the &lt;code&gt;DOMContentLoaded&lt;/code&gt; event, but at page start, so you have to set your own &lt;code&gt;DOMContentLoaded&lt;/code&gt; listener in a browser forked section if you want to execute under the same page conditions under Opera as in Firefox or a Chrome content script set to load at page ready).&lt;br /&gt;
&lt;br /&gt;
Touting standards, Opera decided that a browser extension is essentially a Widget, and reused the &lt;a href="http://www.w3.org/TR/widgets/"&gt;W3C Widget standard&lt;/a&gt; they helped coin a while back, making its manifest sit in &lt;code&gt;config.xml&lt;/code&gt; in the oex (a zip file) root directory (and emphasized that it also means you have to have an &lt;code&gt;index.html&lt;/code&gt; next to it – the background page – but that it can be empty, if you like). For instance:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;
&amp;lt;widget xmlns="http://www.w3.org/ns/widgets" version="1.0.0-0"&amp;gt;
  &amp;lt;name&amp;gt;Github improved&amp;lt;/name&amp;gt;
  &amp;lt;icon src="icon.png"/&amp;gt;
  &amp;lt;author href="http://ecmanaut.blogspot.com/"&amp;gt;Johan Sundström&amp;lt;/author&amp;gt;
  &amp;lt;description xml:lang="en"&amp;gt;Adds github changeset unfolding and other site improvements.&amp;lt;/description&amp;gt;
&amp;lt;/widget&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
This also means that you can use Widget storage and config-based preference init, if you like. It indeed even seems to be the recommended way, as that gets you unlimited storage (actually: the same total cap Opera sets for itself globally), whereas your background page's &lt;code&gt;localStorage&lt;/code&gt; gets subjected to the same arbitrary per-domain storage size cap that web sites are.&lt;br /&gt;
&lt;br /&gt;
As for extension distribution, they of course have their own extension gallery you may want to submit your things to, and like all human-driven approval processes, they have a slightly anal process to get through first. Essentially, the less you can state about your add-on, the fewer opportunities you'll have to fail their test criteria; I was advised by the presenters not to add an add-on homepage, for example.&lt;br /&gt;
&lt;br /&gt;
Currently, every submission attempt of yours in the approval process requires you to update your version number, so you can't aim for releasing a final 1.0 and treat all the attempts on the way there as release candidate 1 through N; my test add-on went through three revisions before coming out, and ended up named 1.0.0-0 in the end. It also was required to list change notes, that are reflected on the download page even when for an add-on that never existed before. Badly implemented good intentions also featured in the insistent numerous-stage wizard walking you through many steps every time (including screen shots, icons, et c), but there is at least the option to copy data from a previous version.&lt;br /&gt;
&lt;br /&gt;
I think I may make Opera extensions of some of the extension-worthy hacks I do, but having tried the Chrome extension gallery's really smooth process, showing how it should be done, I don't think I'll have the patience to jump through Opera's hoops very often unless they improve notably.&lt;br /&gt;
&lt;br /&gt;
To me, the bottom line is that Opera's add-on system doesn't make it prohibitively difficult to support Opera too, if you are already making an add-on for Chrome that does not rely on lots of deeper-integration Chrome API:s. It still surprises me that while they have the best technical user javascript implementation (and first too) a browser has ever had, they gave it the worst UI (a config switch listing a directory into which you yourself drop user scripts manually, after having modded them to add a &lt;code&gt;DOMContentLoaded&lt;/code&gt; event listener to start the main part of the script) ever. Their js hooks still thorougly beat both Greasemonkey and Chrome, yet the lack of installation when visiting a &lt;code&gt;*.user.js&lt;/code&gt; file locks that feature set in for only the really expert of browser users.&lt;img src="http://feeds.feedburner.com/~r/blogspot/xxBcs/~4/9Nk1yawhPs4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://ecmanaut.blogspot.com/feeds/7125742892016250691/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=15626356&amp;postID=7125742892016250691" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/15626356/posts/default/7125742892016250691?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/15626356/posts/default/7125742892016250691?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/xxBcs/~3/9Nk1yawhPs4/opera-11-extensions-add-on-con.html" title="Opera 11 extensions @ Add-on-Con" /><author><name>Johan Sundström</name><uri>http://www.blogger.com/profile/04076097346172610543</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://ecmanaut.blogspot.com/2010/12/opera-11-extensions-add-on-con.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0AFRHw8eSp7ImA9Wx5XGUk.&quot;"><id>tag:blogger.com,1999:blog-15626356.post-1824040395613080461</id><published>2010-09-19T18:21:00.000-07:00</published><updated>2010-09-19T18:21:55.271-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-09-19T18:21:55.271-07:00</app:edited><title>Comfy browser performance testing</title><content type="html">I have been poking around with some performance tests and profiling lately, first with Steve Souders' &lt;a href="http://www.browserscope.org/"&gt;Browserscope&lt;/a&gt;, which gets the job done, at some convenience cost of setting up a publicly hosted web page and tying it to a Google account (that you might have to first create), and, for loading performance, different ways of organizing script tags, images, iframes, style sheets and so on, &lt;a href="http://stevesouders.com/cuzillion/"&gt;Cuzillion&lt;/a&gt;, by same author.&lt;br /&gt;
&lt;br /&gt;
Today, I found and toyed around a bit with &lt;a href="http://jsperf.com/"&gt;jsperf.com&lt;/a&gt; by &lt;a href="http://mathiasbynens.be/"&gt;Mathias Bynens&lt;/a&gt;, which does much of the boring setup job for you, when it comes to micro-benchmarking some snippet of javascript versus another, assuming the thing you want to test is synchronous, and doesn't involve complex preconditions. (I wonder what makes Array copying using a &lt;a href="http://jsperf.com/vs-array-conversion/9#run"&gt;saved Array.prototype.slice&lt;/a&gt; significantly slower than the other more evenly performance-matched variants?) As should always be stated when mentioning benchmarks and optimization, this kind of micro-benchmarking is less relevant than finding your code's hot spots and picking better algorithms where relevant. That said, it's still academic fun to play with this kind of thing.&lt;br /&gt;
&lt;br /&gt;
For this kind of small test, jsperf.com does all the Browserscope setup work for you, and lets others improve (fork) your test after the fact, adding versions you didn't think of yourself that do the same thing. I have a vague plan of trying to make it run some performance tests for a little code snippet I wrought up recently that does a deep copy of a nested (JSON:able) structure from a parent window where there may be crud on &lt;code&gt;Object.prototype&lt;/code&gt; (the code should run in an iframe free of such), to benchmark vs a mere &lt;code&gt;JSON.parse(JSON.stringify(taintedObject)&lt;/code&gt;, which would also clean away the crud:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;var _slice = [].slice, _toString = Object.prototype.toString;
function array(arrayish) {
  return _slice.call(arrayish, 0);
}

function isArray(obj) {
  return '[object Array]' === _toString.call(obj);
}

// Take a nested structure from a hostile window (presumably full of crap in its
// Object.prototype, et cetera) and return a cleaned-up version with this window
// object's (pure) Array and Object constructors.
function deepClone(obj) {
  if ('object' !== typeof obj) return obj;
  if (null === obj) return null;
  if (isArray(obj)) return array(obj).map(deepClone);
  var clean = {};
  for (var key in obj)
    if (obj.hasOwnProperty(key))
      clean[key] = deepClone(obj[key]);
  return clean;
}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
What surprised me about the above code, when testing it on the kinds of payloads it would typically handle (data somewhat heavy on largeish strings), was that it actually was a bit faster than using the browser native JSON codecs, whereas, for larger inputs, native code always won out. Sometimes you just have to test stuff, to find out what wins.&lt;img src="http://feeds.feedburner.com/~r/blogspot/xxBcs/~4/ZubA_4Gb2EQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://ecmanaut.blogspot.com/feeds/1824040395613080461/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=15626356&amp;postID=1824040395613080461" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/15626356/posts/default/1824040395613080461?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/15626356/posts/default/1824040395613080461?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/xxBcs/~3/ZubA_4Gb2EQ/comfy-browser-performance-testing.html" title="Comfy browser performance testing" /><author><name>Johan Sundström</name><uri>http://www.blogger.com/profile/04076097346172610543</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://ecmanaut.blogspot.com/2010/09/comfy-browser-performance-testing.html</feedburner:origLink></entry></feed>
