markjnet

iPhone @2x Graphics, scale, and iPad

The iPhone 4’s retina display has 2x the pixel pitch of the previous iPhones, giving the screen 4x as many pixels. It looks fantastic, and with dimensions exactly twice the original screen it means that the phone can pixel double graphics in apps that haven’t been updated yet, and it looks fine (at least until you get used to using high resolution apps, and then its hard to go back). Apple gave developers an easy way to adapt apps to work with either screen. For UIKit based apps, if a view loads a graphic ‘myButton.png’ for the original resolution, then just by adding a file named ‘myButton@2x.png’ to the project in Xcode means that on iPhone 4 the app will load the @2x file instead. Simple and effective.

Detecting iPhone 4 / Scale

For graphics that aren’t loaded as a project resource, you might need to programmatically determine if you want to draw or load @2x resolution or normal resolution. To determine this, you could use something like:

+ (BOOL *) isIPhone4 {
  return ([MyDeviceClass platformCode] isEqualToString:@"iPhone3,1"]);
}
 
+ (NSString *) platformCode {
  size_t size;
  sysctlbyname("hw.machine", NULL, &size, NULL, 0);
  char *machine = malloc(size);
  sysctlbyname("hw.machine", machine, &size, NULL, 0);
  NSString *platform = [NSString stringWithCString:machine encoding:[NSString defaultCStringEncoding]];
  free(machine);
  return platform;
}

However this isn’t going to work on the simulator, iPad, or future devices. Instead, use the scale property of UIImage or UIScreen. Older versions of iOS don’t have this property, so you have to test that its available before use:

+(BOOL) screenIs2xResolution {
  return 2.0 == [MyDeviceClass mainScreenScale];
}
 
+(CGFloat) mainScreenScale {
  CGFloat scale = 1.0;
  UIScreen* screen = [UIScreen mainScreen];
  if ([UIScreen instancesRespondToSelector:@selector(scale)]) {
    scale = [screen scale];
   }
  return scale;
}

Scale on the iPad

