From 8f3b198c230deaeef7100535ed46cebff5079972 Mon Sep 17 00:00:00 2001
From: notmasteryet <async.processingjs@yahoo.com>
Date: Sun, 19 Feb 2012 20:12:57 -0600
Subject: [PATCH 01/15] Check if glyph are stored outside the glyf table

---
 src/fonts.js            |  10 +++++++++-
 test/pdfs/.gitignore    |   1 +
 test/pdfs/issue1249.pdf | Bin 0 -> 68783 bytes
 test/test_manifest.json |   6 ++++++
 4 files changed, 16 insertions(+), 1 deletion(-)
 create mode 100644 test/pdfs/issue1249.pdf

diff --git a/src/fonts.js b/src/fonts.js
index 0f9b6f9d0..23a08c0c7 100644
--- a/src/fonts.js
+++ b/src/fonts.js
@@ -1636,12 +1636,20 @@ var Font = (function FontClosure() {
         var locaData = loca.data;
         // removing the invalid glyphs
         var oldGlyfData = glyf.data;
-        var newGlyfData = new Uint8Array(oldGlyfData.length);
+        var oldGlyfDataLength = oldGlyfData.length;
+        var newGlyfData = new Uint8Array(oldGlyfDataLength);
         var startOffset = itemDecode(locaData, 0);
         var writeOffset = 0;
         itemEncode(locaData, 0, writeOffset);
         for (var i = 0, j = itemSize; i < numGlyphs; i++, j += itemSize) {
           var endOffset = itemDecode(locaData, j);
+          if (endOffset > oldGlyfDataLength) {
+            // glyph end offset points outside glyf data, rejecting the glyph
+            itemEncode(locaData, j, writeOffset);
+            startOffset = endOffset;
+            continue;
+          }
+
           var newLength = sanitizeGlyph(oldGlyfData, startOffset, endOffset,
                                         newGlyfData, writeOffset);
           writeOffset += newLength;
diff --git a/test/pdfs/.gitignore b/test/pdfs/.gitignore
index e0926492b..7e79f90f0 100644
--- a/test/pdfs/.gitignore
+++ b/test/pdfs/.gitignore
@@ -20,6 +20,7 @@
 !scan-bad.pdf
 !freeculture.pdf
 !issue918.pdf
+!issue1249.pdf
 !smaskdim.pdf
 !type4psfunc.pdf
 !S2.pdf
diff --git a/test/pdfs/issue1249.pdf b/test/pdfs/issue1249.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..f7bacda0241f7fdf7f069037999e0fda4580a942
GIT binary patch
literal 68783
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

literal 0
HcmV?d00001

diff --git a/test/test_manifest.json b/test/test_manifest.json
index e09f16da9..19d25317a 100644
--- a/test/test_manifest.json
+++ b/test/test_manifest.json
@@ -417,6 +417,12 @@
       "link": true,
       "type": "eq"
     },
+    {  "id": "issue1249-load",
+      "file": "pdfs/issue1249.pdf",
+      "md5": "4f81339fa09422a7db980f34ea963609",
+      "rounds": 1,
+      "type": "load"
+    },
     {  "id": "liveprogramming",
       "file": "pdfs/liveprogramming.pdf",
       "md5": "7bd4dad1188232ef597d36fd72c33e52",

From 0ea87068ed9683c7483abd45b110e264cfa4fee9 Mon Sep 17 00:00:00 2001
From: notmasteryet <async.processingjs@yahoo.com>
Date: Wed, 22 Feb 2012 21:52:29 -0600
Subject: [PATCH 02/15] Skipping HTTP POST requests in the addon

---
 extensions/firefox/components/PdfStreamConverter.js | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/extensions/firefox/components/PdfStreamConverter.js b/extensions/firefox/components/PdfStreamConverter.js
index 06db4e2d3..c6dab9ba7 100644
--- a/extensions/firefox/components/PdfStreamConverter.js
+++ b/extensions/firefox/components/PdfStreamConverter.js
@@ -124,6 +124,19 @@ PdfStreamConverter.prototype = {
   asyncConvertData: function(aFromType, aToType, aListener, aCtxt) {
     if (!Services.prefs.getBoolPref('extensions.pdf.js.active'))
       throw Cr.NS_ERROR_NOT_IMPLEMENTED;
+
+    // Ignoring HTTP POST requests -- pdf.js has to repeat the request.
+    var skipConversion = false;
+    try {
+      var request = aCtxt;
+      request.QueryInterface(Ci.nsIHttpChannel);
+      skipConversion = (request.requestMethod === 'POST');
+    } catch (e) {
+      // Non-HTTP request... continue normally.
+    }
+    if (skipConversion)
+      throw Cr.NS_ERROR_NOT_IMPLEMENTED;
+
     // Store the listener passed to us
     this.listener = aListener;
   },

From d0143cc2894307a7d0e652e190f9d2a67874dfb2 Mon Sep 17 00:00:00 2001
From: Brendan Dahl <brendan.dahl@gmail.com>
Date: Thu, 23 Feb 2012 09:21:35 -0800
Subject: [PATCH 03/15] Fix missing bidi for extension.

---
 src/bidi.js   | 2 +-
 web/viewer.js | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/bidi.js b/src/bidi.js
index a3308fa2c..a6e3e429f 100644
--- a/src/bidi.js
+++ b/src/bidi.js
@@ -3,7 +3,7 @@
 
 'use strict';
 
-var bidi = (function bidiClosure() {
+var bidi = PDFJS.bidi = (function bidiClosure() {
   // Character types for symbols from 0000 to 00FF.
   var baseTypes = [
     'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'BN', 'S', 'B', 'S', 'WS',
diff --git a/web/viewer.js b/web/viewer.js
index 0a1ad7508..9f477f3a7 100644
--- a/web/viewer.js
+++ b/web/viewer.js
@@ -1097,7 +1097,7 @@ var TextLayerBuilder = function textLayerBuilder(textLayerDiv) {
     textDiv.style.fontSize = fontHeight + 'px';
     textDiv.style.left = text.geom.x + 'px';
     textDiv.style.top = (text.geom.y - fontHeight) + 'px';
-    textDiv.textContent = bidi(text, -1);
+    textDiv.textContent = PDFJS.bidi(text, -1);
     textDiv.dir = text.direction;
     textDiv.dataset.textLength = text.length;
     this.textDivs.push(textDiv);

From 2cc89735aea412870c5b3cc0ace446d8b621916c Mon Sep 17 00:00:00 2001
From: notmasteryet <async.processingjs@yahoo.com>
Date: Wed, 29 Feb 2012 18:31:03 -0600
Subject: [PATCH 04/15] Fixing cap1 statement

---
 src/fonts.js | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/src/fonts.js b/src/fonts.js
index 542c33f55..9d11d81cc 100644
--- a/src/fonts.js
+++ b/src/fonts.js
@@ -1863,6 +1863,13 @@ var Font = (function FontClosure() {
         var hasShortCmap = !!cmapTable.hasShortCmap;
         var toFontChar = this.toFontChar;
 
+        if (hasShortCmap && ids.length == numGlyphs) {
+          // Fixes the short cmap tables -- some generators use incorrect
+          // glyph id.
+          for (var i = 0, ii = ids.length; i < ii; i++)
+            ids[i] = i;
+        }
+
         if (toFontChar && toFontChar.length > 0) {
           // checking if cmap is just identity map
           var isIdentity = true;
@@ -1906,11 +1913,14 @@ var Font = (function FontClosure() {
           // copying all characters to private use area, all mapping all known
           // glyphs to the unicodes. The glyphs and ids arrays will grow.
           var usedUnicodes = [];
+          var glyphNames = properties.glyphNames || [];
           for (var i = 0, ii = glyphs.length; i < ii; i++) {
             var code = glyphs[i].unicode;
+            var gid = ids[i];
             glyphs[i].unicode += kCmapGlyphOffset;
+            toFontChar[code] = glyphs[i].unicode;
 
-            var glyphName = properties.baseEncoding[code];
+            var glyphName = glyphNames[gid] || properties.baseEncoding[code];
             if (glyphName in GlyphsUnicode) {
               var unicode = GlyphsUnicode[glyphName];
               if (unicode in usedUnicodes)
@@ -1921,9 +1931,11 @@ var Font = (function FontClosure() {
                 unicode: unicode,
                 code: glyphs[i].code
               });
-              ids.push(ids[i]);
+              ids.push(gid);
+              toFontChar[code] = unicode;
             }
           }
+          this.useToFontChar = true;
         }
 
         // Moving all symbolic font glyphs into 0xF000 - 0xF0FF range.

From a6b9efc06bc7ef12806c26cbcefc1feebbb7467f Mon Sep 17 00:00:00 2001
From: notmasteryet <async.processingjs@yahoo.com>
Date: Wed, 29 Feb 2012 22:11:32 -0600
Subject: [PATCH 05/15] Re-encode cmap based on post table or current encoding;
 fix GlyphsUnicode table entries

---
 src/fonts.js     | 58 ++++++++++++++++++++++++++++++++--
 src/glyphlist.js | 81 ------------------------------------------------
 2 files changed, 55 insertions(+), 84 deletions(-)

diff --git a/src/fonts.js b/src/fonts.js
index 9d11d81cc..d04fd1a4e 100644
--- a/src/fonts.js
+++ b/src/fonts.js
@@ -1870,6 +1870,9 @@ var Font = (function FontClosure() {
             ids[i] = i;
         }
 
+        var unusedUnicode = kCmapGlyphOffset;
+        var glyphNames = properties.glyphNames || [];
+        var encoding = properties.baseEncoding;
         if (toFontChar && toFontChar.length > 0) {
           // checking if cmap is just identity map
           var isIdentity = true;
@@ -1892,7 +1895,6 @@ var Font = (function FontClosure() {
               glyphs[i].unicode = unicode;
               usedUnicodes[unicode] = true;
             }
-            var unusedUnicode = kCmapGlyphOffset;
             for (var j = 0, jj = unassignedUnicodeItems.length; j < jj; j++) {
               var i = unassignedUnicodeItems[j];
               while (unusedUnicode in usedUnicodes)
@@ -1913,14 +1915,13 @@ var Font = (function FontClosure() {
           // copying all characters to private use area, all mapping all known
           // glyphs to the unicodes. The glyphs and ids arrays will grow.
           var usedUnicodes = [];
-          var glyphNames = properties.glyphNames || [];
           for (var i = 0, ii = glyphs.length; i < ii; i++) {
             var code = glyphs[i].unicode;
             var gid = ids[i];
             glyphs[i].unicode += kCmapGlyphOffset;
             toFontChar[code] = glyphs[i].unicode;
 
-            var glyphName = glyphNames[gid] || properties.baseEncoding[code];
+            var glyphName = glyphNames[gid] || encoding[code];
             if (glyphName in GlyphsUnicode) {
               var unicode = GlyphsUnicode[glyphName];
               if (unicode in usedUnicodes)
@@ -1936,6 +1937,57 @@ var Font = (function FontClosure() {
             }
           }
           this.useToFontChar = true;
+        } else if (!this.isSymbolicFont &&
+                   (this.hasEncoding || properties.glyphNames)) {
+          // Re-encode cmap encoding to unicode, based on the 'post' table data
+          // or base encoding
+          var reverseMap = [];
+          for (var i = 0, ii = glyphs.length; i < ii; i++)
+            reverseMap[glyphs[i].unicode] = i;
+
+          for (var i = 0, ii = glyphs.length; i < ii; i++) {
+            var code = glyphs[i].unicode;
+            var gid = ids[i]
+
+            var glyphName = glyphNames[gid] || encoding[code];
+            if (glyphName in GlyphsUnicode) {
+              var unicode = GlyphsUnicode[glyphName];
+              if (!unicode || reverseMap[unicode] === i)
+                continue; // unknown glyph name or in its own place
+
+              var destination = reverseMap[unicode];
+              var j = i;
+              // Flipping unicodes while next destination unicode has assigned
+              // glyph and future glyph can be assigned to unicode.
+              while (typeof destination === 'number') {
+                glyphs[j].unicode = unicode;
+                reverseMap[unicode] = j;
+
+                code = glyphs[destination].unicode;
+                gid = ids[destination];
+                glyphName = glyphNames[gid] || encoding[code];
+
+                unicode = GlyphsUnicode[glyphName];
+                if (!unicode || reverseMap[unicode] === j) {
+                  unicode = 0;
+                  break; // unknown glyph name or in its own place
+                }
+
+                j = destination;
+                destination = reverseMap[unicode];
+              }
+
+              if (!unicode) {
+                // Future glyph cannot be assigned to unicode, generate new one.
+                while (reverseMap[unusedUnicode])
+                  unusedUnicode++;
+                unicode = unusedUnicode++;
+              }
+
+              glyphs[j].unicode = unicode;
+              reverseMap[unicode] = j;
+            }
+          }
         }
 
         // Moving all symbolic font glyphs into 0xF000 - 0xF0FF range.
diff --git a/src/glyphlist.js b/src/glyphlist.js
index 01b94442a..694134840 100644
--- a/src/glyphlist.js
+++ b/src/glyphlist.js
@@ -1508,27 +1508,7 @@ var GlyphsUnicode = {
   dalet: 0x05D3,
   daletdagesh: 0xFB33,
   daletdageshhebrew: 0xFB33,
-  dalethatafpatah: 0x05D305B2,
-  dalethatafpatahhebrew: 0x05D305B2,
-  dalethatafsegol: 0x05D305B1,
-  dalethatafsegolhebrew: 0x05D305B1,
   dalethebrew: 0x05D3,
-  dalethiriq: 0x05D305B4,
-  dalethiriqhebrew: 0x05D305B4,
-  daletholam: 0x05D305B9,
-  daletholamhebrew: 0x05D305B9,
-  daletpatah: 0x05D305B7,
-  daletpatahhebrew: 0x05D305B7,
-  daletqamats: 0x05D305B8,
-  daletqamatshebrew: 0x05D305B8,
-  daletqubuts: 0x05D305BB,
-  daletqubutshebrew: 0x05D305BB,
-  daletsegol: 0x05D305B6,
-  daletsegolhebrew: 0x05D305B6,
-  daletsheva: 0x05D305B0,
-  daletshevahebrew: 0x05D305B0,
-  dalettsere: 0x05D305B5,
-  dalettserehebrew: 0x05D305B5,
   dalfinalarabic: 0xFEAA,
   dammaarabic: 0x064F,
   dammalowarabic: 0x064F,
@@ -1845,10 +1825,6 @@ var GlyphsUnicode = {
   finalkafdagesh: 0xFB3A,
   finalkafdageshhebrew: 0xFB3A,
   finalkafhebrew: 0x05DA,
-  finalkafqamats: 0x05DA05B8,
-  finalkafqamatshebrew: 0x05DA05B8,
-  finalkafsheva: 0x05DA05B0,
-  finalkafshevahebrew: 0x05DA05B0,
   finalmem: 0x05DD,
   finalmemhebrew: 0x05DD,
   finalnun: 0x05DF,
@@ -2037,14 +2013,7 @@ var GlyphsUnicode = {
   hakatakanahalfwidth: 0xFF8A,
   halantgurmukhi: 0x0A4D,
   hamzaarabic: 0x0621,
-  hamzadammaarabic: 0x0621064F,
-  hamzadammatanarabic: 0x0621064C,
-  hamzafathaarabic: 0x0621064E,
-  hamzafathatanarabic: 0x0621064B,
   hamzalowarabic: 0x0621,
-  hamzalowkasraarabic: 0x06210650,
-  hamzalowkasratanarabic: 0x0621064D,
-  hamzasukunarabic: 0x06210652,
   hangulfiller: 0x3164,
   hardsigncyrillic: 0x044A,
   harpoonleftbarbup: 0x21BC,
@@ -2476,10 +2445,6 @@ var GlyphsUnicode = {
   lameddagesh: 0xFB3C,
   lameddageshhebrew: 0xFB3C,
   lamedhebrew: 0x05DC,
-  lamedholam: 0x05DC05B9,
-  lamedholamdagesh: '05DC 05B9 05BC',
-  lamedholamdageshhebrew: '05DC 05B9 05BC',
-  lamedholamhebrew: 0x05DC05B9,
   lamfinalarabic: 0xFEDE,
   lamhahinitialarabic: 0xFCCA,
   laminitialarabic: 0xFEDF,
@@ -2489,8 +2454,6 @@ var GlyphsUnicode = {
   lammedialarabic: 0xFEE0,
   lammeemhahinitialarabic: 0xFD88,
   lammeeminitialarabic: 0xFCCC,
-  lammeemjeeminitialarabic: 'FEDF FEE4 FEA0',
-  lammeemkhahinitialarabic: 'FEDF FEE4 FEA8',
   largecircle: 0x25EF,
   lbar: 0x019A,
   lbelt: 0x026C,
@@ -2787,7 +2750,6 @@ var GlyphsUnicode = {
   noonfinalarabic: 0xFEE6,
   noonghunnaarabic: 0x06BA,
   noonghunnafinalarabic: 0xFB9F,
-  noonhehinitialarabic: 0xFEE7FEEC,
   nooninitialarabic: 0xFEE7,
   noonjeeminitialarabic: 0xFCD2,
   noonjeemisolatedarabic: 0xFC4B,
@@ -3159,27 +3121,7 @@ var GlyphsUnicode = {
   qof: 0x05E7,
   qofdagesh: 0xFB47,
   qofdageshhebrew: 0xFB47,
-  qofhatafpatah: 0x05E705B2,
-  qofhatafpatahhebrew: 0x05E705B2,
-  qofhatafsegol: 0x05E705B1,
-  qofhatafsegolhebrew: 0x05E705B1,
   qofhebrew: 0x05E7,
-  qofhiriq: 0x05E705B4,
-  qofhiriqhebrew: 0x05E705B4,
-  qofholam: 0x05E705B9,
-  qofholamhebrew: 0x05E705B9,
-  qofpatah: 0x05E705B7,
-  qofpatahhebrew: 0x05E705B7,
-  qofqamats: 0x05E705B8,
-  qofqamatshebrew: 0x05E705B8,
-  qofqubuts: 0x05E705BB,
-  qofqubutshebrew: 0x05E705BB,
-  qofsegol: 0x05E705B6,
-  qofsegolhebrew: 0x05E705B6,
-  qofsheva: 0x05E705B0,
-  qofshevahebrew: 0x05E705B0,
-  qoftsere: 0x05E705B5,
-  qoftserehebrew: 0x05E705B5,
   qparen: 0x24AC,
   quarternote: 0x2669,
   qubuts: 0x05BB,
@@ -3253,32 +3195,11 @@ var GlyphsUnicode = {
   reharmenian: 0x0580,
   rehfinalarabic: 0xFEAE,
   rehiragana: 0x308C,
-  rehyehaleflamarabic: '0631 FEF3 FE8E 0644',
   rekatakana: 0x30EC,
   rekatakanahalfwidth: 0xFF9A,
   resh: 0x05E8,
   reshdageshhebrew: 0xFB48,
-  reshhatafpatah: 0x05E805B2,
-  reshhatafpatahhebrew: 0x05E805B2,
-  reshhatafsegol: 0x05E805B1,
-  reshhatafsegolhebrew: 0x05E805B1,
   reshhebrew: 0x05E8,
-  reshhiriq: 0x05E805B4,
-  reshhiriqhebrew: 0x05E805B4,
-  reshholam: 0x05E805B9,
-  reshholamhebrew: 0x05E805B9,
-  reshpatah: 0x05E805B7,
-  reshpatahhebrew: 0x05E805B7,
-  reshqamats: 0x05E805B8,
-  reshqamatshebrew: 0x05E805B8,
-  reshqubuts: 0x05E805BB,
-  reshqubutshebrew: 0x05E805BB,
-  reshsegol: 0x05E805B6,
-  reshsegolhebrew: 0x05E805B6,
-  reshsheva: 0x05E805B0,
-  reshshevahebrew: 0x05E805B0,
-  reshtsere: 0x05E805B5,
-  reshtserehebrew: 0x05E805B5,
   reversedtilde: 0x223D,
   reviahebrew: 0x0597,
   reviamugrashhebrew: 0x0597,
@@ -3477,7 +3398,6 @@ var GlyphsUnicode = {
   shaddadammaarabic: 0xFC61,
   shaddadammatanarabic: 0xFC5E,
   shaddafathaarabic: 0xFC60,
-  shaddafathatanarabic: 0x0651064B,
   shaddakasraarabic: 0xFC62,
   shaddakasratanarabic: 0xFC5F,
   shade: 0x2592,
@@ -3674,7 +3594,6 @@ var GlyphsUnicode = {
   tchehfinalarabic: 0xFB7B,
   tchehinitialarabic: 0xFB7C,
   tchehmedialarabic: 0xFB7D,
-  tchehmeeminitialarabic: 0xFB7CFEE4,
   tcircle: 0x24E3,
   tcircumflexbelow: 0x1E71,
   tcommaaccent: 0x0163,

From 8cb8de3092c90e1ceb6753372ef6ab4b0b33bd57 Mon Sep 17 00:00:00 2001
From: notmasteryet <async.processingjs@yahoo.com>
Date: Wed, 29 Feb 2012 22:57:54 -0600
Subject: [PATCH 06/15] Lint error

---
 src/fonts.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/fonts.js b/src/fonts.js
index d04fd1a4e..1992c0c7d 100644
--- a/src/fonts.js
+++ b/src/fonts.js
@@ -1947,7 +1947,7 @@ var Font = (function FontClosure() {
 
           for (var i = 0, ii = glyphs.length; i < ii; i++) {
             var code = glyphs[i].unicode;
-            var gid = ids[i]
+            var gid = ids[i];
 
             var glyphName = glyphNames[gid] || encoding[code];
             if (glyphName in GlyphsUnicode) {

From 447098936cde2ceeb62d080edfd7418fceabc91d Mon Sep 17 00:00:00 2001
From: Artur Adib <arturadib@gmail.com>
Date: Thu, 1 Mar 2012 12:31:53 -0500
Subject: [PATCH 07/15] dummy README - testing bot's gh-pages update

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 33bb30b66..c9631df61 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
 # PDF.JS
-
+ 
 
 pdf.js is an HTML5 technology experiment that explores building a faithful
 and efficient Portable Document Format (PDF) renderer without native code 

From fb1276c00f232fadbc269f04102fcf251c6f21f9 Mon Sep 17 00:00:00 2001
From: Artur Adib <arturadib@gmail.com>
Date: Thu, 1 Mar 2012 12:35:38 -0500
Subject: [PATCH 08/15] testing bot

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index c9631df61..33bb30b66 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
 # PDF.JS
- 
+
 
 pdf.js is an HTML5 technology experiment that explores building a faithful
 and efficient Portable Document Format (PDF) renderer without native code 

From 65811a7bfe5e730c770a1d368e51995f4040943f Mon Sep 17 00:00:00 2001
From: Artur Adib <arturadib@gmail.com>
Date: Thu, 1 Mar 2012 12:41:06 -0500
Subject: [PATCH 09/15] another bot test

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 33bb30b66..c9631df61 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
 # PDF.JS
-
+ 
 
 pdf.js is an HTML5 technology experiment that explores building a faithful
 and efficient Portable Document Format (PDF) renderer without native code 

From 38e3f32557a8a96fba2fea3851a0e2d6b0563598 Mon Sep 17 00:00:00 2001
From: notmasteryet <async.processingjs@yahoo.com>
Date: Thu, 1 Mar 2012 21:23:36 -0600
Subject: [PATCH 10/15] Add and fix pdfkit_compressed.pdf

---
 src/fonts.js                    |  30 +++++++++++++++++++++++++-----
 test/pdfs/.gitignore            |   1 +
 test/pdfs/pdfkit_compressed.pdf | Bin 0 -> 8286 bytes
 test/test_manifest.json         |   6 ++++++
 4 files changed, 32 insertions(+), 5 deletions(-)
 create mode 100644 test/pdfs/pdfkit_compressed.pdf

diff --git a/src/fonts.js b/src/fonts.js
index 261a907f2..0d0e12fec 100644
--- a/src/fonts.js
+++ b/src/fonts.js
@@ -1881,6 +1881,7 @@ var Font = (function FontClosure() {
         var unusedUnicode = kCmapGlyphOffset;
         var glyphNames = properties.glyphNames || [];
         var encoding = properties.baseEncoding;
+        var differences = properties.differences;
         if (toFontChar && toFontChar.length > 0) {
           // checking if cmap is just identity map
           var isIdentity = true;
@@ -1945,35 +1946,51 @@ var Font = (function FontClosure() {
             }
           }
           this.useToFontChar = true;
-        } else if (!this.isSymbolicFont &&
-                   (this.hasEncoding || properties.glyphNames)) {
+        } else if (!this.isSymbolicFont && (this.hasEncoding ||
+                    properties.glyphNames || differences.length > 0)) {
           // Re-encode cmap encoding to unicode, based on the 'post' table data
-          // or base encoding
+          // diffrence array or base encoding
           var reverseMap = [];
           for (var i = 0, ii = glyphs.length; i < ii; i++)
             reverseMap[glyphs[i].unicode] = i;
 
           for (var i = 0, ii = glyphs.length; i < ii; i++) {
             var code = glyphs[i].unicode;
+            var changeCode = false;
             var gid = ids[i];
 
-            var glyphName = glyphNames[gid] || encoding[code];
+            var glyphName = glyphNames[gid];
+            if (!glyphName) {
+              glyphName = differences[code] || encoding[code];
+              changeCode = true;
+            }
             if (glyphName in GlyphsUnicode) {
               var unicode = GlyphsUnicode[glyphName];
               if (!unicode || reverseMap[unicode] === i)
                 continue; // unknown glyph name or in its own place
 
               var destination = reverseMap[unicode];
+              if (typeof destination === 'number' && destination > i)
+                continue;
+
               var j = i;
               // Flipping unicodes while next destination unicode has assigned
               // glyph and future glyph can be assigned to unicode.
               while (typeof destination === 'number') {
                 glyphs[j].unicode = unicode;
                 reverseMap[unicode] = j;
+                if (changeCode) {
+                  toFontChar[code] = unicode;
+                  changeCode = false;
+                }
 
                 code = glyphs[destination].unicode;
                 gid = ids[destination];
-                glyphName = glyphNames[gid] || encoding[code];
+                glyphName = glyphNames[gid];
+                if (!glyphName) {
+                  glyphName = differences[code] || encoding[code];
+                  changeCode = true;
+                }
 
                 unicode = GlyphsUnicode[glyphName];
                 if (!unicode || reverseMap[unicode] === j) {
@@ -1994,7 +2011,10 @@ var Font = (function FontClosure() {
 
               glyphs[j].unicode = unicode;
               reverseMap[unicode] = j;
+              if (changeCode)
+                toFontChar[code] = unicode;
             }
+            this.useToFontChar = true;
           }
         }
 
diff --git a/test/pdfs/.gitignore b/test/pdfs/.gitignore
index 81b63290d..f14236860 100644
--- a/test/pdfs/.gitignore
+++ b/test/pdfs/.gitignore
@@ -19,6 +19,7 @@
 !issue840.pdf
 !scan-bad.pdf
 !freeculture.pdf
+!pdfkit_compressed.pdf
 !issue918.pdf
 !issue1249.pdf
 !smaskdim.pdf
diff --git a/test/pdfs/pdfkit_compressed.pdf b/test/pdfs/pdfkit_compressed.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..f3e25216d231f4b18c14e33b00bfc7877650c30c
GIT binary patch
literal 8286
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
NVEHN=o07Kj{{RcE)-wPA

literal 0
HcmV?d00001

diff --git a/test/test_manifest.json b/test/test_manifest.json
index c2cbaa415..16d924151 100644
--- a/test/test_manifest.json
+++ b/test/test_manifest.json
@@ -466,6 +466,12 @@
       "link": true,
       "type": "eq"
     },
+    {  "id": "pdfkit_compressed",
+      "file": "pdfs/pdfkit_compressed.pdf",
+      "md5": "ffe9c571d0a1572e234253e6c7cdee6c",
+      "rounds": 1,
+      "type": "eq"
+    },
     {  "id": "issue925",
       "file": "pdfs/issue925.pdf",
       "md5": "f58fe943090aff89dcc8e771bc0db4c2",

From ab3107e8e0df30f2006fca6881aebb3730f5fd63 Mon Sep 17 00:00:00 2001
From: notmasteryet <async.processingjs@yahoo.com>
Date: Thu, 1 Mar 2012 22:01:39 -0600
Subject: [PATCH 11/15] Optimization

---
 src/fonts.js | 48 ++++--------------------------------------------
 1 file changed, 4 insertions(+), 44 deletions(-)

diff --git a/src/fonts.js b/src/fonts.js
index 0d0e12fec..df0acbbc5 100644
--- a/src/fonts.js
+++ b/src/fonts.js
@@ -1966,51 +1966,11 @@ var Font = (function FontClosure() {
             }
             if (glyphName in GlyphsUnicode) {
               var unicode = GlyphsUnicode[glyphName];
-              if (!unicode || reverseMap[unicode] === i)
-                continue; // unknown glyph name or in its own place
+              if (!unicode || (unicode in reverseMap))
+                continue; // unknown glyph name or its place is taken
 
-              var destination = reverseMap[unicode];
-              if (typeof destination === 'number' && destination > i)
-                continue;
-
-              var j = i;
-              // Flipping unicodes while next destination unicode has assigned
-              // glyph and future glyph can be assigned to unicode.
-              while (typeof destination === 'number') {
-                glyphs[j].unicode = unicode;
-                reverseMap[unicode] = j;
-                if (changeCode) {
-                  toFontChar[code] = unicode;
-                  changeCode = false;
-                }
-
-                code = glyphs[destination].unicode;
-                gid = ids[destination];
-                glyphName = glyphNames[gid];
-                if (!glyphName) {
-                  glyphName = differences[code] || encoding[code];
-                  changeCode = true;
-                }
-
-                unicode = GlyphsUnicode[glyphName];
-                if (!unicode || reverseMap[unicode] === j) {
-                  unicode = 0;
-                  break; // unknown glyph name or in its own place
-                }
-
-                j = destination;
-                destination = reverseMap[unicode];
-              }
-
-              if (!unicode) {
-                // Future glyph cannot be assigned to unicode, generate new one.
-                while (reverseMap[unusedUnicode])
-                  unusedUnicode++;
-                unicode = unusedUnicode++;
-              }
-
-              glyphs[j].unicode = unicode;
-              reverseMap[unicode] = j;
+              glyphs[i].unicode = unicode;
+              reverseMap[unicode] = i;
               if (changeCode)
                 toFontChar[code] = unicode;
             }

From b870cbad0f38235d1bc19efd8f331f85aec34e76 Mon Sep 17 00:00:00 2001
From: notmasteryet <async.processingjs@yahoo.com>
Date: Fri, 2 Mar 2012 07:11:24 -0600
Subject: [PATCH 12/15] Move custom style

---
 src/util.js   | 51 ---------------------------------------------------
 web/viewer.js | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 51 insertions(+), 51 deletions(-)

diff --git a/src/util.js b/src/util.js
index b0739ec3a..93bd36b55 100644
--- a/src/util.js
+++ b/src/util.js
@@ -174,57 +174,6 @@ var Util = (function UtilClosure() {
   return Util;
 })();
 
-// optimised CSS custom property getter/setter
-var CustomStyle = (function CustomStyleClosure() {
-
-  // As noted on: http://www.zachstronaut.com/posts/2009/02/17/
-  //              animate-css-transforms-firefox-webkit.html
-  // in some versions of IE9 it is critical that ms appear in this list
-  // before Moz
-  var prefixes = ['ms', 'Moz', 'Webkit', 'O'];
-  var _cache = { };
-
-  function CustomStyle() {
-  }
-
-  CustomStyle.getProp = function get(propName, element) {
-    // check cache only when no element is given
-    if (arguments.length == 1 && typeof _cache[propName] == 'string') {
-      return _cache[propName];
-    }
-
-    element = element || document.documentElement;
-    var style = element.style, prefixed, uPropName;
-
-    // test standard property first
-    if (typeof style[propName] == 'string') {
-      return (_cache[propName] = propName);
-    }
-
-    // capitalize
-    uPropName = propName.charAt(0).toUpperCase() + propName.slice(1);
-
-    // test vendor specific properties
-    for (var i = 0, l = prefixes.length; i < l; i++) {
-      prefixed = prefixes[i] + uPropName;
-      if (typeof style[prefixed] == 'string') {
-        return (_cache[propName] = prefixed);
-      }
-    }
-
-    //if all fails then set to undefined
-    return (_cache[propName] = 'undefined');
-  }
-
-  CustomStyle.setProp = function set(propName, element, str) {
-    var prop = this.getProp(propName);
-    if (prop != 'undefined')
-      element.style[prop] = str;
-  }
-
-  return CustomStyle;
-})();
-
 var PDFStringTranslateTable = [
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   0x2D8, 0x2C7, 0x2C6, 0x2D9, 0x2DD, 0x2DB, 0x2DA, 0x2DC, 0, 0, 0, 0, 0, 0, 0,
diff --git a/web/viewer.js b/web/viewer.js
index 9f477f3a7..77bbc2c0e 100644
--- a/web/viewer.js
+++ b/web/viewer.js
@@ -1022,6 +1022,57 @@ var DocumentOutlineView = function documentOutlineView(outline) {
   }
 };
 
+// optimised CSS custom property getter/setter
+var CustomStyle = (function CustomStyleClosure() {
+
+  // As noted on: http://www.zachstronaut.com/posts/2009/02/17/
+  //              animate-css-transforms-firefox-webkit.html
+  // in some versions of IE9 it is critical that ms appear in this list
+  // before Moz
+  var prefixes = ['ms', 'Moz', 'Webkit', 'O'];
+  var _cache = { };
+
+  function CustomStyle() {
+  }
+
+  CustomStyle.getProp = function get(propName, element) {
+    // check cache only when no element is given
+    if (arguments.length == 1 && typeof _cache[propName] == 'string') {
+      return _cache[propName];
+    }
+
+    element = element || document.documentElement;
+    var style = element.style, prefixed, uPropName;
+
+    // test standard property first
+    if (typeof style[propName] == 'string') {
+      return (_cache[propName] = propName);
+    }
+
+    // capitalize
+    uPropName = propName.charAt(0).toUpperCase() + propName.slice(1);
+
+    // test vendor specific properties
+    for (var i = 0, l = prefixes.length; i < l; i++) {
+      prefixed = prefixes[i] + uPropName;
+      if (typeof style[prefixed] == 'string') {
+        return (_cache[propName] = prefixed);
+      }
+    }
+
+    //if all fails then set to undefined
+    return (_cache[propName] = 'undefined');
+  }
+
+  CustomStyle.setProp = function set(propName, element, str) {
+    var prop = this.getProp(propName);
+    if (prop != 'undefined')
+      element.style[prop] = str;
+  }
+
+  return CustomStyle;
+})();
+
 var TextLayerBuilder = function textLayerBuilder(textLayerDiv) {
   this.textLayerDiv = textLayerDiv;
 

From f6ba3843bd59337a6760e8df85aedd53685d237e Mon Sep 17 00:00:00 2001
From: Artur Adib <arturadib@gmail.com>
Date: Sat, 3 Mar 2012 14:01:31 -0500
Subject: [PATCH 13/15] Using ShellJS

---
 external/shelljs/LICENSE      |   26 +
 external/shelljs/README.md    |  316 +++++++++
 external/shelljs/global.js    |    3 +
 external/shelljs/make.js      |   46 ++
 external/shelljs/package.json |   12 +
 external/shelljs/shell.js     | 1207 +++++++++++++++++++++++++++++++++
 make.js                       |  401 +++++++++++
 7 files changed, 2011 insertions(+)
 create mode 100644 external/shelljs/LICENSE
 create mode 100644 external/shelljs/README.md
 create mode 100644 external/shelljs/global.js
 create mode 100644 external/shelljs/make.js
 create mode 100644 external/shelljs/package.json
 create mode 100644 external/shelljs/shell.js
 create mode 100755 make.js

diff --git a/external/shelljs/LICENSE b/external/shelljs/LICENSE
new file mode 100644
index 000000000..1b35ee9fb
--- /dev/null
+++ b/external/shelljs/LICENSE
@@ -0,0 +1,26 @@
+Copyright (c) 2012, Artur Adib <aadib@mozilla.com>
+All rights reserved.
+
+You may use this project under the terms of the New BSD license as follows:
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+    * Neither the name of Artur Adib nor the
+      names of the contributors may be used to endorse or promote products
+      derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ARE DISCLAIMED. IN NO EVENT SHALL ARTUR ADIB BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/external/shelljs/README.md b/external/shelljs/README.md
new file mode 100644
index 000000000..01b99a5f8
--- /dev/null
+++ b/external/shelljs/README.md
@@ -0,0 +1,316 @@
+# ShellJS - Unix shell commands for Node.js [![Build Status](https://secure.travis-ci.org/arturadib/shelljs.png)](http://travis-ci.org/arturadib/shelljs)
+
+ShellJS is a **portable** (Windows included) implementation of Unix shell commands on top of the Node.js API. You can use it to eliminate your shell script's dependency on Unix while still keeping its familiar and powerful commands.
+
+The project is both [unit-tested](http://travis-ci.org/arturadib/shelljs) and battle-tested at Mozilla's [pdf.js](http://github.com/mozilla/pdf.js).
+
+
+### Example
+
+```javascript
+require('shelljs/global');
+
+// Copy files to release dir
+mkdir('-p', 'out/Release');
+cp('-R', 'lib/*.js', 'out/Release');
+
+// Replace macros in each .js file
+cd('lib');
+for (file in ls('*.js')) {
+  sed('-i', 'BUILD_VERSION', 'v0.1.2', file);
+  sed('-i', /.*REMOVE_THIS_LINE.*\n/, '', file);
+  sed('-i', /.*REPLACE_LINE_WITH_MACRO.*\n/, cat('macro.js'), file);
+}
+cd('..');
+
+// Run external tool synchronously
+if (exec('git commit -am "Auto-commit"').code !== 0) {
+  echo('Error: Git commit failed');
+  exit(1);
+}
+```
+
+### Global vs. Local
+
+The example above uses the convenience script `shelljs/global` to reduce verbosity. If polluting your global namespace is not desirable, simply require `shelljs`.
+
+Example:
+
+```javascript
+var shell = require('shelljs');
+shell.echo('hello world');
+```
+
+### Make tool
+
+A convenience script `shelljs/make` is also provided to mimic the behavior of a Unix Makefile. In this case all shell objects are global, and command line arguments will cause the script to execute only the corresponding function in the global `target` object. To avoid redundant calls, target functions are executed only once per script.
+
+Example:
+
+```javascript
+//
+// Example file: make.js
+//
+require('shelljs/make');
+
+target.all = function() {
+  target.bundle();
+  target.docs();
+}
+
+// Bundle JS files
+target.bundle = function() {
+  cd(__dirname);
+  mkdir('build');
+  cd('lib');
+  cat('*.js').to('../build/output.js');
+}
+
+// Generate docs
+target.docs = function() {
+  cd(__dirname);
+  mkdir('docs');
+  cd('lib');
+  for (file in ls('*.js')) {
+    var text = grep('//@', file); // extract special comments
+    text.replace('//@', ''); // remove comment tags
+    text.to('docs/my_docs.md');
+  }
+}
+```
+
+To run the target `all`, call the above script without arguments: `$ node make`. To run the target `docs`: `$ node make docs`, and so on.
+
+### Installing
+
+Via npm:
+
+```bash
+$ npm install shelljs
+```
+
+Or simply copy `shell.js` into your project's directory, and `require()` accordingly.
+
+
+<!-- 
+
+  DO NOT MODIFY BEYOND THIS POINT - IT'S AUTOMATICALLY GENERATED
+
+-->
+
+
+# Command reference
+
+
+All commands run synchronously, unless otherwise stated.
+
+
+#### cd('dir')
+Changes to directory `dir` for the duration of the script
+
+#### pwd()
+Returns the current directory.
+
+#### ls([options ,] path [,path ...])
+#### ls([options ,] path_array)
+Available options:
+
++ `-R`: recursive
++ `-a`: all files (include files beginning with `.`)
+
+Examples:
+
+```javascript
+ls('projs/*.js');
+ls('-R', '/users/me', '/tmp');
+ls('-R', ['/users/me', '/tmp']); // same as above
+```
+
+Returns list of files in the given path, or in current directory if no path provided.
+For convenient iteration via `for (file in ls())`, the format returned is a hash object:
+`{ 'file1':null, 'dir1/file2':null, ...}`.
+
+#### cp('[options ,] source [,source ...], dest')
+#### cp('[options ,] source_array, dest')
+Available options:
+
++ `-f`: force
++ `-r, -R`: recursive
+
+Examples:
+
+```javascript
+cp('file1', 'dir1');
+cp('-Rf', '/tmp/*', '/usr/local/*', '/home/tmp');
+cp('-Rf', ['/tmp/*', '/usr/local/*'], '/home/tmp'); // same as above
+```
+
+Copies files. The wildcard `*` is accepted.
+
+#### rm([options ,] file [, file ...])
+#### rm([options ,] file_array)
+Available options:
+
++ `-f`: force
++ `-r, -R`: recursive
+
+Examples:
+
+```javascript
+rm('-rf', '/tmp/*');
+rm('some_file.txt', 'another_file.txt');
+rm(['some_file.txt', 'another_file.txt']); // same as above
+```
+
+Removes files. The wildcard `*` is accepted. 
+
+#### mv(source [, source ...], dest')
+#### mv(source_array, dest')
+Available options:
+
++ `f`: force
+
+Examples:
+
+```javascript
+mv('-f', 'file', 'dir/');
+mv('file1', 'file2', 'dir/');
+mv(['file1', 'file2'], 'dir/'); // same as above
+```
+
+Moves files. The wildcard `*` is accepted.
+
+#### mkdir([options ,] dir [, dir ...])
+#### mkdir([options ,] dir_array)
+Available options:
+
++ `p`: full path (will create intermediate dirs if necessary)
+
+Examples:
+
+```javascript
+mkdir('-p', '/tmp/a/b/c/d', '/tmp/e/f/g');
+mkdir('-p', ['/tmp/a/b/c/d', '/tmp/e/f/g']); // same as above
+```
+
+Creates directories.
+
+#### cat(file [, file ...])
+#### cat(file_array)
+
+Examples:
+
+```javascript
+var str = cat('file*.txt');
+var str = cat('file1', 'file2');
+var str = cat(['file1', 'file2']); // same as above
+```
+
+Returns a string containing the given file, or a concatenated string
+containing the files if more than one file is given (a new line character is
+introduced between each file). Wildcard `*` accepted.
+
+#### 'string'.to(file)
+
+Examples:
+
+```javascript
+cat('input.txt').to('output.txt');
+```
+
+Analogous to the redirection operator `>` in Unix, but works with JavaScript strings (such as
+those returned by `cat`, `grep`, etc). _Like Unix redirections, `to()` will overwrite any existing file!_
+
+#### sed([options ,] search_regex, replace_str, file)
+Available options:
+
++ `-i`: Replace contents of 'file' in-place. _Note that no backups will be created!_
+
+Examples:
+
+```javascript
+sed('-i', 'PROGRAM_VERSION', 'v0.1.3', 'source.js');
+sed(/.*DELETE_THIS_LINE.*\n/, '', 'source.js');
+```
+
+Reads an input string from `file` and performs a JavaScript `replace()` on the input
+using the given search regex and replacement string. Returns the new string after replacement.
+
+#### grep(regex_filter, file [, file ...])
+#### grep(regex_filter, file_array)
+
+Examples:
+
+```javascript
+grep('GLOBAL_VARIABLE', '*.js');
+```
+
+Reads input string from given files and returns a string containing all lines of the 
+file that match the given `regex_filter`. Wildcard `*` accepted.
+
+#### which(command)
+
+Examples:
+
+```javascript
+var nodeExec = which('node');
+```
+
+Searches for `command` in the system's PATH. On Windows looks for `.exe`, `.cmd`, and `.bat` extensions.
+Returns string containing the absolute path to the command.
+
+#### echo(string [,string ...])
+
+Examples:
+
+```javascript
+echo('hello world');
+var str = echo('hello world');
+```
+
+Prints string to stdout, and returns string with additional utility methods
+like `.to()`.
+
+#### exit(code)
+Exits the current process with the given exit code.
+
+#### env['VAR_NAME']
+Object containing environment variables (both getter and setter). Shortcut to process.env.
+
+#### exec(command [, options] [, callback])
+Available options (all `false` by default):
+
++ `async`: Asynchronous execution. Needs callback.
++ `silent`: Do not echo program output to console.
+
+Examples:
+
+```javascript
+var version = exec('node --version', {silent:true}).output;
+```
+
+Executes the given `command` _synchronously_, unless otherwise specified. 
+When in synchronous mode returns the object `{ code:..., output:... }`, containing the program's 
+`output` (stdout + stderr)  and its exit `code`. Otherwise the `callback` gets the 
+arguments `(code, output)`.
+
+## Non-Unix commands
+
+
+#### tempdir()
+Searches and returns string containing a writeable, platform-dependent temporary directory.
+Follows Python's [tempfile algorithm](http://docs.python.org/library/tempfile.html#tempfile.tempdir).
+
+#### exists(path [, path ...])
+#### exists(path_array)
+Returns true if all the given paths exist.
+
+#### error()
+Tests if error occurred in the last command. Returns `null` if no error occurred,
+otherwise returns string explaining the error
+
+#### verbose()
+Enables all output (default)
+
+#### silent()
+Suppresses all output, except for explict `echo()` calls
diff --git a/external/shelljs/global.js b/external/shelljs/global.js
new file mode 100644
index 000000000..83a27e69a
--- /dev/null
+++ b/external/shelljs/global.js
@@ -0,0 +1,3 @@
+var shell = require('./shell.js');
+for (cmd in shell)
+  global[cmd] = shell[cmd];
diff --git a/external/shelljs/make.js b/external/shelljs/make.js
new file mode 100644
index 000000000..9c92dadc8
--- /dev/null
+++ b/external/shelljs/make.js
@@ -0,0 +1,46 @@
+require('./global');
+
+global.target = {};
+
+// This ensures we only execute the script targets after the entire script has
+// been evaluated
+var args = process.argv.slice(2);
+setTimeout(function() {
+
+  if (args.length === 1 && args[0] === '--help') {
+    console.log('Available targets:');
+    for (t in target)
+      console.log('  ' + t);
+    return;
+  }
+
+  // Wrap targets to prevent duplicate execution
+  for (t in target) {
+    (function(t, oldTarget){
+
+      // Wrap it
+      target[t] = function(force) {
+        if (oldTarget.done && !force)
+          return;
+        oldTarget.done = true;
+        return oldTarget(arguments);
+      }
+
+    })(t, target[t]);
+  }
+
+  // Execute desired targets
+  if (args.length > 0) {
+    args.forEach(function(arg) {
+      if (arg in target) 
+        target[arg]();
+      else {
+        console.log('no such target: ' + arg);
+        exit(1);
+      }
+    });
+  } else if ('all' in target) {
+    target.all();
+  }
+
+}, 0);
diff --git a/external/shelljs/package.json b/external/shelljs/package.json
new file mode 100644
index 000000000..9499680e9
--- /dev/null
+++ b/external/shelljs/package.json
@@ -0,0 +1,12 @@
+{ "name": "shelljs"
+, "version": "0.0.2pre1"
+, "author": "Artur Adib <aadib@mozilla.com>"
+, "description": "Portable Unix shell commands for Node.js"
+, "keywords": ["unix", "shell", "makefile", "make", "jake", "synchronous"]
+, "repository": "git://github.com/arturadib/shelljs"
+, "homepage": "http://github.com/arturadib/shelljs"
+, "main": "./shell.js"
+, "scripts": {
+    "test": "node scripts/run-tests"
+  }
+}
diff --git a/external/shelljs/shell.js b/external/shelljs/shell.js
new file mode 100644
index 000000000..2d9a5a787
--- /dev/null
+++ b/external/shelljs/shell.js
@@ -0,0 +1,1207 @@
+//
+// ShellJS
+// Unix shell commands on top of Node's API
+//
+// Copyright (c) 2012 Artur Adib
+// http://github.com/arturadib/shelljs
+//
+
+var fs = require('fs'),
+    path = require('path'),
+    util = require('util'),
+    vm = require('vm'),
+    child = require('child_process'),
+    os = require('os');
+
+// Node shims for < v0.7
+fs.existsSync = fs.existsSync || path.existsSync;
+
+var state = {
+      error: null,
+      fatal: false,
+      silent: false,
+      currentCmd: 'shell.js',
+      tempDir: null
+    },
+    platform = os.type().match(/^Win/) ? 'win' : 'unix';
+
+
+//@
+//@ All commands run synchronously, unless otherwise stated.
+//@ 
+
+
+//@
+//@ #### cd('dir')
+//@ Changes to directory `dir` for the duration of the script
+function _cd(options, dir) {
+  if (!dir)
+    error('directory not specified');
+
+  if (!fs.existsSync(dir))
+    error('no such file or directory: ' + dir);
+
+  if (fs.existsSync(dir) && !fs.statSync(dir).isDirectory())
+    error('not a directory: ' + dir);
+
+  process.chdir(dir);
+};
+exports.cd = wrap('cd', _cd);
+
+//@
+//@ #### pwd()
+//@ Returns the current directory.
+function _pwd(options) {
+  var pwd = path.resolve(process.cwd());
+  return ShellString(pwd);
+};
+exports.pwd = wrap('pwd', _pwd);
+
+//@
+//@ #### ls([options ,] path [,path ...])
+//@ #### ls([options ,] path_array)
+//@ Available options:
+//@
+//@ + `-R`: recursive
+//@ + `-a`: all files (include files beginning with `.`)
+//@
+//@ Examples:
+//@
+//@ ```javascript
+//@ ls('projs/*.js');
+//@ ls('-R', '/users/me', '/tmp');
+//@ ls('-R', ['/users/me', '/tmp']); // same as above
+//@ ```
+//@
+//@ Returns list of files in the given path, or in current directory if no path provided.
+//@ For convenient iteration via `for (file in ls())`, the format returned is a hash object:
+//@ `{ 'file1':null, 'dir1/file2':null, ...}`.
+function _ls(options, paths) {
+  options = parseOptions(options, {
+    'R': 'recursive',
+    'a': 'all'
+  });
+
+  if (!paths)
+    paths = ['.'];
+  else if (typeof paths === 'object')
+    paths = paths; // assume array
+  else if (typeof paths === 'string')
+    paths = [].slice.call(arguments, 1);
+
+  var hash = {};
+
+  function pushHash(file, query) {
+    // hidden file?
+    if (path.basename(file)[0] === '.') {
+      // not explicitly asking for hidden files?
+      if (!options.all && !(path.basename(query)[0] === '.' && path.basename(query).length > 1))
+        return;
+    }
+
+    hash[file] = null;
+  }
+
+  paths.forEach(function(p) {
+    if (fs.existsSync(p)) {
+      // Simple file?
+      if (fs.statSync(p).isFile()) {
+        pushHash(p, p);
+        return; // continue
+      }
+      
+      // Simple dir?
+      if (fs.statSync(p).isDirectory()) {
+        // Iterate over p contents
+        fs.readdirSync(p).forEach(function(file) {
+          pushHash(file, p);
+
+          // Recursive
+          var oldDir = _pwd();
+          _cd('', p);
+          if (fs.statSync(file).isDirectory() && options.recursive)
+            hash = extend(hash, _ls('-R', file+'/*'));
+          _cd('', oldDir);
+        });
+        return; // continue
+      }
+    }
+
+    // p does not exist - possible wildcard present
+
+    var basename = path.basename(p);
+    var dirname = path.dirname(p);
+    // Wildcard present on an existing dir? (e.g. '/tmp/*.js')
+    if (basename.search(/\*/) > -1 && fs.existsSync(dirname) && fs.statSync(dirname).isDirectory) {
+      // Escape special regular expression chars
+      var regexp = basename.replace(/(\^|\$|\(|\)|\<|\>|\[|\]|\{|\}|\.|\+|\?)/g, '\\$1');
+      // Translates wildcard into regex
+      regexp = '^' + regexp.replace(/\*/g, '.*');
+      // Iterate over directory contents
+      fs.readdirSync(dirname).forEach(function(file) {
+        if (file.match(new RegExp(regexp))) {
+          pushHash(path.normalize(dirname+'/'+file), basename);
+
+          // Recursive
+          var pp = dirname + '/' + file;
+          if (fs.statSync(pp).isDirectory() && options.recursive)
+            hash = extend(hash, _ls('-R', pp+'/*'));
+        }
+      }); // forEach
+      return;
+    }
+
+    error('no such file or directory: ' + p, true);
+  });
+
+  return hash;
+};
+exports.ls = wrap('ls', _ls);
+
+
+//@
+//@ #### cp('[options ,] source [,source ...], dest')
+//@ #### cp('[options ,] source_array, dest')
+//@ Available options:
+//@
+//@ + `-f`: force
+//@ + `-r, -R`: recursive
+//@
+//@ Examples:
+//@
+//@ ```javascript
+//@ cp('file1', 'dir1');
+//@ cp('-Rf', '/tmp/*', '/usr/local/*', '/home/tmp');
+//@ cp('-Rf', ['/tmp/*', '/usr/local/*'], '/home/tmp'); // same as above
+//@ ```
+//@
+//@ Copies files. The wildcard `*` is accepted.
+function _cp(options, sources, dest) {
+  options = parseOptions(options, {
+    'f': 'force',
+    'R': 'recursive',
+    'r': 'recursive'
+  });
+
+  // Get sources, dest
+  if (arguments.length < 3) {
+    error('missing <source> and/or <dest>');
+  } else if (arguments.length > 3) {
+    sources = [].slice.call(arguments, 1, arguments.length - 1);
+    dest = arguments[arguments.length - 1];
+  } else if (typeof sources === 'string') {
+    sources = [sources];
+  } else if ('length' in sources) {
+    sources = sources; // no-op for array
+  } else {
+    error('invalid arguments');
+  }
+
+  // Dest is not existing dir, but multiple sources given
+  if ((!fs.existsSync(dest) || !fs.statSync(dest).isDirectory()) && sources.length > 1)
+    error('dest is not a directory (too many sources)');
+
+  // Dest is an existing file, but no -f given
+  if (fs.existsSync(dest) && fs.statSync(dest).isFile() && !options.force)
+    error('dest file already exists: ' + dest);
+
+  sources = expand(sources);
+
+  sources.forEach(function(src) {
+    if (!fs.existsSync(src)) {
+      error('no such file or directory: '+src, true);
+      return; // skip file
+    }
+
+    // If here, src exists
+
+    if (fs.statSync(src).isDirectory()) {
+      if (!options.recursive) {
+        // Non-Recursive
+        log(src + ' is a directory (not copied)');
+      } else {
+        // Recursive
+        // 'cp /a/source dest' should create 'source' in 'dest'
+        var newDest = dest+'/'+path.basename(src),
+            checkDir = fs.statSync(src);
+        try {
+          fs.mkdirSync(newDest, checkDir.mode);
+        } catch (e) {
+          //if the directory already exists, that's okay
+          if (e.code !== 'EEXIST') throw e;
+        }
+        cpdirSyncRecursive(src, newDest, {force: options.force});
+      }
+      return; // done with dir
+    }
+
+    // If here, src is a file
+
+    // When copying to '/path/dir':
+    //    thisDest = '/path/dir/file1'
+    var thisDest = dest;
+    if (fs.existsSync(dest) && fs.statSync(dest).isDirectory())
+      thisDest = path.normalize(dest + '/' + path.basename(src));
+
+    if (fs.existsSync(thisDest) && !options.force) {
+      error('dest file already exists: ' + thisDest, true);
+      return; // skip file
+    }
+
+    copyFileSync(src, thisDest);
+  }); // forEach(src)
+}; // cp
+exports.cp = wrap('cp', _cp);
+
+//@
+//@ #### rm([options ,] file [, file ...])
+//@ #### rm([options ,] file_array)
+//@ Available options:
+//@
+//@ + `-f`: force
+//@ + `-r, -R`: recursive
+//@
+//@ Examples:
+//@
+//@ ```javascript
+//@ rm('-rf', '/tmp/*');
+//@ rm('some_file.txt', 'another_file.txt');
+//@ rm(['some_file.txt', 'another_file.txt']); // same as above
+//@ ```
+//@
+//@ Removes files. The wildcard `*` is accepted. 
+function _rm(options, files) {
+  options = parseOptions(options, {
+    'f': 'force',
+    'r': 'recursive',
+    'R': 'recursive'
+  });
+  if (!files)
+    error('no paths given');
+
+  if (typeof files === 'string')
+    files = [].slice.call(arguments, 1);
+  // if it's array leave it as it is
+
+  files = expand(files);
+
+  files.forEach(function(file) {
+    if (!fs.existsSync(file)) {
+      // Path does not exist, no force flag given
+      if (!options.force)
+        error('no such file or directory: '+file, true);
+
+      return; // skip file
+    }
+
+    // If here, path exists
+
+    // Remove simple file
+    if (fs.statSync(file).isFile()) {
+      fs.unlinkSync(file);
+      return;
+    }
+
+    // Path is an existing directory, but no -r flag given
+    if (fs.statSync(file).isDirectory() && !options.recursive) {
+      error('path is a directory', true);
+      return; // skip path
+    }
+
+    // Recursively remove existing directory
+    if (fs.statSync(file).isDirectory() && options.recursive) {
+      rmdirSyncRecursive(file);
+    }
+  }); // forEach(file)
+}; // rm
+exports.rm = wrap('rm', _rm);
+
+//@
+//@ #### mv(source [, source ...], dest')
+//@ #### mv(source_array, dest')
+//@ Available options:
+//@
+//@ + `f`: force
+//@
+//@ Examples:
+//@
+//@ ```javascript
+//@ mv('-f', 'file', 'dir/');
+//@ mv('file1', 'file2', 'dir/');
+//@ mv(['file1', 'file2'], 'dir/'); // same as above
+//@ ```
+//@
+//@ Moves files. The wildcard `*` is accepted.
+function _mv(options, sources, dest) {
+  options = parseOptions(options, {
+    'f': 'force'
+  });
+
+  // Get sources, dest
+  if (arguments.length < 3) {
+    error('missing <source> and/or <dest>');
+  } else if (arguments.length > 3) {
+    sources = [].slice.call(arguments, 1, arguments.length - 1);
+    dest = arguments[arguments.length - 1];
+  } else if (typeof sources === 'string') {
+    sources = [sources];
+  } else if ('length' in sources) {
+    sources = sources; // no-op for array
+  } else {
+    error('invalid arguments');
+  }
+
+  sources = expand(sources);
+
+  // Dest is not existing dir, but multiple sources given
+  if ((!fs.existsSync(dest) || !fs.statSync(dest).isDirectory()) && sources.length > 1)
+    error('dest is not a directory (too many sources)');
+
+  // Dest is an existing file, but no -f given
+  if (fs.existsSync(dest) && fs.statSync(dest).isFile() && !options.force)
+    error('dest file already exists: ' + dest);
+
+  sources.forEach(function(src) {
+    if (!fs.existsSync(src)) {
+      error('no such file or directory: '+src, true);
+      return; // skip file
+    }
+
+    // If here, src exists
+
+    // When copying to '/path/dir':
+    //    thisDest = '/path/dir/file1'
+    var thisDest = dest;
+    if (fs.existsSync(dest) && fs.statSync(dest).isDirectory())
+      thisDest = path.normalize(dest + '/' + path.basename(src));
+
+    if (fs.existsSync(thisDest) && !options.force) {
+      error('dest file already exists: ' + thisDest, true);
+      return; // skip file
+    }
+
+    if (path.resolve(src) === path.dirname(path.resolve(thisDest))) {
+      error('cannot move to self: '+src, true);
+      return; // skip file
+    }
+
+    fs.renameSync(src, thisDest);
+  }); // forEach(src)
+}; // mv
+exports.mv = wrap('mv', _mv);
+
+//@
+//@ #### mkdir([options ,] dir [, dir ...])
+//@ #### mkdir([options ,] dir_array)
+//@ Available options:
+//@
+//@ + `p`: full path (will create intermediate dirs if necessary)
+//@
+//@ Examples:
+//@
+//@ ```javascript
+//@ mkdir('-p', '/tmp/a/b/c/d', '/tmp/e/f/g');
+//@ mkdir('-p', ['/tmp/a/b/c/d', '/tmp/e/f/g']); // same as above
+//@ ```
+//@
+//@ Creates directories.
+function _mkdir(options, dirs) {
+  options = parseOptions(options, {
+    'p': 'fullpath'
+  });
+  if (!dirs)
+    error('no paths given');
+
+  if (typeof dirs === 'string')
+    dirs = [].slice.call(arguments, 1);
+  // if it's array leave it as it is
+
+  dirs.forEach(function(dir) {
+    if (fs.existsSync(dir)) {
+      if (!options.fullpath)
+          error('path already exists: ' + dir, true);
+      return; // skip dir
+    }
+
+    // Base dir does not exist, and no -p option given
+    var baseDir = path.dirname(dir);
+    if (!fs.existsSync(baseDir) && !options.fullpath) {
+      error('no such file or directory: ' + baseDir, true);
+      return; // skip dir
+    }
+
+    if (options.fullpath)
+      mkdirSyncRecursive(dir);
+    else
+      fs.mkdirSync(dir, 0777);
+  });
+}; // mkdir
+exports.mkdir = wrap('mkdir', _mkdir);
+
+//@
+//@ #### cat(file [, file ...])
+//@ #### cat(file_array)
+//@
+//@ Examples:
+//@
+//@ ```javascript
+//@ var str = cat('file*.txt');
+//@ var str = cat('file1', 'file2');
+//@ var str = cat(['file1', 'file2']); // same as above
+//@ ```
+//@
+//@ Returns a string containing the given file, or a concatenated string
+//@ containing the files if more than one file is given (a new line character is
+//@ introduced between each file). Wildcard `*` accepted.
+function _cat(options, files) {
+  var cat = '';
+
+  if (!files)
+    error('no paths given');
+
+  if (typeof files === 'string')
+    files = [].slice.call(arguments, 1);
+  // if it's array leave it as it is
+
+  files = expand(files);
+
+  files.forEach(function(file) {
+    if (!fs.existsSync(file))
+      error('no such file or directory: ' + file);
+
+    cat += fs.readFileSync(file, 'utf8') + '\n';
+  });
+
+  if (cat[cat.length-1] === '\n')
+    cat = cat.substring(0, cat.length-1);
+
+  return ShellString(cat);
+};
+exports.cat = wrap('cat', _cat);
+
+//@
+//@ #### 'string'.to(file)
+//@
+//@ Examples:
+//@
+//@ ```javascript
+//@ cat('input.txt').to('output.txt');
+//@ ```
+//@
+//@ Analogous to the redirection operator `>` in Unix, but works with JavaScript strings (such as
+//@ those returned by `cat`, `grep`, etc). _Like Unix redirections, `to()` will overwrite any existing file!_
+function _to(options, file) {
+  if (!file)
+    error('wrong arguments');
+
+  if (!fs.existsSync( path.dirname(file) ))
+      error('no such file or directory: ' + path.dirname(file));
+
+  fs.writeFileSync(file, this.toString(), 'utf8');
+};
+// In the future, when Proxies are default, we can add methods like `.to()` to primitive strings. 
+// For now, this is a dummy function to bookmark places we need such strings
+function ShellString(str) {
+  return str;
+}
+String.prototype.to = wrap('to', _to);
+
+//@
+//@ #### sed([options ,] search_regex, replace_str, file)
+//@ Available options:
+//@
+//@ + `-i`: Replace contents of 'file' in-place. _Note that no backups will be created!_
+//@
+//@ Examples:
+//@
+//@ ```javascript
+//@ sed('-i', 'PROGRAM_VERSION', 'v0.1.3', 'source.js');
+//@ sed(/.*DELETE_THIS_LINE.*\n/, '', 'source.js');
+//@ ```
+//@
+//@ Reads an input string from `file` and performs a JavaScript `replace()` on the input
+//@ using the given search regex and replacement string. Returns the new string after replacement.
+function _sed(options, regex, replacement, file) {
+  options = parseOptions(options, {
+    'i': 'inplace'
+  });
+
+  if (typeof replacement === 'string')
+    replacement = replacement; // no-op
+  else if (typeof replacement === 'number')
+    replacement = replacement.toString(); // fallback
+  else
+    error('invalid replacement string');
+
+  if (!file)
+    error('no file given');
+
+  if (!fs.existsSync(file))
+    error('no such file or directory: ' + file);
+
+  var result = fs.readFileSync(file, 'utf8').replace(regex, replacement);
+  if (options.inplace)
+    fs.writeFileSync(file, result, 'utf8');
+
+  return ShellString(result);
+};
+exports.sed = wrap('sed', _sed);
+
+//@
+//@ #### grep(regex_filter, file [, file ...])
+//@ #### grep(regex_filter, file_array)
+//@
+//@ Examples:
+//@
+//@ ```javascript
+//@ grep('GLOBAL_VARIABLE', '*.js');
+//@ ```
+//@
+//@ Reads input string from given files and returns a string containing all lines of the 
+//@ file that match the given `regex_filter`. Wildcard `*` accepted.
+function _grep(options, regex, files) {
+  if (!files)
+    error('no paths given');
+
+  if (typeof files === 'string')
+    files = [].slice.call(arguments, 2);
+  // if it's array leave it as it is
+
+  files = expand(files);
+
+  var grep = '';
+  files.forEach(function(file) {
+    if (!fs.existsSync(file)) {
+      error('no such file or directory: ' + file, true);
+      return;
+    }
+
+    var contents = fs.readFileSync(file, 'utf8'),
+        lines = contents.split(/\r*\n/);
+    lines.forEach(function(line) {
+      if (line.match(regex))
+        grep += line + '\n';
+    });
+  });
+
+  return ShellString(grep);
+};
+exports.grep = wrap('grep', _grep);
+
+
+//@
+//@ #### which(command)
+//@
+//@ Examples:
+//@
+//@ ```javascript
+//@ var nodeExec = which('node');
+//@ ```
+//@
+//@ Searches for `command` in the system's PATH. On Windows looks for `.exe`, `.cmd`, and `.bat` extensions.
+//@ Returns string containing the absolute path to the command.
+function _which(options, cmd) {
+  if (!cmd)
+    error('must specify command');
+
+  var pathEnv = process.env.path || process.env.Path || process.env.PATH,
+      pathArray = splitPath(pathEnv),
+      where = null;
+
+  // No relative/absolute paths provided?
+  if (cmd.search(/\//) === -1) {
+    // Search for command in PATH
+    pathArray.forEach(function(dir) {
+      if (where)
+        return; // already found it
+
+      var attempt = path.resolve(dir + '/' + cmd);
+      if (fs.existsSync(attempt)) {
+        where = attempt;
+        return;
+      }
+
+      if (platform === 'win') {
+        var baseAttempt = attempt;
+        attempt = baseAttempt + '.exe';
+        if (fs.existsSync(attempt)) {
+          where = attempt;
+          return;
+        }
+        attempt = baseAttempt + '.cmd';
+        if (fs.existsSync(attempt)) {
+          where = attempt;
+          return;
+        }
+        attempt = baseAttempt + '.bat';
+        if (fs.existsSync(attempt)) {
+          where = attempt;
+          return;
+        }
+      } // if 'win'
+    });
+  }
+    
+  // Command not found anywhere?
+  if (!fs.existsSync(cmd) && !where)
+    return null;
+
+  where = where || path.resolve(cmd);
+
+  return ShellString(where);
+};
+exports.which = wrap('which', _which);
+
+//@
+//@ #### echo(string [,string ...])
+//@
+//@ Examples:
+//@
+//@ ```javascript
+//@ echo('hello world');
+//@ var str = echo('hello world');
+//@ ```
+//@
+//@ Prints string to stdout, and returns string with additional utility methods
+//@ like `.to()`.
+function _echo(options) {
+  var messages = [].slice.call(arguments, 1);
+  log.apply(this, messages);
+  return ShellString(messages.join(' '));
+};
+exports.echo = wrap('echo', _echo);
+
+//@
+//@ #### exit(code)
+//@ Exits the current process with the given exit code.
+exports.exit = process.exit;
+
+//@
+//@ #### env['VAR_NAME']
+//@ Object containing environment variables (both getter and setter). Shortcut to process.env.
+exports.env = process.env;
+
+//@
+//@ #### exec(command [, options] [, callback])
+//@ Available options (all `false` by default):
+//@
+//@ + `async`: Asynchronous execution. Needs callback.
+//@ + `silent`: Do not echo program output to console.
+//@
+//@ Examples:
+//@
+//@ ```javascript
+//@ var version = exec('node --version', {silent:true}).output;
+//@ ```
+//@
+//@ Executes the given `command` _synchronously_, unless otherwise specified. 
+//@ When in synchronous mode returns the object `{ code:..., output:... }`, containing the program's 
+//@ `output` (stdout + stderr)  and its exit `code`. Otherwise the `callback` gets the 
+//@ arguments `(code, output)`.
+function _exec(command, options, callback) {
+  if (!command)
+    error('must specify command');
+
+  if (typeof options === 'function') {
+    callback = options;
+    options = {};
+  }
+
+  options = extend({
+    silent: false,
+    async: false
+  }, options);
+
+  if (options.async)
+    execAsync(command, options, callback);
+  else
+    return execSync(command, options);
+};
+exports.exec = wrap('exec', _exec, {notUnix:true});
+
+
+
+
+//@
+//@ ## Non-Unix commands
+//@
+
+
+
+
+
+
+//@
+//@ #### tempdir()
+//@ Searches and returns string containing a writeable, platform-dependent temporary directory.
+//@ Follows Python's [tempfile algorithm](http://docs.python.org/library/tempfile.html#tempfile.tempdir).
+exports.tempdir = wrap('tempdir', tempDir);
+
+//@
+//@ #### exists(path [, path ...])
+//@ #### exists(path_array)
+//@ Returns true if all the given paths exist.
+function _exists(options, paths) {
+  if (!paths)
+    error('no paths given');
+
+  if (typeof paths === 'string')
+    paths = [].slice.call(arguments, 1);
+  // if it's array leave it as it is
+
+  var exists = true;
+  paths.forEach(function(p) {
+    if (!fs.existsSync(p))
+      exists = false;
+  });
+
+  return exists;
+};
+exports.exists = wrap('exists', _exists);
+
+//@
+//@ #### error()
+//@ Tests if error occurred in the last command. Returns `null` if no error occurred,
+//@ otherwise returns string explaining the error
+exports.error = function() {
+  return state.error;
+}
+
+//@
+//@ #### verbose()
+//@ Enables all output (default)
+exports.verbose = function() {
+  state.silent = false;
+}
+
+//@
+//@ #### silent()
+//@ Suppresses all output, except for explict `echo()` calls
+exports.silent = function() {
+  state.silent = true;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Auxiliary functions (internal use only)
+//
+
+function log() {
+  if (!state.silent)
+    console.log.apply(this, arguments);
+}
+
+function write(msg) {
+  if (!state.silent)
+    process.stdout.write(msg);
+}
+
+// Shows error message. Throws unless '_continue = true'.
+function error(msg, _continue) {
+  if (state.error === null)
+    state.error = '';
+  state.error += state.currentCmd + ': ' + msg + '\n';
+  
+  log(state.error);
+
+  if (!_continue)
+    throw '';
+}
+
+// Returns {'alice': true, 'bob': false} when passed:
+//   parseOptions('-a', {'a':'alice', 'b':'bob'});
+function parseOptions(str, map) {
+  if (!map)
+    error('parseOptions() internal error: no map given');
+
+  // All options are false by default
+  var options = {};
+  for (letter in map)
+    options[map[letter]] = false;
+
+  if (!str)
+    return options; // defaults
+
+  if (typeof str !== 'string')
+    error('parseOptions() internal error: wrong str');
+
+  // e.g. match[1] = 'Rf' for str = '-Rf'
+  var match = str.match(/^\-(.+)/);
+  if (!match)
+    return options;
+
+  // e.g. chars = ['R', 'f']
+  var chars = match[1].split('');
+
+  chars.forEach(function(char) {
+    if (char in map)
+      options[map[char]] = true;
+    else
+      error('option not recognized: '+char);
+  });
+
+  return options;
+}
+
+// Common wrapper for all Unix-like commands
+function wrap(cmd, fn, options) {
+  return function() {
+    var retValue = null;
+
+    state.currentCmd = cmd;
+    state.error = null;
+
+    try {
+      var args = [].slice.call(arguments, 0);
+
+      if (options && options.notUnix) {
+        retValue = fn.apply(this, args);
+      } else {
+        if (args.length === 0 || typeof args[0] !== 'string' || args[0][0] !== '-')
+          args.unshift(''); // only add dummy option if '-option' not already present
+        retValue = fn.apply(this, args);
+      }
+    } catch (e) {
+      if (!state.error) {
+        // If state.error hasn't been set it's an error thrown by Node, not us - probably a bug...
+        console.log('maker.js: internal error');
+        console.log(e.stack || e);
+        process.exit(1);
+      }
+      if (state.fatal)
+        throw e;
+    }
+
+    state.currentCmd = 'maker.js';
+    return retValue;
+  }
+} // wrap
+
+// Buffered file copy, synchronous
+// (Using readFileSync() + writeFileSync() could easily cause a memory overflow
+//  with large files)
+function copyFileSync(srcFile, destFile) {
+  if (!fs.existsSync(srcFile))
+    error('copyFileSync: no such file or directory: ' + srcFile);
+
+  var BUF_LENGTH = 64*1024,
+      buf = new Buffer(BUF_LENGTH),
+      fdr = fs.openSync(srcFile, 'r'),
+      fdw = fs.openSync(destFile, 'w'),
+      bytesRead = BUF_LENGTH,
+      pos = 0;
+
+  while (bytesRead === BUF_LENGTH) {
+    bytesRead = fs.readSync(fdr, buf, 0, BUF_LENGTH, pos);
+    fs.writeSync(fdw, buf, 0, bytesRead);
+    pos += bytesRead;
+  }
+
+  fs.closeSync(fdr);
+  fs.closeSync(fdw);
+}
+
+// Recursively copies 'sourceDir' into 'destDir'
+// Adapted from https://github.com/ryanmcgrath/wrench-js
+//
+// Copyright (c) 2010 Ryan McGrath
+// Copyright (c) 2012 Artur Adib
+//
+// Licensed under the MIT License
+// http://www.opensource.org/licenses/mit-license.php
+function cpdirSyncRecursive(sourceDir, destDir, opts) {
+  if (!opts) opts = {};
+
+  /* Create the directory where all our junk is moving to; read the mode of the source directory and mirror it */
+  var checkDir = fs.statSync(sourceDir);
+  try {
+    fs.mkdirSync(destDir, checkDir.mode);
+  } catch (e) {
+    //if the directory already exists, that's okay
+    if (e.code !== 'EEXIST') throw e;
+  }
+
+  var files = fs.readdirSync(sourceDir);
+
+  for(var i = 0; i < files.length; i++) {
+    var currFile = fs.lstatSync(sourceDir + "/" + files[i]);
+
+    if (currFile.isDirectory()) {
+      /* recursion this thing right on back. */
+      cpdirSyncRecursive(sourceDir + "/" + files[i], destDir + "/" + files[i], opts);
+    } else if (currFile.isSymbolicLink()) {
+      var symlinkFull = fs.readlinkSync(sourceDir + "/" + files[i]);
+      fs.symlinkSync(symlinkFull, destDir + "/" + files[i]);
+    } else {
+      /* At this point, we've hit a file actually worth copying... so copy it on over. */
+      if (fs.existsSync(destDir + "/" + files[i]) && !opts.force) {
+        log('skipping existing file: ' + files[i]);
+      } else {
+        copyFileSync(sourceDir + "/" + files[i], destDir + "/" + files[i]);
+      }
+    }
+
+  } // for files
+}; // cpdirSyncRecursive
+
+// Recursively removes 'dir'
+// Adapted from https://github.com/ryanmcgrath/wrench-js
+//
+// Copyright (c) 2010 Ryan McGrath
+// Copyright (c) 2012 Artur Adib
+//
+// Licensed under the MIT License
+// http://www.opensource.org/licenses/mit-license.php
+function rmdirSyncRecursive(dir) {
+  var files;
+
+  files = fs.readdirSync(dir);
+
+  // Loop through and delete everything in the sub-tree after checking it
+  for(var i = 0; i < files.length; i++) {
+    var currFile = fs.lstatSync(dir + "/" + files[i]);
+
+    if(currFile.isDirectory()) // Recursive function back to the beginning
+      rmdirSyncRecursive(dir + "/" + files[i]);
+
+    else if(currFile.isSymbolicLink()) // Unlink symlinks
+      fs.unlinkSync(dir + "/" + files[i]);
+
+    else // Assume it's a file - perhaps a try/catch belongs here?
+      fs.unlinkSync(dir + "/" + files[i]);
+  }
+
+  // Now that we know everything in the sub-tree has been deleted, we can delete the main directory. 
+  // Huzzah for the shopkeep.
+  return fs.rmdirSync(dir);
+}; // rmdirSyncRecursive
+
+// Recursively creates 'dir'
+function mkdirSyncRecursive(dir) {
+  var baseDir = path.dirname(dir);
+
+  // Base dir exists, no recursion necessary
+  if (fs.existsSync(baseDir)) {
+    fs.mkdirSync(dir, 0777);
+    return;
+  }
+
+  // Base dir does not exist, go recursive
+  mkdirSyncRecursive(baseDir);
+
+  // Base dir created, can create dir
+  fs.mkdirSync(dir, 0777);
+};
+
+// e.g. 'makerjs_a5f185d0443ca...'
+function randomFileName() {
+  function randomHash(count) {
+    if (count === 1)
+      return parseInt(16*Math.random()).toString(16);
+    else {
+      var hash = '';
+      for (var i=0; i<count; i++)
+        hash += randomHash(1);
+      return hash;
+    }
+  }
+
+  return 'makerjs_'+randomHash(20);
+}
+
+// Returns false if 'dir' is not a writeable directory, 'dir' otherwise
+function writeableDir(dir) {
+  if (!dir || !fs.existsSync(dir))
+    return false;
+
+  if (!fs.statSync(dir).isDirectory())
+    return false;
+
+  var testFile = dir+'/'+randomFileName();
+  try {
+    fs.writeFileSync(testFile, ' ');
+    fs.unlinkSync(testFile);
+    return dir;
+  } catch (e) {
+    return false;
+  }
+}
+
+// Cross-platform method for getting an available temporary directory.
+// Follows the algorithm of Python's tempfile.tempdir
+// http://docs.python.org/library/tempfile.html#tempfile.tempdir
+function tempDir() {
+  if (state.tempDir)
+    return state.tempDir; // from cache
+
+  state.tempDir = writeableDir(process.env['TMPDIR']) ||
+                  writeableDir(process.env['TEMP']) ||
+                  writeableDir(process.env['TMP']) ||
+                  writeableDir(process.env['Wimp$ScrapDir']) || // RiscOS
+                  writeableDir('C:\\TEMP') || // Windows
+                  writeableDir('C:\\TMP') || // Windows
+                  writeableDir('\\TEMP') || // Windows
+                  writeableDir('\\TMP') || // Windows
+                  writeableDir('/tmp') ||
+                  writeableDir('/var/tmp') ||
+                  writeableDir('/usr/tmp') ||
+                  writeableDir('.'); // last resort
+  
+  return state.tempDir;
+}
+
+// Wrapper around exec() to enable echoing output to console in real time
+function execAsync(cmd, opts, callback) {
+  var output = '';
+  
+  var c = child.exec(cmd, {env: process.env}, function(err) {
+    if (callback) 
+      callback(err ? err.code : 0, output);
+  });
+
+  c.stdout.on('data', function(data) {
+    output += data;
+    if (!opts.silent)
+      write(data);
+  });
+
+  c.stderr.on('data', function(data) {
+    output += data;
+    if (!opts.silent)
+      write(data);
+  });
+}
+
+// Hack to run child_process.exec() synchronously (sync avoids callback hell)
+// Uses a custom wait loop that checks for a flag file, created when the child process is done.
+// (Can't do a wait loop that checks for internal Node variables/messages as
+// Node is single-threaded; callbacks and other internal state changes are done in the 
+// event loop).
+function execSync(cmd, opts) {
+  var stdoutFile = path.resolve(tempDir()+'/'+randomFileName()),
+      codeFile = path.resolve(tempDir()+'/'+randomFileName()),
+      scriptFile = path.resolve(tempDir()+'/'+randomFileName());
+
+  var options = extend({
+    silent: false
+  }, opts);
+
+  var previousStdoutContent = '';
+  // Echoes stdout changes from running process, if not silent
+  function updateStdout() {
+    if (state.silent || options.silent || !fs.existsSync(stdoutFile))
+      return;
+
+    var stdoutContent = fs.readFileSync(stdoutFile, 'utf8');
+    // No changes since last time?
+    if (stdoutContent.length <= previousStdoutContent.length)
+      return;
+
+    process.stdout.write(stdoutContent.substr(previousStdoutContent.length));
+    previousStdoutContent = stdoutContent;
+  }
+
+  function escape(str) {
+    str = str.replace(/\'/g, '"');
+    str = str.replace(/\\/g, '\\\\');
+    return str;
+  }
+    
+  cmd += ' > '+stdoutFile+' 2>&1'; // works on both win/unix
+
+  var script = 
+   "var child = require('child_process'), \
+        fs = require('fs'); \
+    child.exec('"+escape(cmd)+"', {env: process.env}, function(err) { \
+      fs.writeFileSync('"+escape(codeFile)+"', err ? err.code.toString() : '0'); \
+    });";
+
+  if (fs.existsSync(scriptFile)) fs.unlinkSync(scriptFile);
+  if (fs.existsSync(stdoutFile)) fs.unlinkSync(stdoutFile);
+  if (fs.existsSync(codeFile)) fs.unlinkSync(codeFile);
+
+  fs.writeFileSync(scriptFile, script);
+  child.exec('node '+scriptFile, { 
+    env: process.env,
+    cwd: exports.pwd()
+  });
+
+  // The wait loop
+  while (!fs.existsSync(codeFile)) { updateStdout(); };
+  while (!fs.existsSync(stdoutFile)) { updateStdout(); };
+
+  // At this point codeFile exists, but it's not necessarily flushed yet.
+  // Keep reading it until it is.
+  var code = parseInt('');
+  while (isNaN(code))
+    code = parseInt(fs.readFileSync(codeFile, 'utf8'));
+
+  var stdout = fs.readFileSync(stdoutFile, 'utf8');
+
+  fs.unlinkSync(scriptFile);
+  fs.unlinkSync(stdoutFile);
+  fs.unlinkSync(codeFile);
+
+  // True if successful, false if not
+  var obj = {
+    code: code,
+    output: stdout
+  };
+  return obj;
+} // execSync()
+
+// Expands wildcards with matching file names. For a given array of file names 'list', returns 
+// another array containing all file names as per ls(list[i]). 
+// For example: expand(['file*.js']) = ['file1.js', 'file2.js', ...]
+// (if the files 'file1.js', 'file2.js', etc, exist in the current dir)
+function expand(list) {
+  var expanded = [];
+  list.forEach(function(listEl) {
+    // Wildcard present? 
+    if (listEl.search(/\*/) > -1) {
+      for (file in _ls('', listEl))
+        expanded.push(file);
+    } else {
+      expanded.push(listEl);
+    }
+  });  
+  return expanded;
+}
+
+// Cross-platform method for splitting environment PATH variables
+function splitPath(p) {
+  if (!p)
+    return [];
+
+  if (platform === 'win')
+    return p.split(';');
+  else
+    return p.split(':');
+}
+
+// extend(target_obj, source_obj1 [, source_obj2 ...])
+// Shallow extend, e.g.:
+//    aux.extend({a:1}, {b:2}, {c:3}) 
+//    returns {a:1, b:2, c:3}
+function extend(target) {
+  var sources = [].slice.call(arguments, 1);
+  sources.forEach(function(source) {
+    for (key in source) 
+      target[key] = source[key];
+  });
+  
+  return target;
+}
diff --git a/make.js b/make.js
new file mode 100755
index 000000000..873e14d74
--- /dev/null
+++ b/make.js
@@ -0,0 +1,401 @@
+#!/usr/bin/env node
+require('./external/shelljs/make');
+
+var ROOT_DIR = __dirname+'/', // absolute path to project's root
+    BUILD_DIR = 'build/',
+    BUILD_TARGET = BUILD_DIR+'pdf.js',
+    FIREFOX_BUILD_DIR = BUILD_DIR+'/firefox/',
+    EXTENSION_SRC_DIR = 'extensions/',
+    GH_PAGES_DIR = BUILD_DIR+'gh-pages/',
+    REPO = 'git@github.com:mozilla/pdf.js.git',
+    PYTHON_BIN = 'python2.7';
+
+//
+// make all
+//
+target.all = function() {  
+  // Don't do anything by default
+  echo('Please specify a target. Available targets:');
+  for (t in target)
+    if (t !== 'all') echo('  ' + t);
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////
+//
+// Production stuff
+//
+
+//
+// make web
+// Generates the website for the project, by checking out the gh-pages branch underneath 
+// the build directory, and then moving the various viewer files into place.
+//
+target.web = function() {
+  target.production();
+  target.extension();
+  target.pagesrepo();
+  
+  cd(ROOT_DIR);
+  echo();
+  echo('### Creating web site');
+
+  cp(BUILD_TARGET, GH_PAGES_DIR+BUILD_TARGET);
+  cp('-R', 'web/*', GH_PAGES_DIR+'/web');
+  cp(FIREFOX_BUILD_DIR+'/*.xpi', FIREFOX_BUILD_DIR+'/*.rdf', GH_PAGES_DIR+EXTENSION_SRC_DIR+'firefox/');
+  cp(GH_PAGES_DIR+'/web/index.html.template', GH_PAGES_DIR+'/index.html');
+  mv('-f', GH_PAGES_DIR+'/web/viewer-production.html', GH_PAGES_DIR+'/web/viewer.html');
+  cd(GH_PAGES_DIR);
+  exec('git add -A');
+  
+  echo();
+  echo("Website built in "+GH_PAGES_DIR);
+  echo("Don't forget to cd into "+GH_PAGES_DIR+" and issue 'git commit' to push changes.");
+}
+
+//
+// make production
+// Creates production output (pdf.js, and corresponding changes to web/ files)
+//
+target.production = function() {
+  target.bundle();
+  target.viewer();
+}
+
+//
+// make bundle
+// Bundles all source files into one wrapper 'pdf.js' file, in the given order.
+//
+
+target.bundle = function() {
+  cd(ROOT_DIR);
+  echo();
+  echo('### Bundling files into '+BUILD_TARGET);
+
+  // File order matters
+  var SRC_FILES = 
+       ['core.js',
+        'util.js',
+        'canvas.js',
+        'obj.js',
+        'function.js',
+        'charsets.js',
+        'cidmaps.js',
+        'colorspace.js',
+        'crypto.js',
+        'evaluator.js',
+        'fonts.js',
+        'glyphlist.js',
+        'image.js',
+        'metrics.js',
+        'parser.js',
+        'pattern.js',
+        'stream.js',
+        'worker.js',
+        '../external/jpgjs/jpg.js',
+        'jpx.js',
+        'bidi.js'];
+
+  if (!exists(BUILD_DIR))
+    mkdir(BUILD_DIR);
+
+  cd('src');
+  var bundle = cat(SRC_FILES),
+      bundleVersion = exec('git log --format="%h" -n 1', {silent:true}).output.replace('\n', '');
+
+  sed(/.*PDFJSSCRIPT_INCLUDE_ALL.*\n/, bundle, 'pdf.js').to(ROOT_DIR+BUILD_TARGET);
+  sed('-i', 'PDFJSSCRIPT_BUNDLE_VER', bundleVersion, ROOT_DIR+BUILD_TARGET);
+}
+
+//
+// make viewer
+// Changes development <script> tags in our web viewer to use only 'pdf.js'.
+// Produces 'viewer-production.html'
+//
+target.viewer = function() {
+  cd(ROOT_DIR);
+  echo();
+  echo('### Generating production-level viewer');
+
+  cd('web');
+  // Remove development lines
+  sed(/.*PDFJSSCRIPT_REMOVE_CORE.*\n/g, '', 'viewer.html').to('viewer-production.html');
+  // Introduce snippet
+  sed('-i', /.*PDFJSSCRIPT_INCLUDE_BUILD.*\n/g, cat('viewer-snippet.html'), 'viewer-production.html');
+}
+
+//
+// make pagesrepo
+//
+// This target clones the gh-pages repo into the build directory. It deletes the current contents 
+// of the repo, since we overwrite everything with data from the master repo. The 'make web' target
+// then uses 'git add -A' to track additions, modifications, moves, and deletions.
+target.pagesrepo = function() {
+  cd(ROOT_DIR);
+  echo();
+  echo('### Creating fresh clone of gh-pages');
+
+  if (!exists(BUILD_DIR))
+    mkdir(BUILD_DIR);
+
+  if (!exists(GH_PAGES_DIR)) {
+    echo();
+    echo('Cloning project repo...');
+    echo('(This operation can take a while, depending on network conditions)');
+    exec('git clone -b gh-pages --depth=1 '+REPO+' '+GH_PAGES_DIR, {silent:true});
+    echo('Done.');
+  }
+
+  rm('-rf', GH_PAGES_DIR+'/*');
+  mkdir('-p', GH_PAGES_DIR+'/web');
+  mkdir('-p', GH_PAGES_DIR+'/web/images');
+  mkdir('-p', GH_PAGES_DIR+BUILD_DIR);
+  mkdir('-p', GH_PAGES_DIR+EXTENSION_SRC_DIR+'/firefox');
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////
+//
+// Extension stuff
+//
+
+var EXTENSION_WEB_FILES =
+      ['web/images',
+       'web/viewer.css',
+       'web/viewer.js',
+       'web/viewer.html',
+       'web/viewer-production.html'],
+    EXTENSION_BASE_VERSION = '4bb289ec499013de66eb421737a4dbb4a9273eda',
+    EXTENSION_BUILD_NUMBER;
+
+//
+// make extension
+//
+target.extension = function() {
+  cd(ROOT_DIR);
+  echo();
+  echo('### Building extensions');
+
+  target.production();
+  target.firefox();
+  target.chrome();
+}
+
+target.buildnumber = function() {
+  cd(ROOT_DIR);
+  echo();
+  echo('### Getting extension build number');
+
+  // Build number is the number of commits since base version
+  EXTENSION_BUILD_NUMBER = exec('git log --format=oneline '+EXTENSION_BASE_VERSION+'..', {silent:true})
+    .output.match(/\n/g).length; // get # of lines in git output
+  
+  echo('Extension build number: ' + EXTENSION_BUILD_NUMBER);  
+}
+
+//
+// make firefox
+//
+target.firefox = function() {
+  cd(ROOT_DIR);
+  echo();
+  echo('### Building Firefox extension');
+
+  var FIREFOX_BUILD_CONTENT_DIR = FIREFOX_BUILD_DIR+'/content/',
+      FIREFOX_CONTENT_DIR = EXTENSION_SRC_DIR+'/firefox/content/',
+      FIREFOX_EXTENSION_FILES_TO_COPY =
+        ['*.js',
+         '*.rdf',
+         'components'];
+      FIREFOX_EXTENSION_FILES =
+        ['content',
+         '*.js',
+         'install.rdf',
+         'components',
+         'content'];
+      FIREFOX_EXTENSION_NAME = 'pdf.js.xpi',
+      FIREFOX_AMO_EXTENSION_NAME = 'pdf.js.amo.xpi';
+
+  target.production();
+  target.buildnumber();
+  cd(ROOT_DIR);
+
+  // Clear out everything in the firefox extension build directory
+  rm('-rf', FIREFOX_BUILD_DIR);
+  mkdir('-p', FIREFOX_BUILD_CONTENT_DIR);
+  mkdir('-p', FIREFOX_BUILD_CONTENT_DIR+BUILD_DIR);
+  mkdir('-p', FIREFOX_BUILD_CONTENT_DIR+'/web');
+  
+  // Copy extension files  
+  cd('extensions/firefox');
+  cp('-R', FIREFOX_EXTENSION_FILES_TO_COPY, ROOT_DIR+FIREFOX_BUILD_DIR);
+  cd(ROOT_DIR);
+
+  // Copy a standalone version of pdf.js inside the content directory
+  cp(BUILD_TARGET, FIREFOX_BUILD_CONTENT_DIR+BUILD_DIR);
+  cp('-R', EXTENSION_WEB_FILES, FIREFOX_BUILD_CONTENT_DIR+'/web');
+  rm(FIREFOX_BUILD_CONTENT_DIR+'/web/viewer-production.html');
+
+  // Copy over the firefox extension snippet so we can inline pdf.js in it
+  cp('web/viewer-snippet-firefox-extension.html', FIREFOX_BUILD_CONTENT_DIR+'/web');
+
+  // Modify the viewer so it does all the extension-only stuff.
+  cd(FIREFOX_BUILD_CONTENT_DIR+'/web');
+  sed('-i', /.*PDFJSSCRIPT_INCLUDE_BUNDLE.*\n/, cat(ROOT_DIR+BUILD_TARGET), 'viewer-snippet-firefox-extension.html');
+  sed('-i', /.*PDFJSSCRIPT_REMOVE_CORE.*\n/g, '', 'viewer.html');
+  sed('-i', /.*PDFJSSCRIPT_REMOVE_FIREFOX_EXTENSION.*\n/g, '', 'viewer.html');
+  sed('-i', /.*PDFJSSCRIPT_INCLUDE_FIREFOX_EXTENSION.*\n/, cat('viewer-snippet-firefox-extension.html'), 'viewer.html');
+  cd(ROOT_DIR);
+
+  // We don't need pdf.js anymore since its inlined
+  rm('-Rf', FIREFOX_BUILD_CONTENT_DIR+BUILD_DIR);
+
+  // Update the build version number
+  sed('-i', /PDFJSSCRIPT_BUILD/, EXTENSION_BUILD_NUMBER, FIREFOX_BUILD_DIR+'/install.rdf');
+  sed('-i', /PDFJSSCRIPT_BUILD/, EXTENSION_BUILD_NUMBER, FIREFOX_BUILD_DIR+'/update.rdf');
+
+  // Create the xpi
+  cd(FIREFOX_BUILD_DIR);
+  exec('zip -r '+FIREFOX_EXTENSION_NAME+' '+FIREFOX_EXTENSION_FILES.join(' '));
+  echo('extension created: ' + FIREFOX_EXTENSION_NAME);
+  cd(ROOT_DIR);
+
+  // Build the amo extension too (remove the updateUrl)
+  cd(FIREFOX_BUILD_DIR);
+  sed('-i', /.*updateURL.*\n/, '', 'install.rdf');
+  exec('zip -r '+FIREFOX_AMO_EXTENSION_NAME+' '+FIREFOX_EXTENSION_FILES.join(' '));
+  echo('AMO extension created: ' + FIREFOX_AMO_EXTENSION_NAME);
+  cd(ROOT_DIR);
+}
+
+//
+// make chrome
+//
+target.chrome = function() {
+  cd(ROOT_DIR);
+  echo();
+  echo('### Building Chrome extension');
+
+  var CHROME_BUILD_DIR = BUILD_DIR+'/chrome/',
+      CHROME_CONTENT_DIR = EXTENSION_SRC_DIR+'/chrome/content/',
+      CHROME_BUILD_CONTENT_DIR = CHROME_BUILD_DIR+'/content/',
+      CHROME_EXTENSION_FILES =
+        ['extensions/chrome/*.json',
+         'extensions/chrome/*.html'];
+
+  target.production();
+  target.buildnumber();
+  cd(ROOT_DIR);
+
+  // Clear out everything in the chrome extension build directory
+  rm('-Rf', CHROME_BUILD_DIR);
+  mkdir('-p', CHROME_BUILD_CONTENT_DIR);
+  mkdir('-p', CHROME_BUILD_CONTENT_DIR+BUILD_DIR);
+  mkdir('-p', CHROME_BUILD_CONTENT_DIR+'/web');
+
+  // Copy extension files  
+  cp('-R', CHROME_EXTENSION_FILES, CHROME_BUILD_DIR);
+
+  // Copy a standalone version of pdf.js inside the content directory
+  cp(BUILD_TARGET, CHROME_BUILD_CONTENT_DIR+BUILD_DIR);
+  cp('-R', EXTENSION_WEB_FILES, CHROME_BUILD_CONTENT_DIR+'/web');
+  mv('-f', CHROME_BUILD_CONTENT_DIR+'/web/viewer-production.html', CHROME_BUILD_CONTENT_DIR+'/web/viewer.html');
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////
+//
+// Test stuff
+//
+
+//
+// make test
+//
+target.test = function() {
+  target.browsertest();
+  target.unittest();
+}
+
+//
+// make browsertest
+//
+target.browsertest = function() {
+  cd(ROOT_DIR);
+  echo();
+  echo('### Running browser tests');
+
+  var PDF_TEST = env['PDF_TEST'] || 'test_manifest.json',
+      PDF_BROWSERS = env['PDF_BROWSERS'] || 'resources/browser_manifests/browser_manifest.json';
+
+  if (!exists('test/'+PDF_BROWSERS)) {
+    echo('Browser manifest file test/'+PDF_BROWSERS+' does not exist.');
+    echo('Try copying one of the examples in test/resources/browser_manifests/');
+    exit(1);
+  }
+
+  cd('test');
+  exec(PYTHON_BIN+' test.py --reftest --browserManifestFile='+PDF_BROWSERS+' --manifestFile='+PDF_TEST, {async:true});
+}
+
+//
+// make unittest
+//
+target.unittest = function() {
+  cd(ROOT_DIR);
+  echo();
+  echo('### Running unit tests');
+
+  cd('test/unit');
+  exec('make', {async:true});
+}
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////
+//
+// Other
+//
+
+//
+// make server
+//
+target.server = function() {
+  cd(ROOT_DIR);
+  echo();
+  echo('### Starting local server');
+
+  cd('test');
+  exec(PYTHON_BIN+' -u test.py --port=8888', {async:true});
+}
+
+//
+// make lint
+//
+target.lint = function() {
+  cd(ROOT_DIR);
+  echo();
+  echo('### Linting JS files (this can take a while!)');
+
+  var LINT_FILES = 'src/*.js \
+                    web/*.js \
+                    test/*.js \
+                    test/unit/*.js \
+                    extensions/firefox/*.js \
+                    extensions/firefox/components/*.js \
+                    extensions/chrome/*.js';
+
+  exec('gjslint --nojsdoc '+LINT_FILES);
+}
+
+//
+// make clean
+//
+target.clean = function() {
+  cd(ROOT_DIR);
+  echo();
+  echo('### Cleaning up project builds');
+
+  rm('-rf', BUILD_DIR);
+}

From 30888e94bd10423de3112d8569aeec6ac3ff3cf3 Mon Sep 17 00:00:00 2001
From: notmasteryet <async.processingjs@yahoo.com>
Date: Sun, 4 Mar 2012 20:26:57 -0600
Subject: [PATCH 14/15] Exclude make.js from the linting; fixes few lint
 make.js errors

---
 Makefile |   4 +-
 make.js  | 176 +++++++++++++++++++++++++++++--------------------------
 2 files changed, 94 insertions(+), 86 deletions(-)

diff --git a/Makefile b/Makefile
index b11b015b6..d32c1a252 100644
--- a/Makefile
+++ b/Makefile
@@ -144,9 +144,9 @@ browser-test:
 # To install gjslint, see:
 #
 # <http://code.google.com/closure/utilities/docs/linter_howto.html>
-SRC_DIRS := . src utils web test examples/helloworld extensions/firefox \
+SRC_DIRS := src utils web test examples/helloworld extensions/firefox \
             extensions/firefox/components extensions/chrome test/unit
-GJSLINT_FILES = $(foreach DIR,$(SRC_DIRS),$(wildcard $(DIR)/*.js))
+GJSLINT_FILES = $(foreach DIR, $(SRC_DIRS), $(wildcard $(DIR)/*.js))
 lint:
 	gjslint --nojsdoc $(GJSLINT_FILES)
 
diff --git a/make.js b/make.js
index 873e14d74..7c514a34a 100755
--- a/make.js
+++ b/make.js
@@ -1,25 +1,24 @@
 #!/usr/bin/env node
 require('./external/shelljs/make');
 
-var ROOT_DIR = __dirname+'/', // absolute path to project's root
+var ROOT_DIR = __dirname + '/', // absolute path to project's root
     BUILD_DIR = 'build/',
-    BUILD_TARGET = BUILD_DIR+'pdf.js',
-    FIREFOX_BUILD_DIR = BUILD_DIR+'/firefox/',
+    BUILD_TARGET = BUILD_DIR + 'pdf.js',
+    FIREFOX_BUILD_DIR = BUILD_DIR + '/firefox/',
     EXTENSION_SRC_DIR = 'extensions/',
-    GH_PAGES_DIR = BUILD_DIR+'gh-pages/',
+    GH_PAGES_DIR = BUILD_DIR + 'gh-pages/',
     REPO = 'git@github.com:mozilla/pdf.js.git',
     PYTHON_BIN = 'python2.7';
 
 //
 // make all
 //
-target.all = function() {  
+target.all = function() {
   // Don't do anything by default
   echo('Please specify a target. Available targets:');
   for (t in target)
     if (t !== 'all') echo('  ' + t);
-}
-
+};
 
 
 ///////////////////////////////////////////////////////////////////////////////////////////
@@ -29,30 +28,33 @@ target.all = function() {
 
 //
 // make web
-// Generates the website for the project, by checking out the gh-pages branch underneath 
+// Generates the website for the project, by checking out the gh-pages branch underneath
 // the build directory, and then moving the various viewer files into place.
 //
 target.web = function() {
   target.production();
   target.extension();
   target.pagesrepo();
-  
+
   cd(ROOT_DIR);
   echo();
   echo('### Creating web site');
 
-  cp(BUILD_TARGET, GH_PAGES_DIR+BUILD_TARGET);
-  cp('-R', 'web/*', GH_PAGES_DIR+'/web');
-  cp(FIREFOX_BUILD_DIR+'/*.xpi', FIREFOX_BUILD_DIR+'/*.rdf', GH_PAGES_DIR+EXTENSION_SRC_DIR+'firefox/');
-  cp(GH_PAGES_DIR+'/web/index.html.template', GH_PAGES_DIR+'/index.html');
-  mv('-f', GH_PAGES_DIR+'/web/viewer-production.html', GH_PAGES_DIR+'/web/viewer.html');
+  cp(BUILD_TARGET, GH_PAGES_DIR + BUILD_TARGET);
+  cp('-R', 'web/*', GH_PAGES_DIR + '/web');
+  cp(FIREFOX_BUILD_DIR + '/*.xpi', FIREFOX_BUILD_DIR + '/*.rdf',
+    GH_PAGES_DIR + EXTENSION_SRC_DIR + 'firefox/');
+  cp(GH_PAGES_DIR + '/web/index.html.template', GH_PAGES_DIR + '/index.html');
+  mv('-f', GH_PAGES_DIR + '/web/viewer-production.html',
+    GH_PAGES_DIR + '/web/viewer.html');
   cd(GH_PAGES_DIR);
   exec('git add -A');
-  
+
   echo();
-  echo("Website built in "+GH_PAGES_DIR);
-  echo("Don't forget to cd into "+GH_PAGES_DIR+" and issue 'git commit' to push changes.");
-}
+  echo("Website built in " + GH_PAGES_DIR);
+  echo("Don't forget to cd into " + GH_PAGES_DIR +
+    " and issue 'git commit' to push changes.");
+};
 
 //
 // make production
@@ -61,7 +63,7 @@ target.web = function() {
 target.production = function() {
   target.bundle();
   target.viewer();
-}
+};
 
 //
 // make bundle
@@ -71,10 +73,10 @@ target.production = function() {
 target.bundle = function() {
   cd(ROOT_DIR);
   echo();
-  echo('### Bundling files into '+BUILD_TARGET);
+  echo('### Bundling files into ' + BUILD_TARGET);
 
   // File order matters
-  var SRC_FILES = 
+  var SRC_FILES =
        ['core.js',
         'util.js',
         'canvas.js',
@@ -102,11 +104,13 @@ target.bundle = function() {
 
   cd('src');
   var bundle = cat(SRC_FILES),
-      bundleVersion = exec('git log --format="%h" -n 1', {silent:true}).output.replace('\n', '');
+      bundleVersion = exec('git log --format="%h" -n 1',
+        {silent: true}).output.replace('\n', '');
 
-  sed(/.*PDFJSSCRIPT_INCLUDE_ALL.*\n/, bundle, 'pdf.js').to(ROOT_DIR+BUILD_TARGET);
-  sed('-i', 'PDFJSSCRIPT_BUNDLE_VER', bundleVersion, ROOT_DIR+BUILD_TARGET);
-}
+  sed(/.*PDFJSSCRIPT_INCLUDE_ALL.*\n/, bundle, 'pdf.js')
+    .to(ROOT_DIR + BUILD_TARGET);
+  sed('-i', 'PDFJSSCRIPT_BUNDLE_VER', bundleVersion, ROOT_DIR + BUILD_TARGET);
+};
 
 //
 // make viewer
@@ -120,15 +124,17 @@ target.viewer = function() {
 
   cd('web');
   // Remove development lines
-  sed(/.*PDFJSSCRIPT_REMOVE_CORE.*\n/g, '', 'viewer.html').to('viewer-production.html');
+  sed(/.*PDFJSSCRIPT_REMOVE_CORE.*\n/g, '', 'viewer.html')
+    .to('viewer-production.html');
   // Introduce snippet
-  sed('-i', /.*PDFJSSCRIPT_INCLUDE_BUILD.*\n/g, cat('viewer-snippet.html'), 'viewer-production.html');
-}
+  sed('-i', /.*PDFJSSCRIPT_INCLUDE_BUILD.*\n/g, cat('viewer-snippet.html'),
+    'viewer-production.html');
+};
 
 //
 // make pagesrepo
 //
-// This target clones the gh-pages repo into the build directory. It deletes the current contents 
+// This target clones the gh-pages repo into the build directory. It deletes the current contents
 // of the repo, since we overwrite everything with data from the master repo. The 'make web' target
 // then uses 'git add -A' to track additions, modifications, moves, and deletions.
 target.pagesrepo = function() {
@@ -143,16 +149,17 @@ target.pagesrepo = function() {
     echo();
     echo('Cloning project repo...');
     echo('(This operation can take a while, depending on network conditions)');
-    exec('git clone -b gh-pages --depth=1 '+REPO+' '+GH_PAGES_DIR, {silent:true});
+    exec('git clone -b gh-pages --depth=1 ' + REPO + ' ' + ßGH_PAGES_DIR,
+      {silent: true});
     echo('Done.');
   }
 
-  rm('-rf', GH_PAGES_DIR+'/*');
-  mkdir('-p', GH_PAGES_DIR+'/web');
-  mkdir('-p', GH_PAGES_DIR+'/web/images');
-  mkdir('-p', GH_PAGES_DIR+BUILD_DIR);
-  mkdir('-p', GH_PAGES_DIR+EXTENSION_SRC_DIR+'/firefox');
-}
+  rm('-rf', GH_PAGES_DIR + '/*');
+  mkdir('-p', GH_PAGES_DIR + '/web');
+  mkdir('-p', GH_PAGES_DIR + '/web/images');
+  mkdir('-p', GH_PAGES_DIR + BUILD_DIR);
+  mkdir('-p', GH_PAGES_DIR + EXTENSION_SRC_DIR + '/firefox');
+};
 
 
 ///////////////////////////////////////////////////////////////////////////////////////////
@@ -180,7 +187,7 @@ target.extension = function() {
   target.production();
   target.firefox();
   target.chrome();
-}
+};
 
 target.buildnumber = function() {
   cd(ROOT_DIR);
@@ -188,11 +195,12 @@ target.buildnumber = function() {
   echo('### Getting extension build number');
 
   // Build number is the number of commits since base version
-  EXTENSION_BUILD_NUMBER = exec('git log --format=oneline '+EXTENSION_BASE_VERSION+'..', {silent:true})
+  EXTENSION_BUILD_NUMBER = exec('git log --format=oneline ' +
+    EXTENSION_BASE_VERSION + '..', {silent: true})
     .output.match(/\n/g).length; // get # of lines in git output
-  
-  echo('Extension build number: ' + EXTENSION_BUILD_NUMBER);  
-}
+
+  echo('Extension build number: ' + EXTENSION_BUILD_NUMBER);
+};
 
 //
 // make firefox
@@ -202,8 +210,8 @@ target.firefox = function() {
   echo();
   echo('### Building Firefox extension');
 
-  var FIREFOX_BUILD_CONTENT_DIR = FIREFOX_BUILD_DIR+'/content/',
-      FIREFOX_CONTENT_DIR = EXTENSION_SRC_DIR+'/firefox/content/',
+  var FIREFOX_BUILD_CONTENT_DIR = FIREFOX_BUILD_DIR + '/content/',
+      FIREFOX_CONTENT_DIR = EXTENSION_SRC_DIR + '/firefox/content/',
       FIREFOX_EXTENSION_FILES_TO_COPY =
         ['*.js',
          '*.rdf',
@@ -224,50 +232,50 @@ target.firefox = function() {
   // Clear out everything in the firefox extension build directory
   rm('-rf', FIREFOX_BUILD_DIR);
   mkdir('-p', FIREFOX_BUILD_CONTENT_DIR);
-  mkdir('-p', FIREFOX_BUILD_CONTENT_DIR+BUILD_DIR);
-  mkdir('-p', FIREFOX_BUILD_CONTENT_DIR+'/web');
-  
-  // Copy extension files  
+  mkdir('-p', FIREFOX_BUILD_CONTENT_DIR + BUILD_DIR);
+  mkdir('-p', FIREFOX_BUILD_CONTENT_DIR + '/web');
+
+  // Copy extension files
   cd('extensions/firefox');
-  cp('-R', FIREFOX_EXTENSION_FILES_TO_COPY, ROOT_DIR+FIREFOX_BUILD_DIR);
+  cp('-R', FIREFOX_EXTENSION_FILES_TO_COPY, ROOT_DIR + FIREFOX_BUILD_DIR);
   cd(ROOT_DIR);
 
   // Copy a standalone version of pdf.js inside the content directory
-  cp(BUILD_TARGET, FIREFOX_BUILD_CONTENT_DIR+BUILD_DIR);
-  cp('-R', EXTENSION_WEB_FILES, FIREFOX_BUILD_CONTENT_DIR+'/web');
-  rm(FIREFOX_BUILD_CONTENT_DIR+'/web/viewer-production.html');
+  cp(BUILD_TARGET, FIREFOX_BUILD_CONTENT_DIR + BUILD_DIR);
+  cp('-R', EXTENSION_WEB_FILES, FIREFOX_BUILD_CONTENT_DIR + '/web');
+  rm(FIREFOX_BUILD_CONTENT_DIR + '/web/viewer-production.html');
 
   // Copy over the firefox extension snippet so we can inline pdf.js in it
-  cp('web/viewer-snippet-firefox-extension.html', FIREFOX_BUILD_CONTENT_DIR+'/web');
+  cp('web/viewer-snippet-firefox-extension.html', FIREFOX_BUILD_CONTENT_DIR + '/web');
 
   // Modify the viewer so it does all the extension-only stuff.
-  cd(FIREFOX_BUILD_CONTENT_DIR+'/web');
-  sed('-i', /.*PDFJSSCRIPT_INCLUDE_BUNDLE.*\n/, cat(ROOT_DIR+BUILD_TARGET), 'viewer-snippet-firefox-extension.html');
+  cd(FIREFOX_BUILD_CONTENT_DIR + '/web');
+  sed('-i', /.*PDFJSSCRIPT_INCLUDE_BUNDLE.*\n/, cat(ROOT_DIR + BUILD_TARGET), 'viewer-snippet-firefox-extension.html');
   sed('-i', /.*PDFJSSCRIPT_REMOVE_CORE.*\n/g, '', 'viewer.html');
   sed('-i', /.*PDFJSSCRIPT_REMOVE_FIREFOX_EXTENSION.*\n/g, '', 'viewer.html');
   sed('-i', /.*PDFJSSCRIPT_INCLUDE_FIREFOX_EXTENSION.*\n/, cat('viewer-snippet-firefox-extension.html'), 'viewer.html');
   cd(ROOT_DIR);
 
   // We don't need pdf.js anymore since its inlined
-  rm('-Rf', FIREFOX_BUILD_CONTENT_DIR+BUILD_DIR);
+  rm('-Rf', FIREFOX_BUILD_CONTENT_DIR + BUILD_DIR);
 
   // Update the build version number
-  sed('-i', /PDFJSSCRIPT_BUILD/, EXTENSION_BUILD_NUMBER, FIREFOX_BUILD_DIR+'/install.rdf');
-  sed('-i', /PDFJSSCRIPT_BUILD/, EXTENSION_BUILD_NUMBER, FIREFOX_BUILD_DIR+'/update.rdf');
+  sed('-i', /PDFJSSCRIPT_BUILD/, EXTENSION_BUILD_NUMBER, FIREFOX_BUILD_DIR + '/install.rdf');
+  sed('-i', /PDFJSSCRIPT_BUILD/, EXTENSION_BUILD_NUMBER, FIREFOX_BUILD_DIR + '/update.rdf');
 
   // Create the xpi
   cd(FIREFOX_BUILD_DIR);
-  exec('zip -r '+FIREFOX_EXTENSION_NAME+' '+FIREFOX_EXTENSION_FILES.join(' '));
+  exec('zip -r ' + FIREFOX_EXTENSION_NAME + ' ' + FIREFOX_EXTENSION_FILES.join(' '));
   echo('extension created: ' + FIREFOX_EXTENSION_NAME);
   cd(ROOT_DIR);
 
   // Build the amo extension too (remove the updateUrl)
   cd(FIREFOX_BUILD_DIR);
   sed('-i', /.*updateURL.*\n/, '', 'install.rdf');
-  exec('zip -r '+FIREFOX_AMO_EXTENSION_NAME+' '+FIREFOX_EXTENSION_FILES.join(' '));
+  exec('zip -r ' + FIREFOX_AMO_EXTENSION_NAME + ' ' + FIREFOX_EXTENSION_FILES.join(' '));
   echo('AMO extension created: ' + FIREFOX_AMO_EXTENSION_NAME);
   cd(ROOT_DIR);
-}
+};
 
 //
 // make chrome
@@ -277,9 +285,9 @@ target.chrome = function() {
   echo();
   echo('### Building Chrome extension');
 
-  var CHROME_BUILD_DIR = BUILD_DIR+'/chrome/',
-      CHROME_CONTENT_DIR = EXTENSION_SRC_DIR+'/chrome/content/',
-      CHROME_BUILD_CONTENT_DIR = CHROME_BUILD_DIR+'/content/',
+  var CHROME_BUILD_DIR = BUILD_DIR + '/chrome/',
+      CHROME_CONTENT_DIR = EXTENSION_SRC_DIR + '/chrome/content/',
+      CHROME_BUILD_CONTENT_DIR = CHROME_BUILD_DIR + '/content/',
       CHROME_EXTENSION_FILES =
         ['extensions/chrome/*.json',
          'extensions/chrome/*.html'];
@@ -291,17 +299,18 @@ target.chrome = function() {
   // Clear out everything in the chrome extension build directory
   rm('-Rf', CHROME_BUILD_DIR);
   mkdir('-p', CHROME_BUILD_CONTENT_DIR);
-  mkdir('-p', CHROME_BUILD_CONTENT_DIR+BUILD_DIR);
-  mkdir('-p', CHROME_BUILD_CONTENT_DIR+'/web');
+  mkdir('-p', CHROME_BUILD_CONTENT_DIR + BUILD_DIR);
+  mkdir('-p', CHROME_BUILD_CONTENT_DIR + '/web');
 
-  // Copy extension files  
+  // Copy extension files
   cp('-R', CHROME_EXTENSION_FILES, CHROME_BUILD_DIR);
 
   // Copy a standalone version of pdf.js inside the content directory
-  cp(BUILD_TARGET, CHROME_BUILD_CONTENT_DIR+BUILD_DIR);
-  cp('-R', EXTENSION_WEB_FILES, CHROME_BUILD_CONTENT_DIR+'/web');
-  mv('-f', CHROME_BUILD_CONTENT_DIR+'/web/viewer-production.html', CHROME_BUILD_CONTENT_DIR+'/web/viewer.html');
-}
+  cp(BUILD_TARGET, CHROME_BUILD_CONTENT_DIR + BUILD_DIR);
+  cp('-R', EXTENSION_WEB_FILES, CHROME_BUILD_CONTENT_DIR + '/web');
+  mv('-f', CHROME_BUILD_CONTENT_DIR + '/web/viewer-production.html',
+    CHROME_BUILD_CONTENT_DIR + '/web/viewer.html');
+};
 
 
 ///////////////////////////////////////////////////////////////////////////////////////////
@@ -315,7 +324,7 @@ target.chrome = function() {
 target.test = function() {
   target.browsertest();
   target.unittest();
-}
+};
 
 //
 // make browsertest
@@ -328,15 +337,16 @@ target.browsertest = function() {
   var PDF_TEST = env['PDF_TEST'] || 'test_manifest.json',
       PDF_BROWSERS = env['PDF_BROWSERS'] || 'resources/browser_manifests/browser_manifest.json';
 
-  if (!exists('test/'+PDF_BROWSERS)) {
-    echo('Browser manifest file test/'+PDF_BROWSERS+' does not exist.');
+  if (!exists('test/' + PDF_BROWSERS)) {
+    echo('Browser manifest file test/' + PDF_BROWSERS + ' does not exist.');
     echo('Try copying one of the examples in test/resources/browser_manifests/');
     exit(1);
   }
 
   cd('test');
-  exec(PYTHON_BIN+' test.py --reftest --browserManifestFile='+PDF_BROWSERS+' --manifestFile='+PDF_TEST, {async:true});
-}
+  exec(PYTHON_BIN + ' test.py --reftest --browserManifestFile=' + PDF_BROWSERS +
+    ' --manifestFile=' + PDF_TEST, {async: true});
+};
 
 //
 // make unittest
@@ -347,10 +357,8 @@ target.unittest = function() {
   echo('### Running unit tests');
 
   cd('test/unit');
-  exec('make', {async:true});
-}
-
-
+  exec('make', {async: true});
+};
 
 
 ///////////////////////////////////////////////////////////////////////////////////////////
@@ -367,8 +375,8 @@ target.server = function() {
   echo('### Starting local server');
 
   cd('test');
-  exec(PYTHON_BIN+' -u test.py --port=8888', {async:true});
-}
+  exec(PYTHON_BIN + ' -u test.py --port=8888', {async: true});
+};
 
 //
 // make lint
@@ -386,8 +394,8 @@ target.lint = function() {
                     extensions/firefox/components/*.js \
                     extensions/chrome/*.js';
 
-  exec('gjslint --nojsdoc '+LINT_FILES);
-}
+  exec('gjslint --nojsdoc ' + LINT_FILES);
+};
 
 //
 // make clean
@@ -398,4 +406,4 @@ target.clean = function() {
   echo('### Cleaning up project builds');
 
   rm('-rf', BUILD_DIR);
-}
+};

From 02711c761062c544aebadd235cd1d3b937373d0b Mon Sep 17 00:00:00 2001
From: notmasteryet <async.processingjs@yahoo.com>
Date: Wed, 7 Mar 2012 19:12:05 -0600
Subject: [PATCH 15/15] Fixes unnecessary style attributes in svg

---
 web/images/zoom-in.svg  | 4 ++--
 web/images/zoom-out.svg | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/web/images/zoom-in.svg b/web/images/zoom-in.svg
index db28218a8..48ee42dd9 100644
--- a/web/images/zoom-in.svg
+++ b/web/images/zoom-in.svg
@@ -419,12 +419,12 @@
        d="M 33.278212 34.94062 A 10.31934 2.320194 0 1 1  12.639532,34.94062 A 10.31934 2.320194 0 1 1  33.278212 34.94062 z"
        transform="matrix(1.550487,0,0,1.978714,-12.4813,-32.49103)" />
     <path
-       style="font-size:59.901077px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125.00000%;writing-mode:lr-tb;text-anchor:start;fill:#75a1d0;fill-opacity:1.0000000;stroke:#3465a4;stroke-width:1.0000004px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000;font-family:Bitstream Vera Sans"
+       style="fill:#75a1d0;fill-opacity:1.0000000;stroke:#3465a4;stroke-width:1.0000004px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
        d="M 27.514356,37.542682 L 27.514356,28.515722 L 37.492820,28.475543 L 37.492820,21.480219 L 27.523285,21.480219 L 27.514356,11.520049 L 20.498082,11.531210 L 20.502546,21.462362 L 10.512920,21.536022 L 10.477206,28.504561 L 20.511475,28.475543 L 20.518171,37.515896 L 27.514356,37.542682 z "
        id="text1314"
        sodipodi:nodetypes="ccccccccccccc" />
     <path
-       style="font-size:59.901077px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125.00000%;writing-mode:lr-tb;text-anchor:start;opacity:0.40860215;fill:url(#linearGradient4975);fill-opacity:1.0000000;stroke:url(#linearGradient7922);stroke-width:1.0000006px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000;font-family:Bitstream Vera Sans"
+       style="opacity:0.40860215;fill:url(#linearGradient4975);fill-opacity:1.0000000;stroke:url(#linearGradient7922);stroke-width:1.0000006px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
        d="M 26.498702,36.533920 L 26.498702,27.499738 L 36.501304,27.499738 L 36.494607,22.475309 L 26.507630,22.475309 L 26.507630,12.480335 L 21.512796,12.498193 L 21.521725,22.475309 L 11.495536,22.493166 L 11.468750,27.466256 L 21.533143,27.475185 L 21.519750,36.502670 L 26.498702,36.533920 z "
        id="path7076"
        sodipodi:nodetypes="ccccccccccccc" />
diff --git a/web/images/zoom-out.svg b/web/images/zoom-out.svg
index c58d9c4c6..eb13b60e3 100644
--- a/web/images/zoom-out.svg
+++ b/web/images/zoom-out.svg
@@ -407,12 +407,12 @@
      inkscape:label="Layer 1"
      inkscape:groupmode="layer">
     <path
-       style="font-size:59.901077px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125.00000%;writing-mode:lr-tb;text-anchor:start;fill:#75a1d0;fill-opacity:1.0000000;stroke:#3465a4;stroke-width:1.0000004px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000;font-family:Bitstream Vera Sans"
+       style="fill:#75a1d0;fill-opacity:1.0000000;stroke:#3465a4;stroke-width:1.0000004px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
        d="M 27.514356,28.359472 L 39.633445,28.475543 L 39.633445,21.480219 L 27.523285,21.480219 L 20.502546,21.462362 L 8.5441705,21.489147 L 8.5084565,28.457686 L 20.511475,28.475543 L 27.514356,28.359472 z "
        id="text1314"
        sodipodi:nodetypes="ccccccccc" />
     <path
-       style="font-size:59.901077px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125.00000%;writing-mode:lr-tb;text-anchor:start;opacity:0.40860215;fill:url(#linearGradient4975);fill-opacity:1.0000000;stroke:url(#linearGradient7922);stroke-width:1.0000006px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000;font-family:Bitstream Vera Sans"
+       style="opacity:0.40860215;fill:url(#linearGradient4975);fill-opacity:1.0000000;stroke:url(#linearGradient7922);stroke-width:1.0000006px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
        d="M 38.579429,27.484113 L 38.588357,22.475309 L 9.5267863,22.493166 L 9.5000003,27.466256 L 38.579429,27.484113 z "
        id="path7076"
        sodipodi:nodetypes="ccccc" />