devin venable bits

FEED

Thought Stream Follows

Sun May 5 07:40:09 2013
I'm hundreds of millions of years old
I woke up last night thinking about how comfortable I felt wrapped up in my blankets with my wife.  I thought about what it must have been like for my grandfather when he woke up at night with my grandmother in their little home in Ada, Oklahoma.  I wondered about my great, great grandfather before him, and for the countless generations before him and before the invention of the modern mattress set.

They're all me, and maybe some of you.  They're not the personal me, the me of my conscious mind, but nonetheless my life is their life.  My life is a continuation of their being through sexual reproduction.  If at any point in my lineage had one of my forefathers' life been cut short prematurely, before his opportunity to reproduce, I would not exist.

We're all unique, it's true, as our generics are a combination of two different lines of humans---lines that likely crossed many generations ago, perhaps many times.  But the resulting human, me or you, we are literally them.  Our traits, our personalities, our physical makeup---all born of lines of DNA passed from organism to organism for millions of years.

Sometimes I wonder if we overemphasize the importance of the individual human, the person we know ourselves to be.  After all, our consciousness is transient.  We live in one body so briefly.  It seems we barely have enough time to grow up before it's over.  In 70 to 100 years, we go from knowing nothing of the world to knowing much that a human can know before consciousness shuts off.  But, if we reproduce, we pass on the core of who we are, the recipe, literally the life, on to the next generation.

Some might argue that you pass on the blueprint only, and that each new life is "born", but I'm not sure I would agree.  From the moment my little swimmers left my body, they were alive.  The fought their way into an egg and from there life morphed and continued.  I have three kids walking the earth today carrying on my life force.  If I were to die today, this life of mine would be considered a success from a biological perspective.

So who are we?  Macro individuals or members of a micro collective?  Are we but mere vessels, an ark for microorganisms to ride upon through time?

And from a conscious level, how am I connected to my ancestors?  Is my consciousness an echo of theirs?  Do I have the same struggles as a distant forefather 1000 years ago?  Did his back hurt like mine does?  Did he have high blood pressure?  Did he struggle with depression?  Did he like spicy foods?  Did he lay awake at night, satisfied to be near his wife, wondering about what it really means to be alive?



Thu Apr 25 17:35:44 2013
Low latency midi
This might be just about the only way to get decent latency performance out of midi (using external hardware):


devin@devin-OEM:~$ jackd --sync -Xalsarawmidi -dalsa -r48000 -p256

Or even more betta:

devin@devin-OEM:~$ jackd --sync -Xalsarawmidi -dfirewire -r48000 -p256

Starts up midi in raw midi and firewire for audio...still testing this out

Tue Apr 2 18:47:07 2013
Ardour 3.0 Notes
First off, I paid for the software.  Why?  Because I like it and I've been using it for years.  I thought now would be a good time to pay for a release.

I'm excited about using the midi features with my external keyboards. But the midi port setup has changed.

jack midi ports (virtual) can't talk to alsa midi ports (hardware cards) without a little help.  So after starting up qjackctrl, I must launch this daemon.


 a2jmidid -e

After running, hardware ports show up under an a2j node in the MIDI tab.

I want to connect my BCF2000 to Ardour and this process too has changed.

1. Map ardour MIDI control out to BCF2000 midi 1
2. Map a2j BCF2000 capture midi 1 to ardour MIDI control in

Using preset 2 on the BCF2000, I can then "Operate Controller Now" on a virtual fader and take control with a hardware slider.

But...PRESET 2, which with Ardour 2 was configured to control Ardour's transport controls, don't seem to have an affect.

After reading Paul's comment (https://community.ardour.org/node/4942), I'm about to try to map the MMC.

Yes!  That worked.  I simply had to map the MMC in and out ports to the same BCF2000 ports I used in steps 1 and 2 above.

Sun Dec 30 15:01:07 2012
Alesis Perforamnce Pad midi clock sync
Just a quick note...it's not easy to get the Alesis Performance Pad synced up with your Linux system.  Jack and Ardour supports MTC, not midi clock (at least not yet).

My need was to sync all of my virtual stuff (seq24, Ardour) with my drum machine, the Alesis.  Unfortunately, no midi in on the Alesis, only midi out.  The Alesis will emit old school midi clock messages, and that's about it.

My hackish solution: use Rosegarden.

Under settings/midi/midi sync you'll find a MIDI Clock and System Messages option.  From the drop down select "Accept start, stop and continue."