So now you can code conditionally for iPhone 4’s retina display, but what about the iPad running iOS 3.2? iPad can run iPhone apps at normal 1x size, or pixel doubled 2x size. When running 2x pixel doubled on the iPad, iOS3.2 will automatically use real screen pixels if its drawing UIImages and hence draw them at full resolution, which is a handy compromise. This _doesn’t_ work for iOS4 targetted apps built with the @2x file names :-( but of course we can assume this will come to the iPad in the fall with iOS4.

iOS3.2 on the iPad does have support for the scale property. So if you want higher resolution graphics loaded programmatically when your iPhone app is running on the iPad, the code above will work. There’s a catch though. When running an iPhone app in 1x mode on the iPad, scale returns 1.0, and when running in 2x mode scale returns 2.0. The first time someone uses your iPhone app on their iPad they might switch between 1x and 2x few times to decide which they prefer. So you could end up loading a mix of normal and 2x resolution images. If you are loading images from the net and caching them (very common in the apps we build), then you might end up drawing the low resolution image from cache even in @2x mode. In that case, a specific test for the iPad might be in order too when deciding which resolution to download and cache, so you always have the 2x files ready for the iPad:

+(BOOL) isIPad {
  BOOL isIPad=NO;
  NSString* model = [UIDevice currentDevice].model;
  if ([model rangeOfString:@"iPad"].location != NSNotFound) {
    return YES;
  }
  return isIPad;
}

[Slashdot] [Digg] [del.icio.us] [StumbleUpon]

Xcode on a 2010 Macbook Pro High Res with SSD

I just bought a new 2010 15″ Macbook Pro and put in a solid state drive - OWC Mercury Extreme Pro SSD 240GB. It’s to replace my 2007 macbook used all the time for iPhone development with Xcode. I picked the hi-res antiglare screen (1680 x 1050). The OWC SSD is a new Sandforce based model that is reported to not suffer from the precipitous drop in write performance common to many SSDs on the market. (I also considered using a Seagate Momentus hybrid drive.) Benefits of the new machine include:

  • Faster CPUs and hyperthreading, so CPU bound Xcode builds gets to run 4 parallel compiles at the same time for a big speed boost.
  • The SSD has blazing random access times thus speeding up all general use of the machine, including the compile-deploy-test cycle with Xcode and the iPhone simulator.
  • More screen space makes it easier to work with Xcode and the iPhone & iPad simulator on the road.
  • The machine can better keep up with demanding Instruments profiling.

Simple Benchmarks

Here are some simple stopwatch based benchmarks comparing new and old machines. Its much snappier all round, and definitely speedier for development work.

2007 Macbook Pro 2.16GHz 2010 Macbook Pro 2.4GHz i5
7200rpm HD 5400rpm HD SSD
Boot, from power on to desktop first appearing 30s 40s 24s
Launch Xcode 7s 6s 4.5s
Build complex iPhone project from clean 86s 48s 45s
iPhone sim & Xcode install & debug app 10s 9s 3s
Instruments open 30MB trace 11s 6s
Start Photoshop CS3 (1st time, 2nd time) 15s / 5s 5s / 4s

High-res Display

The high-res display gives more pixels within the same space, so GUI elements take up less space and fonts draw smaller. This means Xcode and the simulator fit on the high res display. For me they didn’t quite fit right on the normal display, so I always found myself re-arranging windows when working out of my office (where I have a 27″ desktop display). You can see this in the two screen shots below, the first from the old macbook and below that the new high-res macbook. I boosted the font for code from Monaco-12 on old macbook (also great on my desktop display) to Monaco-14 to get the same sized text on the high res macbook display. I might settle on a 12 or 13 though because the new screen is much clearer than the old one. Fortunately Xcode makes it easy to change font sizes for code so switching between 12pt for desktop and 14pt when on the road shouldn’t be an annoyance.

Xcode on high res macbook pro

Open-GL on Simulator

I was hoping that the faster CPUs would boost performance of the iPad simulator running OpenGL. OpenGL on the simulator has terrible performance, I guess this is because the simulator is doing all its graphics with CPU based emulation of the graphics hardware on the phones, or maybe it just doesn’t use real graphics hardware on the macbook. On the one hand thats fine for performance work because performance work of course has to be done on real devices. However for general game and graphics logic development it means that running the game on the simulator (especially in iPad mode) means that frame rates are really low, lower than a generation 1 iPhone. The new macbook didn’t really help much here, OpenGL on the simulator still pegs one CPU on the macbook, and frame rates really didn’t improve much.

Xbench Tests

Result: 266.92
System Info
Xbench Version 1.3
System Version 10.6.4 (10F569)
Physical RAM 4096 MB
Model MacBookPro6,2
Drive Type OWC Mercury Extreme Pro SSD
CPU Test 189.95
GCD Loop 296.65 15.64 Mops/sec
Floating Point Basic 166.76 3.96 Gflop/sec
vecLib FFT 109.83 3.62 Gflop/sec
Floating Point Library 386.71 67.34 Mops/sec
Thread Test 465.08
Computation 483.74 9.80 Mops/sec, 4 threads
Lock Contention 447.80 19.26 Mlocks/sec, 4 threads
Memory Test 300.03
System 320.11
Allocate 469.76 1.73 Malloc/sec
Fill 214.25 10417.48 MB/sec
Copy 388.24 8018.86 MB/sec
Stream 282.32
Copy 281.48 5813.81 MB/sec
Scale 278.43 5752.27 MB/sec
Add 287.15 6116.93 MB/sec
Triad 282.38 6040.76 MB/sec
Quartz Graphics Test 243.53
Line 191.89 12.78 Klines/sec [50% alpha]
Rectangle 244.42 72.97 Krects/sec [50% alpha]
Circle 216.59 17.65 Kcircles/sec [50% alpha]
Bezier 207.61 5.24 Kbeziers/sec [50% alpha]
Text 557.04 34.85 Kchars/sec
OpenGL Graphics Test 192.35
Spinning Squares 192.35 244.01 frames/sec
User Interface Test 326.40
Elements 326.40 1.50 Krefresh/sec
Disk Test 321.71
Sequential 192.97
Uncached Write 282.94 173.72 MB/sec [4K blocks]
Uncached Write 278.32 157.47 MB/sec [256K blocks]
Uncached Read 92.01 26.93 MB/sec [4K blocks]
Uncached Read 365.84 183.87 MB/sec [256K blocks]
Random 966.64
Uncached Write 1186.91 125.65 MB/sec [4K blocks]
Uncached Write 517.95 165.82 MB/sec [256K blocks]
Uncached Read 2940.24 20.84 MB/sec [4K blocks]
Uncached Read 975.84 181.07 MB/sec [256K blocks]
    

[Slashdot] [Digg] [del.icio.us] [StumbleUpon]

Increase iPhone App Downloads by A/B Testing App Names

I’m about to outline the single most powerful thing you can do to improve sales/downloads of your iPhone app. I know this is a bold claim, but read on and I will justify it. I first presented this at 360iDev San Jose 2010.

Apple made us an amazing market for our software and threw in a fantastic distribution & sales platform. All that for just 30% of receipts, which IMHO, is an incredibly good deal for developers. But the app store doesn’t help anyone find your app right? Wrong! The app store is a catalog of ads for iPhone apps, and millions of people are browsing through those ads – especially the top 100 lists. These browsing people are primed and ready to download, you just have to make them notice your ‘ad’ among the 200,000 others. When people are looking in the app store they are scrolling through a table of app listings. It doesn’t matter if they are checking out the top 100 games or they searched for ‘gardening’, everything in the app store is shown as a list of apps. The listing shows: icon; app name; price; star rating, company name. Get someone to notice your listing, and they will tap through to your app’s page. There they see the screen shot and maybe download your app, but that can’t happen until they’ve tapped on your listing in the first place. The key then, is to get them to tap on your listing. To make the very best performing app listing you need to carefully select the best icon and the best app name. How do you know what will be the best performing, and what do I even mean by best performing anyway?

If you study how to be successful advertising on Google, or you learn about AARRR metrics for online business, you will discover that a key metric for online ads is is the Click Through Rate. CTR = clicks / impressions. (Clicks: number of times it was clicked on by people; impressions: number of times the ad was seen by people.) Better CTR means a better performing ad. Study this or try it yourself, and you’ll soon find that no-one makes money on Google by writing an ad, paying for the clicks, and sitting back while money pours in through their web-site. This is because it nearly always cost more for the ads than you can make back by selling your stuff! To make money you need to test several ads, figure out which is the best performing, take that ‘winner’ and make more variations to test. Keep repeating this until you have discovered one that performs well enough so that it is cost effective to pay Google a bunch of money to run the ad in large volume. iPhone app developers should use this same approach to figure out the best performing app listing: change name or icon, measure, compare, repeat.

OK, so how do you measure CTR of your app listing? You need to know impressions and clicks. But you don’t know these, only Apple knows how many times your app listing was shown and how many times people tapped on it (assuming even they are tracking this stuff). Hmmm… What we need is a way to test our app listing outside of the app store. It turns out there is something almost as good and extremely affordable: Admob. Below on the left is an app store listing for one of our old apps ‘Smart Caller’. On the right is an Admob ad in an iPhone app. Consider the content, structure, and context – they are very similar. So what I’m saying is that you can use Admob ads to test different icons and different app names for your app, to figure out the very best performing app name and icon for your app in the app store.

apListingAsAd.png

You can run an Admob mobile banner ad campaign for as little as $50, which will buy you 1000+ clicks (click prices vary by geography and demand). You might have a CTR of 1-2%, so that $50 is buying you 50,000+ impressions. This means you can test your icon or app name by sampling it 50,000+ times (which probably translates to almost 50,000 different people) all in a day. Survey 50,000 people in one day for just $50 to see which icon or which app name most catches peoples attention? Wow, if that doesn’t blow your mind then you’d better leave your app marketing to someone else. You can even test several ads at once in one $50 campaign, though you might have to baby sit it a little in order to get even testing of each. Now repeat a few times and you can find an app name and icon that performs much better than the ones you started with, all this for around $200 and a few hours work.

OK, here’s some proof for you of just how powerful the app icon and app name is. The graph below is real download data for one of our free apps. I won’t explain all the in & outs of the various name and icon changes the app has been through here, but you can see from the graph what a huge effect changing the name and icon had on downloads. Each blue line marks where we changed name or icon, and the red line is the daily download rate. (Of course when you do this, you are trying to increase downloads, and you can see that we decreased downloads… but exactly what happened there is for another blog post!) For this app, we saw 20x difference in download rate for the best app listing vs the worst. Wow. Now in testing via Admob you won’t see such a huge difference in CTR, because live in the app store, a better CTR for your app listing has a leveraging effect. Double your CTR and you double downloads. Doubling downloads will increase your rankings a whole lot, and with increased rankings more people will see your app (more impressions), which leads to even more downloads. Your app listing CTR has massive leveraging power, which I’ll discuss more in a later blog post.

downloads.png

Often when app publishers (especially indie developers) look at paid promotions like Admob ads, it’s not clear if it’s money well spent because of the question of how many actual downloads you will get for your money. It can cost a lot per download (Admob does have a way to measure downloads per impression and per $ spent, which is very neat). For example, one campaign we ran ended up costing us $2.50 per download for a free app, which was not a cost effective way of acquiring users for that app. Figuring the download rate (aka conversion rate) for your ad is a more sophisticated way to measure how ‘good’ the ad is, and you should try to measure conversion rate if you are using ads to acquire users / makes sales. But here I’m not talking about acquiring users, I’m talking about A/B testing your app name and icon, and for that, your $200 might well be the best money you’ll ever spend.

Why do I claim this is ‘the best’ thing you can do? Consider your sales funnel. Below is the sales funnel for a free apps that doesn’t have a bunch of PR, blog reviews etc. Its downloads come only from people finding it in the app store. To get people out the bottom of the funnel where you actually get paid, you need people to enter in at the top and keep moving down the funnel. To improve the conversion rate at which people will move down from one level to the next, you have to do more work and spend more money. All the conversion rates multiply together to result in the overall conversion rate of your sales funnel, so you can double your overall conversion rate by doubling conversions at any one of the stages. Improving how much people love to use your app (app use stage, or activation and retention in AARRR metrics) is probably quite hard and expensive, but improving how many people click on your app listing in the first place (acquisition) is quite easy and cheap by doing what I just described. Then on top of how cheap this is to do, add in the leveraging effect your app listing CTR can have and I hope you can see the potential here.

salesFunnel.png

You can and should test your app name before you release your app, but you can also do it for an app that’s been out for ages. Got an app sitting there not selling? Experiment with different names and icons and find something that performs better for you. In our experience, existing users won’t mind you changing name & icon, but do consider changing only one at one time unless you go for a full rebranding, in which case just tell existing users what you are doing.

Would you like to de-risk your entire app making business by using this technique? Do app name testing before you ever write a line of code or design a single pixel. Are you an iPhone game developer? I bet you have many ideas for different games, but you’re not sure which one to invest the time and money to develop? Use ads to test several concepts, and build the one with the best click through rate. By doing this you’ll be pre-picking the one that has the best chance of being noticed by people and rising up the app store charts. Up-front market research like this is part of what the customer development & lean startup approach is all about – testing your idea as early as you can.

When you try this watch the CTRs for your ads and see if they change over time. When the ads first run, CTR tends to show higher in the reports than it will end up. As time goes on CTRs drop. Then leave it a few days and you’ll sometimes see CTRs rise again (even once the ad campaign has finished). I think it’s just differences in timing of how the click data and impressions data gets reported. I also suspect there’s an effect because of ‘ad-click jockeys’, users who really like clicking ads to see what new apps are out there, so these people click on new ads as soon as they see them. If this is happening its just fine, because click jockeys are the same people who are going to push your app up in the charts. So do keep an eye on the CTRs, and check back after a few days to see how the numbers settle.

I’d love to hear from anyone else who’s doing this kind of stuff with their mobile app business, and if I’ve inspired you to try it, let me know how it works out for you. Comment below or email markj at markj dot net. I’d love it if you could share the CTRs you get for different kinds of apps and the ranges you find between best and worst performing in order to develop some benchmarks for evaluating app ideas. I’ll be writing more on these topics myself, so please consider subscribing to this blog. Below are some references to the people I learned these techniques from, I encourage you to go read their blogs, books, and hear them speak if you can.

Steve Blank: developed the ‘Customer Development’ approach to the startup business, which my iPhone business is based on.

Eric Ries: was Steve’s student, and went on to pioneer customer development for online businesses in combination with agile engineering practices, resulting in the ‘Lean Startup’ movement.

Dave McClure: has fantastic work on metrics for online businesses and understanding your sales funnels, a lot of which applies well to the app store. AARRR!

Sean Ellis: Lots more great advice on startups and marketing.

Al Ries and Jack Trout: their book ‘Positioning – The Battle for your Mind’ explains the challenges in communicating with your customer, and sets the background for just why your app name is so powerful if you get it right.

Perry Marshal: great material on understanding online advertising with Google (and by proxy Admob etc).

Glenn Livingston: teaches online marketing, emotional marketing, and understanding customers (which is at the heart of whole customer development approach).

Neil Young: At iPhone and game conferences, Neil stands up and lays out ngmoco’s strategy to us. (And I started on a ZX Spectrum too!)

360idev: great place to learn about this mobile apps biz. I first presented this at 360iDev San Jose 2010.

Dave Wooldridge: The Business of iPhone App Development a great practical marketing book for iPhone devs. (Which I was the tech reviewer for.)

[Slashdot] [Digg] [del.icio.us] [StumbleUpon]

iPhone Conference 360 iDev San Jose April 2010

n115911253310_1478Are you going to 360 iDev San Jose 2010 in April? Its by far the best iPhone developers conference I know of… and I’m speaking at it this year. I’ll be introducing people to customer development and telling the story of our app Friend Focus for Facebook.

This year there’s 40 sessions, 3 panels, almost 40 speakers, 5 different Hands-On training sessions, all included for the price of $599 which IMHO is crazy good value. I attended in 2009 and it blew my mind. Here’s some of what I got out of the 2009 conference:

  • Learned lots of inside knowledge about Apple that you can only learn from experience with them, including guidance on the mysteries of the approval process that easily saved me several thousand dollars in wasted development time on my own apps and helped strengthen my consulting practice.
  • Got the inside scoop on mobile advertising, what works, what doesn’t.
  • Met and made friends with a bunch of expert developers and iPhone business entrepreneurs including several chart topping studios and major iPhone app review sites – extending my network of experts to ask for help, advice, and press contacts.
  • Introduced to several companies I’m now doing business with.
  • Shared sales numbers with other developers and got a bunch of marketing tips.
  • Got helpful advice on negotiating a licensing deal I was putting together for one of my apps.
  • Learned techniques for memory optimization; SQLite; advanced debugging using notifications; core animation;
  • Had a ton of fun!

12660_181780978310_115911253310_2937860_2878172_nThe intimate size of the conference is very conducive to making friends and sharing insider knowledge that’s really hard to find elsewhere. Indie developers will be there in numbers, both successful and struggling, and there will be a good mix of major studios and iPhone companies represented too. You’ll be able to both vent your frustrations with peers and grill an Admob Google executive about eCPMs. Really, its tremendous value and great fun. Go and register now.

12660_181782603310_115911253310_2937942_7897015_n

[Slashdot] [Digg] [del.icio.us] [StumbleUpon]

Tweeting from an Ad on the iPhone Using URL Schemes

Lately I’ve been experimenting with promoting out app ‘Friend Focus (for Facebook)‘ by ‘turning out the vote’ – ie getting our existing users to help us promote Focus. Once I’ve found a formula that works well we’ll implement the scheme in app and figure out a way to reward users for helping us, but for now I’ve been using house ads. House ads are our own ads placed in our app using the ad network we’re integrated with. Admob in this case. This is a great way to try out ad copy and experiment with different promotions because its all done with no code updates to our app, all I have to make is a simple HTML landing page for each ad.

A recent campaign we’ve been running is ‘Tweet your support for Focus’, which asks people to tweet saying that Focus is great:

Tweet support for Focus ad

Tweet support landing page

Naturally the tweet has to be pre-filled, which lets me use a bit.ly link so I can track the effectiveness of the campaign. A ‘tweet me’ link is pretty easy on the web, but this is on people’s iphone. Twitter users with lots of followers (ie the people we want to tweet) aren’t using the twitter website on their iPhone, they’re using a twitter app, of which there are many to choose from! So how do we turn a click on my ad into a pre-filled tweet right inside someone’s pre-logged in twitter app of choice? The solution is to use custom URL schemes. Several iPhone twitter apps have custom url schemes that allow you to launch them and pre-fill a tweet using their custom url. This works just as well from the landing page of an admob, in code in a native app, in a web page in mobile safari, or a link in an email.

Hmmm, but which twitter app to choose? Turns out you can choose them all! I wrote some simple javascript to just open all of them – one of them is bound to hit. The code is below. I picked 5 of the most popular twitter clients and included them. The script works great in the UIWebView that Admob opens to show the landing page for the ad, because the UIWebView isn’t throwing up a dialog saying “couldn’t open that URL” for urls where a scheme isn’t installed on the devide. Its imperfect as a web page because of these alerts, which you will see if you try it. I tried a bunch of things – using the tweet url for an image src, in an iframe, as a form submit. I also played with timers and onblur event to try to cancel out the urls tries upon returning to the page in Safari. If someone could figure out the perfect javascript for this that works in Safari and post here in the comments, that would be very awesome.

Go ahead and try it by clicking the ad above, and if you tweet your support for Focus, that would be splendid! As you can see to the left, it works… we’ve had 28 tweets so far, from a variety of twitter apps, which has generated 165 click throughs to the Focus website. Thanks to everyone who tweeted for us so far. Below is my hastily put together javascript.

 
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Tweet Focus Support</title>
 <meta name="viewport" content="width=300; initial-scale=1.0; maximum-scale=1.0; minimum-scale=1.0" />
 
<script type="text/javascript">
var msg = "Get%20the%20best%20Facebook%20on%20%23iphone%20with%20Focus%20for%20Facebook%20http%3A%2F%2Fbit.ly%2FFocus4Facebook%20%40focusedapps%0A";
var tweetTry=0;
var tweetTryCancel=false;
var tweetTrys = new Array();
tweetTrys[0]="tweetie:///post?message="+msg;
tweetTrys[1]="twitterrific:///post?message="+msg;
tweetTrys[2]="echofon:///message?"+msg;
tweetTrys[3]="twit:///post?message="+msg;   //twitelator
tweetTrys[4]="x-birdfeed://post?text="+msg;
 
function tweetPress() {
	tweetTryTime=0;
	tweetTry=0;
	tweetTryCancel=false;
	tweet();
}
 
function tweet() {
//alert("tweet");
	if (tweetTryCancel) {
		alert("cancel");
		return;
	}
	var currentTime = (new Date()).getTime();
	if (tweetTryTime!=0) {
		var elapsedSinceLastTry = currentTime-tweetTryTime;
		//alert(elapsedSinceLastTry);
		if (elapsedSinceLastTry>400) {
		alert(elapsedSinceLastTry);
			tweetTryTime=0;
			tweetTry=0;
			tweetTryCancel=false;
			//alert("reset");
			return;
		}
	}
 
	tweetTryTime = currentTime;
 
	var url = tweetTrys[tweetTry++];
	if (tweetTry>5 || url==null) return;
	if (tweetTryCancel) return;
	//alert(url);
	if ("http:"==url.substr(0,5)) {
		window.location=url;
		window.setTimeout("tweet()",10);
		return;
	} else {
		//window.location=url;
		var obj = document.getElementById("if1");
		obj.src = url;
		window.setTimeout("tweet()",10);
		return;
	}
}
 
function onBlur() {
	tweetTryCancel = true;
};
 
 
window.onblur = onBlur;
 
</script>
</head>
<body>
<div style="margin-right: auto;margin-left: auto;width: 280px;background-color: #DFEFF5;padding: 5px;border: 3px solid #6080C0;"><center>
  <div align="center" class="style1">Tweet Your Support  </div>
  <p align="left">We need your help to spread the word about Focus for Facebook. If you use Twitter, please take a moment to...</p>
 
  <p align="center"><a href="" onclick="tweetPress(); return false;" }><img src="tweetSupportApp.png" alt="tweet support" width="245" height="41" /></a></p>
 
  <p align="center"><a href="http://clicktotweet.com/ha89H"><img src="tweetSupportWeb.png" alt="tweet support" width="245" height="41" /></a></p>
 
  <table width="219" height="94" border="0" align="center" cellpadding="2">
    <tr>
      <td height="15" colspan="3">&nbsp;</td>
    </tr>
    <tr>
      <td rowspan="2" align="left" valign="top"><img src="logo62.png" width="62" height="62" /></td>
      <td rowspan="2" align="left" valign="top">&nbsp;</td>
      <td height="5" align="left" valign="bottom">Thanks,</td>
    </tr>
    <tr>
      <td height="5" align="left" valign="top"><p>Mark &amp; Rob, Focused Apps.</p>
      </td>
    </tr>
  </table>
  <img src="" width="1" height="1" id="img1" /><img src="" width="1" height="1" id="t2" />
  <form id="form1" name="form1" method="get" action=""></form>
  <iframe id=if1 src ="" width="1" height="1"></iframe>
 
  </div>
</body>

[Slashdot] [Digg] [del.icio.us] [StumbleUpon]

Next Page »

  • Categories

  • markjnet