Assuming your external synth or drum machine is connected via midi in to jack, pressing play on the external device will now start Rosegarden.  If synced to other Jack applications, this will also kick off your entire virtual orchestra.
Sat Nov 3 07:15:24 2012
Multi-track export for LMMS
I wrote a new little feature for LMMS, the Linux Multi Media System (which also runs on Windows).  LMMS is an FLStudio-like product that I've been making music with for the last year or so.  One issue I have with it is that I can't do everything I need from within LMMS, like real-time recording or controlling an external midi device---the way that I would want to.  And in fact I'm not sure I would want to do everything in one program.

Instead I use LMMS as a tool.  For electronic beat-based music, it rules.  So I like to do the electronic tracks within LMMS.  But I also am into adding real vocals, or recording other non-sequenced sounds.

In the past I would do my sequence work in LMMS, then export the final mix as a wav file, and then pull it into Ardour as a stereo track.  (I'd like to just use jack to sync the two products, but this hasn't worked out---seems the support is not there.)  Then I add other tracks, and then do a final mix down.

But, this sucks as I sometimes decide I need to re-balance the LMMS submix, which meant going back into LMMS, mixing down there and then re-exporting.

So my solution was to add an "export tracks" feature to LMMS that exports each instrument or sample as it's own wav file.  Now I can import each sound as an individual track in Ardour.

I've submitted the patch to LMMS-dev but it has yet to be accepted, so I don't know if the feature will make it into the product or not.  But I hope it will!


Sat Aug 11 20:59:17 2012
Mounting software raid devices on Linux
Just bought a solid state drive to replace two aging drives.  My two drives have appeared, for the last four years, as a single striped (Raid 1) drive to my system, via software raid.

After a fresh installation of UbuntuStudio 12.04 on the solid state drive, it's time to migrate data.  But how to mount the two old drives?

Turns out it was ridiculously easy.  I simply installed mdadm, rebooted, and there was my Raid 1 drive.


When did it get so easy?  I remember the good (bad?) old days when I'd be posting three pages of technical details to resolve such a problem.

Thanks to all of the open source contributers past and present for making our world a better place!
Wed Jun 27 16:33:18 2012
tag:
Wed Jun 20 19:16:05 2012
tag:
Fri May 11 06:18:38 2012
Jquery Mobile and rubber band drag effect

brokentoe 03:40:11 PM
Best way to eliminate rubber banding of entire page on touch drag?  Want header and footer to stay fixed.

pizthewiz 03:49:56 PM
if you are using PhoneGap on iOS, it has a config option UIWebViewBounce in Cordova.plist, if not you are left to your own devices to sort out (0:


In short, if you are using JQuery mobile as a webapp only, there is not a sanctioned way to prevent fixed headers and footers from bouncing when user attempts to scroll content area past bottom or top of page.  I've tried several posted workarounds, from iscroll.js to custom css and javascript hacks.  Still looking for the perfect solution.
Tue May 1 15:47:03 2012
tag:
Thu Mar 22 20:51:32 2012
tag:
Thu Mar 15 01:40:15 2012
tag:
Mon Feb 20 02:47:11 2012
tag: graph
Sun Feb 19 20:16:46 2012
tag: xen
Wed Feb 15 17:35:59 2012
tag:
Wed Feb 15 09:41:01 2012
Badges
We've been experimenting with badges for the SayAh web site. For example, the following badge---which is just a hyperlink with an embedded image---directs visitors to the CSOS web site to Bryan Hawkin's SayAh Review Site.

SayAh Review Results

I'm not sure if the badge fragment will render properly within a blogger post, thus this post, which tests behavior.
Wed Feb 1 17:23:56 2012
tag:
Sat Jan 7 22:39:49 2012
tag:
Sat Jan 7 22:36:55 2012
tag:
Tue Jan 3 02:54:17 2012
tag:
Fri Dec 16 16:08:23 2011
tag: css3
Fri Sep 30 13:37:09 2011
tag:
Wed Sep 21 08:51:55 2011
git differences between working copy and stashed copy
Shows the differences between copy and third item in the stash stack...

git diff stash@{3}

Thu Sep 15 20:59:49 2011
tag: canvas
Wed Sep 14 19:10:49 2011
tag: canvas
Wed Sep 14 18:56:51 2011
tag: svg
Tue Sep 13 21:42:22 2011
tag: svg
Mon Sep 12 08:58:23 2011
Vim search and replace from current location to end of file
Instead of searching and replacing the entire file with...

:s/old/new/g

Try inserting ".," just after the colon. This means "from current position to end of file".


:.,s/old/new/g

The comma actually specifies a range to make the substitution, from left and right of comma. For example...

:5,10s/old/new/g

...makes the substitutions on lines 5 through 10.


Fri Sep 9 09:07:29 2011
Notice to .NET developers
Word is there are about 30 more JAVA positions that need to be filled in the Tulsa area than there are JAVA capable developers. This is driving up the rate that JAVA developers can demand.

Meanwhile, Tulsa is flooded with .NET developers, which drives the rate .NET developers demand, downward.

So a word to the wise: don't get married to one vendor's technology. Any software engineer worth his salt can switch from .NET to JAVA or visa-versa without much pain.
Wed Aug 31 18:15:36 2011
tag: css
Wed Aug 31 12:40:38 2011
Vim tags
Continuing on with my exploration of Vim features I've yet to use, let's explore tags.

Tags are like bookmarks. They let you jump around to different places in your file that you might want to reference, like a class definition for example.

Create a tag like so: ":tag tagname". This tags the current line number with the name you provide. Alternatively, you can use the shortcut CTRL + ]. The tag name will be taken from either the character under your cursor, or if you've highlighted a word or phrase, it will be used.

":tags" shows you your list of tags.

:tags
# TO tag FROM line in file/text
> 1 1 LongTextAnswer 8 q = LongTextAnswer()

Each time I show my :tags I get this error:

E433: No tags file.

This may also explain why my tags queue only contains the most recent tag I create. Further reading reveals that the tags file is created by the program ctags. I'll try installing exuberant-ctags and see what affect that has on my operation.

sudo apt-get install exuberant-ctags

Restarting vim and trying the :tags command again showed that my tags file could still not be found. I found a nice little page that describes the rest of the process that one must go through to get your tags file set up. Follow the link to learn more.

http://amix.dk/blog/post/19329

On a related note, you can read ctags in python:

http://code.google.com/p/python-ctags/





Wed Aug 31 07:09:38 2011
Vim Execute Mode
I use vim and gvim every day. I'm so productive using the small subset of available commands that I know that I tend not to explore the question, "what else can I do with Vim?"

Take Execute Mode for example. In 10 years of Vim use, I've never tried it. Let's fix that now.

You enter Execute Mode by pressing capital Q (shift + q) when in normal mode. You'll see this at the bottom of your window.

Entering Ex mode. Type "visual" to go to Normal mode.
:

This seems familiar enough, but this is different than when you simply type ":" to enter a command at the bottom of the screen in normal mode. In normal mode, typing ":10 " + enter takes you to the tenth line in the document. In Execute Mode, ":10" + enter displays the tenth line just below your cursor. Hitting return again shows the eleventh line, and so on. You are not editing the document in this mode, simply accessing it. Interesting, but not yet terribly useful. Let's see what else you can do.

:w filename

This writes the file, just as it would if you had typed :w filename in normal mode, except again, instead of returning you to editing the document, you remain in Execute mode, meaning that the ":" appears again, awaiting your next command.

I'm afraid I can't imagine too many good reasons to use Execute Mode. The best use-case I can find is that you could use the :n, where n is a line number, feature view a section of the document you are not working on without leaving the section you are working on. If you have any tips on how Execute Mode makes your life easier, please leave a comment.


Mon Aug 8 09:03:52 2011
Safari URL opens new window
Here's a strange quirk I encountered while working with Safari mobile: HTML anchors (<a href="http://www.blogger.com/something.html">click</a>) open a new Safari browser instance---every time.

Now that can't be right. As it turns out, this is indeed the standard behavior when the target attribute is not explicitly set in the anchor. Apple does provide a work around setting:

http://www.naquah.net/blog/dennis/2008/03/21/how-to-enable-single-window-mode-in-safari

There are many instances when web designers don't need targets, and they are omitted. For most browsers, when the target is not explicitly set, the browser default behavior is _self. See the table from w3cschool:

http://www.w3schools.com/tags/att_a_target.asp

Attribute Values
Value Description
_blank Open the linked document in a new window or tab
_self Open the linked document in the same frame as it was clicked (this is default)
_parent Open the linked document in the parent frameset
_top Open the linked document in the full body of the window
framename Open the linked document in a named frame


The kicker is that Safari uses _blank as the default instead of self. The solution for web designers? Explicitly set the target attribute to _self for every anchor. A bit of a hassle, but the best way to ensure that a new window does not open up with each hyperlink click.


Thu Jul 21 01:03:03 2011
tag: cfd
Wed Jul 20 22:35:40 2011
tag: jquery
Wed Jul 13 07:33:15 2011
Huge gvim annoyance
Since upgrading to Ubuntu 11.01, when I open a document using gvim, I get a very unresponsive file browser window. In the past, I would double click a folder and it would quickly open. Using gvim, when I double-click, I get a wait cursor. I often have to click four or five times before the folder opens. Very irritating. Anyone else have this problem?

Same thing happens whether using vim-gnome or vim-gtk package.

Other programs do not share this quirk. For example, the text editor program behaves as expected when opening the files.
Thu Jul 7 17:49:50 2011
tag: music
Sat Jun 11 16:58:59 2011
tag: uml
Mon Jun 6 18:42:34 2011
tag: django
Wed May 25 08:32:37 2011
Can't ignore IE
I've been using Ubuntu as my operating system for the past five years. So long that I almost forgot that you must always check your web site for IE compliance. Well, I didn't forget so much as I wasn't concerned.

So since I've been shopping for contracts---I decided to return to consulting if I can line up the right opportunities--I thought it would be wise to review the user experience of my site, devinvenable.com, using IE. I fired up a virtual machine running Windows XP, opened up IE 8, and was hit with Javascript errors. Doh!

It's simple enough to conditionally remove code from your page that won't run on IE, or conditionally include code that does. Even if you use cross-platform javascript libraries like jQuery, as I do, you are still bound to run into issues from time to time.

<!--[if IE]>
   You are using IE (IE5+ and above), so include include script that is specific for IE here.
<![endif]-->

<![if !IE]>
   You are NOT using IE, so feel free to use HTML 5 features.
<![endif]>


So don't get lazy and assume that IE is history. While it's true that many savvy technical users have ditched IE for Chrome or Firefox, there are always users who will use IE because it is installed by default on their Windows OS.

Writing this entry made me curious about the current browser usage statistics. Amazingly, Firefox is way out in front with 42.9% this month, followed by Chrome at 25.6%. Microsoft's IE is still hanging in there with a respectable 24.3%. Still a contender but far from being the market leader in 2011.

http://www.w3schools.com/browsers/browsers_stats.asp
Sun May 22 13:34:13 2011
Job search fun!
I've decided to make a transition. New opportunity, here I come!

Looking for a new gig is always a lot of hard work. One must find the right fit: good people, exciting technology, and room for growth. I've talked to one prospective employer already and was asked, "What would be your ideal job if you could have anything you dream of, the perfect environment?"


It's a tough question. As a technologist, I'm probably at the top of my game. With 14 years of software development, I've dappled in just about everything. I don't encounter new technologies or languages often for which I've not already built products. Because of this, I tend to stay in the trenches---doing hands on technical work.

I'm 42. At my age, some get out of the trenches and into management. I'm afraid I would be bored silly if my primary work tool was Microsoft Project. That said, I am a people person, and often find myself wishing for more socialization when working with other developers, as so often they are introverts.

I like building new products versus extending the work others did before me. Who wouldn't? So often you inherit a bug infested mess. Building systems from scratch is fun for me.

I love brainstorming and sharing ideas. I'm a dreamer and I always have been, and this tends to work for me in the creativity department.

I love open source projects and all things Linux. This doesn't always work to my benefit in the Tulsa market where many mid-sized corporations go with Microsoft solutions. Perhaps I ought to go after these markets, selling CTO's on the joy of open source and living in a license free world. For a fraction of what companies pay for licensing fees I could switch them over to free solutions. That's a gift that would keep on giving. Many mid-sized corporations would be well served ditching Oracle, for example, as the scalability and reliability of open source alternatives is easily demonstrable. And what about the hundreds of thousands they spend on DBA's? Database administration doesn't have to be this hard, folks.

I'm no closer now than when I started writing this blog entry to knowing what my ideal job would be. But at least the creative juices are flowing. :)
Tue Apr 26 13:36:47 2011
Adding information to Django's default error page
Django's default error page is a handy way find out what went wrong when your view code runs into an exception that is not explicitly handled. But sometimes you don't get the info you really want to see. For instance, today I kept running into sql errors, something I don't see too much of using Django because they are normally abstracted away by the model framework.

In my case I needed to resort to using raw sql. The query was complex and the variables many, and thus I encountered a number of different database (cx_oracle) errors while working on the view and I didn't have a quick and dirty way to see the sql that was generated.

Getting the most recently generated sql is possible by importing django.db.connections. You can then tack it into your exception and see it on the default error page using the following technique.

try:

    """
    This is where you build your view.  Do whatever you need to do.  In my case
    I was inserting a row into the database here.
    """
except Exception as inst:
    
    """
    inst.args is a tuple of arguments that were passed when the exception
    was raised.  Django will turn this variable into the main error message
    you see atop the default error page.  It's a tuple, so you can't append
    to it, but you can replace it with another tuple and add any information
    that would serve you well.
    """

    inst.args = ("%s sql:%s" % (inst.args[0], " ".join(connections[db].queries.pop()['sql'].split())),)

    """
    Sure that's ugly, but it served my debugging purpose.  Use pop to get the most 
    recent query from the queries list.  I wanted to get rid of the while space and
    newline characters, which is the reason for the split and join.  Now you just 
    raise the exception.
    """
    raise


If you are going to do this kind of thing frequently you should probably explore the process-exception middleware API.

http://docs.djangoproject.com/en/dev/topics/http/middleware/?from=olddocs#process-exception
Mon Apr 25 11:38:15 2011
Best Django debugging technique ever
Start up your test app using the Development Server. Then inject the following into your code where you want to examine everything, perhaps in an exception handler.

import pdb
pdb.set_trace


Now when you hit the exception, pdb will take over the console window you started the test app. Type help if you are unfamiliar with pdb. All of your variables are available for review!

Sweet! I can't believe I didn't know about this technique before.
Mon Mar 28 12:13:02 2011
Dansguardian and Youtube on Ubuntu 10.10
If you want content filtering for your kids on Ubuntu 10.10, Dansguardian does the trick, but be prepared to do some tweaking.

Installation is not difficult. Follow this recipe:

https://help.ubuntu.com/community/Servers/DansGuardian

My kids love youtube but the default configuration renders it useless. Locate the configuration files in /etc/dansguardian. You'll primarily be interested in the content under the "lists" directory.

I added the following file extensions to exceptionextensionlist:

.js
.flv
.mp3
.ico


From bannedregexpurllist, I removed the keyword "naked", which seemed a bit over the top to me.

For video playback, add this line to exceptionurllist:

youtube.com/videoplayback


In exceptionsitelist, add the following. What the heck is ytimg.com? Well apparently it serves the main static css off youtube. I don't know if this changes and if it does how often, but I do know that the addition of this line alone had the most positive change on the overall youtube experience under Dansguardian.

ytimg.com


Similar steps may need to be repeated for other sites that fail to render properly. Watch the log at /var/log/dansguardian/access.log to see what's getting blocked, as that will provide the clues as to what you need to make exception for.
Fri Mar 18 15:25:43 2011
198252_1615661556849_1395634786_31310498_7106841_n
Thu Mar 17 12:50:05 2011
Color highlight columns in Vim
Vim 7.3 has a new, useful feature that allows you to highlight (set the background color) of one or more columns of the document you are working on. This comes in handy if you are working with a file that uses a fixed width format. For example, if you want to quickly see the 44th column for every row as you scan through a file, this might assist in the task.

Vim 7.3 is not yet in the Ubuntu repositories officially, but a PPM is available here:

http://askubuntu.com/questions/7283/where-can-i-find-vim-7-3

Once installed, use vim help to get details about colorcolumn.

:help colorcolumn


This will show you:

'colorcolumn' 'cc'      string  (default "")
                        local to window
                        {not in Vi}
                        {not available when compiled without the |+syntax|
                        feature}
        'colorcolumn' is a comma separated list of screen columns that are
        highlighted with ColorColumn |hl-ColorColumn|.  Useful to align
        text.  Will make screen redrawing slower.
        The screen column can be an absolute number, or a number preceded with
        '+' or '-', which is added to or subtracted from 'textwidth'. 

                :set cc=+1  " highlight column after 'textwidth'
                :set cc=+1,+2,+3  " highlight three columns after 'textwidth'
                :hi ColorColumn ctermbg=lightgrey guibg=lightgrey

        When 'textwidth' is zero then the items with '-' and '+' are not used.
        A maximum of 256 columns are highlighted.



In practice you only need to :set cc=n, as there are default colors.
Thu Mar 3 10:59:56 2011
History in Python shell
I never could get used to ipython, but still wish for command history in my shell. You too? I'm reposting this solution here that not only saves your command history between sessions but also gives you auto-completion.

Here's what you do. Store the following file in ~/.pystartup

Don't forget to export PYTHONSTARTUP as noted in the comments.

# Add auto-completion and a stored history file of commands to your Python
# interactive interpreter. Requires Python 2.0+, readline. Autocomplete is
# bound to the Esc key by default (you can change it - see readline docs).
#
# Store the file in ~/.pystartup, and set an environment variable to point
# to it:  "export PYTHONSTARTUP=/home/user/.pystartup" in bash.
#
# Note that PYTHONSTARTUP does *not* expand "~", so you have to put in the
# full path to your home directory.

import atexit
import os
import readline
import rlcompleter

readline.parse_and_bind('tab: complete')
historyPath = os.path.expanduser("~/.pyhistory")

def save_history(historyPath=historyPath):
    import readline
    readline.write_history_file(historyPath)

if os.path.exists(historyPath):
    readline.read_history_file(historyPath)

atexit.register(save_history)
del os, atexit, readline, rlcompleter, save_history, historyPath


Please note that this will only work on *nix systems. As readline is only available in Unix platform.
Wed Nov 24 07:31:05 2010
Thank God for Tripper McCarthy
A long time ago, in our galaxy, Tripper McCarthy posted this:

Tripper McCarthy  Tue Jun 24 2003 19:19:31 GMT-0500 (CDT) 

 There have been several posts asking how to change the body of a message
(not the header) from within a handler. Here is a way to pull it off. It's a
little strange, but it works. 

    public void invoke(MessageContext msgContext) throws AxisFault {
        try {
            javax.xml.soap.SOAPMessage soapMessage =
msgContext.getRequestMessage();
            String oldRequest =
soapMessage.getSOAPPart().getEnvelope().toString();
            
            int index = oldRequest.indexOf("
            index = oldRequest.indexOf(">",index);
            String newRequest = oldRequest.substring(0,index+1) +
                "5" +
                oldRequest.substring(index+1,oldRequest.length());
            
            ByteArrayInputStream istream = new
ByteArrayInputStream(newRequest.getBytes());            
            Message msg = new Message(istream, false);
            msgContext.setRequestMessage(msg);

        }
        catch(Exception e) {
            e.printStackTrace();
            throw new AxisFault(e.getMessage());
        }
    }


Thanks Tripper. I've been beating my head for hours trying to modify the message using the deeply-nested object model in Handler. Your solution cut to the chase.
Mon Oct 25 09:13:44 2010
RedHat Enterprise 5 and Python
Update:

I found it difficult to make Python 2.6 the default distribution for RHEL. It jacks up YUM when you do it. So I'm abandoning that approach altogether. The following notes were taken before I decided to take a different approach.



Python 2.4 is the python that ships with RedHat Enterprise Linux 5. This will never do.

I didn't remove 2.4 because some suggested against it, saying that RedHat needs to keep this version around.

Suppose you want to go to version 2.6. Here's what to do: either install from repo (yum install python26), which requires that you enable EPEL, or build from Python from source. It will install along side 2.4. When you next run Python you will find that the OS is still defaulting to 2.4. To fix this run update-alternatives.

update-alternatives --config python


Run Python again and your system wide default should now be the latest version you installed.

Alert: After building my own 2.6 and following the process above, I discovered that I had inadvertently screwed up YUM. Beware this process until I post final comments.
Fri Oct 22 10:59:42 2010
Shrink PDF file on linux (command line)
gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/screen -dNOPAUSE -dQUIET -sPAPERSIZE=a4 -dBATCH -sOutputFile=output.pdf input.pdf
Tue Mar 16 15:51:21 2010
JSON API
Tue Mar 16 15:51:20 2010
XML API
Tue Mar 16 15:51:20 2010
Mashup Editor
Tue Mar 16 15:51:19 2010
Object with links to Related Records
Tue Mar 16 15:51:19 2010
Search Result Page
Fri Mar 12 21:28:26 2010
Sitting Under Canvas (8-bit)
Thu Feb 11 19:24:07 2010
I love my retro layout.
Mon Dec 28 15:24:03 2009
ZynAddSubFX Packaged
Mon Dec 28 15:24:02 2009
ZynAddSubFX Compiled
Fri Nov 20 19:54:23 2009
lolas
Thu Nov 19 19:13:45 2009
Crypto Nerd's Imagination