Mwalker has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/136162

Change subject: Updated to latest masters
......................................................................

Updated to latest masters

Change-Id: I8735984d093047127358bfb57eee99daf04fc8cb
---
M Makefile
M mw-ocg-bundler
M mw-ocg-latexer
A node_modules/domino/CHANGELOG.md
M node_modules/domino/lib/Element.js
M node_modules/domino/lib/HTMLParser.js
M node_modules/domino/lib/Node.js
M node_modules/domino/package.json
M node_modules/domino/test/domino.js
A node_modules/gammalatex/node_modules/.bin/rimraf
M node_modules/rimraf/package.json
M node_modules/rimraf/rimraf.js
M node_modules/rimraf/test/run.sh
M node_modules/when/package.json
14 files changed, 370 insertions(+), 147 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/services/ocg-collection 
refs/changes/62/136162/1

diff --git a/Makefile b/Makefile
index 56be9fd..6eb4a80 100644
--- a/Makefile
+++ b/Makefile
@@ -1,9 +1,10 @@
 all: debug
 
 core:
-       rm ./package.json
+       export LINK=g++
+       rm -f ./package.json
        npm cache clear
-       npm install when
+       npm install when semver
        ./unify-package-json.js
        npm install
        npm update
diff --git a/mw-ocg-bundler b/mw-ocg-bundler
index 085d024..f5da3aa 160000
--- a/mw-ocg-bundler
+++ b/mw-ocg-bundler
-Subproject commit 085d024cdc33d82fb2cc4b9d7a1560a24dd6910c
+Subproject commit f5da3aae085ff9912ec10190013f0c402c4e0184
diff --git a/mw-ocg-latexer b/mw-ocg-latexer
index 9bff3d6..8803c27 160000
--- a/mw-ocg-latexer
+++ b/mw-ocg-latexer
-Subproject commit 9bff3d6da3ad1255f5c9d5f8d8a190756545acfe
+Subproject commit 8803c27b6a34a8437531105fb1b1d6ef623ba616
diff --git a/node_modules/domino/CHANGELOG.md b/node_modules/domino/CHANGELOG.md
new file mode 100644
index 0000000..82bff5b
--- /dev/null
+++ b/node_modules/domino/CHANGELOG.md
@@ -0,0 +1,67 @@
+# domino 1.0.17 (14 May 2014)
+* Brown paper bag bug fix for an HTML parsing regression introduced in
+  domino 1.0.16. (#45)
+* Update `mocha` dependency to 1.18.x and `should` to 3.3.x.
+
+# domino 1.0.16 (13 May 2014)
+**DO NOT USE:** contains parser regression, fixed in 1.0.17.
+* Various performance improvements to the HTML5 parser. (#43, #44)
+* Fix `Element#isHTML` for non-HTML elements. (#41)
+
+# domino 1.0.15 (21 Jan 2014)
+* Implement `Element#matches()`.
+* Fix CSS `[lang]`, `[dir]`, etc selectors.
+* Update `mocha` dependency to 1.17.x.
+
+# domino 1.0.14 (21 Dec 2013)
+* `Element#classList.length` should be 0 if there's no `class`
+  attribute.
+* Add `height`/`width` attributes to `HTMLImageElement`.
+* Fix node 0.11 incompatibility in the w3c test harness.
+* Update `mocha` dependency to 1.16.x; update `should` dependency to 2.1.x.
+
+# domino 1.0.13 (8 Oct 2013)
+* Include `<th>` elements in `HTMLTableRowElement#cells`. (#38, #39)
+* Fix old call to `toLowerCase()` function. (#37)
+* Update `mocha` and `should` dependencies.
+
+# domino 1.0.12 (9 Jul 2013)
+* Fix bug in formatting element adoption agency algorithm. (#36)
+* Coerce `document.createTextNode` argument to a string. (#34, #35)
+* Work around performance regression in node <= 0.6.
+
+# domino 1.0.11 (1 May 2013)
+* Fix rooted element traversal (`Element#nextElement`,
+  `Element#getElementsByTagName`).  (#31, #32)
+* Update zest to fix bugs in `+` and `>` combinators.
+* Don't overflow the stack if attribute values are very large (>64k).
+
+# domino 1.0.10 (12 Apr 2013)
+* Document issues with `Element#attributes`. (#27)
+* Fix `Document#title` to match DOM spec. (#29)
+* Add missing `require('utils')` for `handleErrors`. (#28)
+* Implement `DocumentFragment#querySelector` and
+  `DocumentFragment#querySelectorAll`. (#20, #26)
+* Fix `querySelectorAll` on unparented `Element`s. (#23)
+* Move `outerHTML`/`innerHTML` properties from `HTMLElement` to
+  `Element` to match dom parsing spec. (#21)
+* Update zest selector library to 0.0.4. (#25)
+* Fix regression in node 0.10. (#22, #24)
+* Update `mocha` and `should` dependencies.
+
+# domino 1.0.9 (11 Mar 2013)
+* Support jQuery 1.9.x by allowing `Element#attributes[qname]`.
+* Implement `HTMLElement#outerHTML`. (#18)
+* Only add newlines after `<pre>`/`<textarea>`/`<listing>` if
+  necessary, to match HTML5 serialization spec. (#16, #17)
+* Mirror node type properties (`ELEMENT_NODE`, etc) into
+  `Node.prototype`. (#14, #15)
+
+# domino 1.0.8
+
+**DO NOT USE:** was inadvertently published identical to domino 1.0.7.
+
+# domino 1.0.7 (16 Jan 2013)
+* Throw `SyntaxError` upon invocation rather than build-time. (#10)
+* Return nodes in document order. (#11)
+* Added a TreeWalker implementation.
diff --git a/node_modules/domino/lib/Element.js 
b/node_modules/domino/lib/Element.js
index f1d9806..35e7e3a 100644
--- a/node_modules/domino/lib/Element.js
+++ b/node_modules/domino/lib/Element.js
@@ -218,7 +218,7 @@
   }},
 
   // Overwritten in the constructor if not in the HTML namespace
-  isHTML: { value: true },
+  isHTML: { value: true, writable: true },
 
   // Utility methods used by the public API methods above
   clone: { value: function clone() {
diff --git a/node_modules/domino/lib/HTMLParser.js 
b/node_modules/domino/lib/HTMLParser.js
index 7a213cd..03f3f06 100644
--- a/node_modules/domino/lib/HTMLParser.js
+++ b/node_modules/domino/lib/HTMLParser.js
@@ -1438,11 +1438,24 @@
 // Like the above, but for named char refs, the last char can't be =
 var ATTRCHARREF = 
/^#[0-9]+[^0-9]|^#[xX][0-9a-fA-F]+[^0-9a-fA-F]|^[a-zA-Z][a-zA-Z0-9]*[^=a-zA-Z0-9]/;
 
+// note that \r is included in all of these regexps because it will need
+// to be converted to LF by the scanChars() function.
+var DBLQUOTEATTRVAL = /[^\r"&\u0000]+/g;
+var SINGLEQUOTEATTRVAL = /[^\r'&\u0000]+/g;
+var UNQUOTEDATTRVAL = /[^\r\t\n\f &>\u0000]+/g;
+var TAGNAME = /[^\r\t\n\f \/>A-Z\u0000]+/g;
+var ATTRNAME = /[^\r\t\n\f \/=>A-Z\u0000]+/g;
+
 var DATATEXT = /[^&<\r\u0000\uffff]*/g;
 var RAWTEXT = /[^<\r\u0000\uffff]*/g;
 var PLAINTEXT = /[^\r\u0000\uffff]*/g;
-var SIMPLETAG = /^(\/)?([a-z]+)>/g;
-var SIMPLEATTR = /^([a-z]+) *= *('[^'&\r\u0000]*'|"[^"&\r\u0000]*"|[^&> 
\t\n\r\f\u0000][ \t\n\f])/g;
+// Since we don't have the 'sticky tag', add '|.' to the end of SIMPLETAG
+// and SIMPLEATTR so that we are guaranteed to always match.  This prevents
+// us from scanning past the lastIndex set. (Note that the desired matches
+// are always greater than 1 char long, so longest-match will ensure that .
+// is not matched unless the desired match fails.)
+var SIMPLETAG = /(?:(\/)?([a-z]+)>)|[\s\S]/g;
+var SIMPLEATTR = /(?:([-a-z]+)[ \t\n\f]*=[ 
\t\n\f]*('[^'&\r\u0000]*'|"[^"&\r\u0000]*"|[^\t\n\r\f "&'\u0000>][^&> 
\t\n\r\f\u0000]*[ \t\n\f]))|[\s\S]/g;
 
 var NONWS = /[^\x09\x0A\x0C\x0D\x20]/;
 var ALLNONWS = /[^\x09\x0A\x0C\x0D\x20]/g; // like above, with g flag
@@ -1853,11 +1866,11 @@
   // Tokenizer state
   var tokenizer = data_state; // Current tokenizer state
   var savedTokenizerStates = []; // Stack of saved states
-  var tagnamebuf = [];
+  var tagnamebuf = "";
   var lasttagname = ""; // holds the target end tag for text states
   var tempbuf = [];
-  var attrnamebuf = [];
-  var attrvaluebuf = [];
+  var attrnamebuf = "";
+  var attrvaluebuf = "";
   var commentbuf = [];
   var doctypenamebuf = [];
   var doctypepublicbuf = [];
@@ -2234,18 +2247,15 @@
   /***
    * Tokenizer utility functions
    */
-  function addAttribute(namebuf,valuebuf) {
-    var name = buf2str(namebuf);
-    var value;
-
+  function addAttribute(name,value) {
     // Make sure there isn't already an attribute with this name
     // If there is, ignore this one.
     for(var i = 0; i < attributes.length; i++) {
       if (attributes[i][0] === name) return;
     }
 
-    if (valuebuf) {
-      attributes.push([name, buf2str(valuebuf)]);
+    if (value !== undefined) {
+      attributes.push([name, value]);
     }
     else {
       attributes.push([name]);
@@ -2256,8 +2266,9 @@
   function handleSimpleAttribute() {
     SIMPLEATTR.lastIndex = nextchar-1;
     var matched = SIMPLEATTR.exec(chars);
-    if (!matched) return false;
+    if (!matched) throw new Error("should never happen");
     var name = matched[1];
+    if (!name) return false;
     var value = matched[2];
     var len = value.length;
     switch(value[0]) {
@@ -2289,18 +2300,18 @@
   function popState() { tokenizer = savedTokenizerStates.pop(); }
   function beginTagName() {
     is_end_tag = false;
-    tagnamebuf.length = 0;
+    tagnamebuf = "";
     attributes.length = 0;
   }
   function beginEndTagName() {
     is_end_tag = true;
-    tagnamebuf.length = 0;
+    tagnamebuf = "";
     attributes.length = 0;
   }
 
   function beginTempBuf() { tempbuf.length = 0; }
-  function beginAttrName() { attrnamebuf.length = 0; }
-  function beginAttrValue() { attrvaluebuf.length = 0; }
+  function beginAttrName() { attrnamebuf = ""; }
+  function beginAttrValue() { attrvaluebuf = ""; }
   function beginComment() { commentbuf.length = 0; }
   function beginDoctype() {
     doctypenamebuf.length = 0;
@@ -2318,11 +2329,7 @@
   // Return true if the codepoints in the specified buffer match the
   // characters of lasttagname
   function appropriateEndTag(buf) {
-    if (buf.length !== lasttagname.length) return false;
-    for(var i = 0, n = buf.length; i < n; i++) {
-      if (buf[i] !== lasttagname.charCodeAt(i)) return false;
-    }
-    return true;
+    return lasttagname === buf;
   }
 
   function flushText() {
@@ -2340,6 +2347,21 @@
       textIncludesNUL = false;
     }
     ignore_linefeed = false;
+  }
+
+  // Consume chars matched by the pattern and return them as a string. Starts
+  // matching at the current position, so users should drop the current char
+  // otherwise.
+  function getMatchingChars(pattern) {
+      pattern.lastIndex = nextchar - 1;
+      var match = pattern.exec(chars);
+      if (match && match.index === nextchar - 1) {
+          match = match[0];
+          nextchar += match.length - 1;
+          return match;
+      } else {
+          throw new Error("should never happen");
+      }
   }
 
   // emit a string of chars that match a regexp
@@ -2367,11 +2389,11 @@
   }
 
   function emitTag() {
-    if (is_end_tag) insertToken(ENDTAG, buf2str(tagnamebuf));
+    if (is_end_tag) insertToken(ENDTAG, tagnamebuf);
     else {
       // Remember the last open tag we emitted
-      var tagname = buf2str(tagnamebuf);
-      tagnamebuf.length = 0;
+      var tagname = tagnamebuf;
+      tagnamebuf = "";
       lasttagname = tagname;
       insertToken(TAG, tagname, attributes);
     }
@@ -2383,8 +2405,9 @@
   function emitSimpleTag() {
     SIMPLETAG.lastIndex = nextchar;
     var matched = SIMPLETAG.exec(chars);
-    if (!matched) return false;
+    if (!matched) throw new Error("should never happen");
     var tagname = matched[2];
+    if (!tagname) return false;
     var endtag = matched[1];
     if (endtag) {
       nextchar += (tagname.length+2);
@@ -2399,9 +2422,9 @@
   }
 
   function emitSelfClosingTag() {
-    if (is_end_tag) insertToken(ENDTAG, buf2str(tagnamebuf), null, true);
+    if (is_end_tag) insertToken(ENDTAG, tagnamebuf, null, true);
     else {
-      insertToken(TAG, buf2str(tagnamebuf), attributes, true);
+      insertToken(TAG, tagnamebuf, attributes, true);
     }
   }
 
@@ -2418,7 +2441,7 @@
     doc.modclock = 1; // Start tracking modifications
   }
 
-  // Insert a token, either using the current parser insertio mode
+  // Insert a token, either using the current parser insertion mode
   // (for HTML stuff) or using the insertForeignToken() method.
   function insertToken(t, value, arg3, arg4) {
     flushText();
@@ -3187,9 +3210,10 @@
     case 0x004C:case 0x004D:case 0x004E:case 0x004F:case 0x0050:
     case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:
     case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:
-      c += 0x20; // to lowercase
-      /* falls through */
-
+      beginTagName();
+      tagnamebuf += String.fromCharCode(c + 0x0020 /* to lowercase */);
+      tokenizer = tag_name_state;
+      break;
     case 0x0061:  // [a-z]
     case 0x0062:case 0x0063:case 0x0064:case 0x0065:case 0x0066:
     case 0x0067:case 0x0068:case 0x0069:case 0x006A:case 0x006B:
@@ -3197,7 +3221,7 @@
     case 0x0071:case 0x0072:case 0x0073:case 0x0074:case 0x0075:
     case 0x0076:case 0x0077:case 0x0078:case 0x0079:case 0x007A:
       beginTagName();
-      tagnamebuf.push(c);
+      tagnamebuf += getMatchingChars(TAGNAME);
       tokenizer = tag_name_state;
       break;
     case 0x003F: // QUESTION MARK
@@ -3220,9 +3244,10 @@
     case 0x004C:case 0x004D:case 0x004E:case 0x004F:case 0x0050:
     case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:
     case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:
-      c += 0x20; // to lowercase
-      /* falls through */
-
+      beginEndTagName();
+      tagnamebuf += String.fromCharCode(c + 0x0020 /* to lowercase */);
+      tokenizer = tag_name_state;
+      break;
     case 0x0061:  // [a-z]
     case 0x0062:case 0x0063:case 0x0064:case 0x0065:case 0x0066:
     case 0x0067:case 0x0068:case 0x0069:case 0x006A:case 0x006B:
@@ -3230,7 +3255,7 @@
     case 0x0071:case 0x0072:case 0x0073:case 0x0074:case 0x0075:
     case 0x0076:case 0x0077:case 0x0078:case 0x0079:case 0x007A:
       beginEndTagName();
-      tagnamebuf.push(c);
+      tagnamebuf += getMatchingChars(TAGNAME);
       tokenizer = tag_name_state;
       break;
     case 0x003E: // GREATER-THAN SIGN
@@ -3270,18 +3295,17 @@
     case 0x004C:case 0x004D:case 0x004E:case 0x004F:case 0x0050:
     case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:
     case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:
-      tagnamebuf.push(c + 0x0020);
+      tagnamebuf += String.fromCharCode(c + 0x0020);
       break;
     case 0x0000: // NULL
-      tagnamebuf.push(0xFFFD /* REPLACEMENT CHARACTER */);
+      tagnamebuf += String.fromCharCode(0xFFFD /* REPLACEMENT CHARACTER */);
       break;
     case -1: // EOF
       nextchar--; // pushback
       tokenizer = data_state;
       break;
     default:
-      tagnamebuf.push(c);
-      // appendCharsWhile(tagnamebuf, TAGNAMECHARS) || tagnamebuf.push(c);
+      tagnamebuf += getMatchingChars(TAGNAME);
       break;
     }
   }
@@ -3309,7 +3333,7 @@
     case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:
     case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:
       beginEndTagName();
-      tagnamebuf.push(c + 0x0020);
+      tagnamebuf += String.fromCharCode(c + 0x0020);
       tempbuf.push(c);
       tokenizer = rcdata_end_tag_name_state;
       break;
@@ -3320,7 +3344,7 @@
     case 0x0071:case 0x0072:case 0x0073:case 0x0074:case 0x0075:
     case 0x0076:case 0x0077:case 0x0078:case 0x0079:case 0x007A:
       beginEndTagName();
-      tagnamebuf.push(c);
+      tagnamebuf += String.fromCharCode(c);
       tempbuf.push(c);
       tokenizer = rcdata_end_tag_name_state;
       break;
@@ -3365,7 +3389,7 @@
     case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:
     case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:
 
-      tagnamebuf.push(c + 0x0020);
+      tagnamebuf += String.fromCharCode(c + 0x0020);
       tempbuf.push(c);
       return;
     case 0x0061:  // [a-z]
@@ -3375,7 +3399,7 @@
     case 0x0071:case 0x0072:case 0x0073:case 0x0074:case 0x0075:
     case 0x0076:case 0x0077:case 0x0078:case 0x0079:case 0x007A:
 
-      tagnamebuf.push(c);
+      tagnamebuf += String.fromCharCode(c);
       tempbuf.push(c);
       return;
     default:
@@ -3416,7 +3440,7 @@
     case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:
     case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:
       beginEndTagName();
-      tagnamebuf.push(c + 0x0020);
+      tagnamebuf += String.fromCharCode(c + 0x0020);
       tempbuf.push(c);
       tokenizer = rawtext_end_tag_name_state;
       break;
@@ -3427,7 +3451,7 @@
     case 0x0071:case 0x0072:case 0x0073:case 0x0074:case 0x0075:
     case 0x0076:case 0x0077:case 0x0078:case 0x0079:case 0x007A:
       beginEndTagName();
-      tagnamebuf.push(c);
+      tagnamebuf += String.fromCharCode(c);
       tempbuf.push(c);
       tokenizer = rawtext_end_tag_name_state;
       break;
@@ -3471,7 +3495,7 @@
     case 0x004C:case 0x004D:case 0x004E:case 0x004F:case 0x0050:
     case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:
     case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:
-      tagnamebuf.push(c + 0x0020);
+      tagnamebuf += String.fromCharCode(c + 0x0020);
       tempbuf.push(c);
       return;
     case 0x0061:  // [a-z]
@@ -3480,7 +3504,7 @@
     case 0x006C:case 0x006D:case 0x006E:case 0x006F:case 0x0070:
     case 0x0071:case 0x0072:case 0x0073:case 0x0074:case 0x0075:
     case 0x0076:case 0x0077:case 0x0078:case 0x0079:case 0x007A:
-      tagnamebuf.push(c);
+      tagnamebuf += String.fromCharCode(c);
       tempbuf.push(c);
       return;
     default:
@@ -3526,7 +3550,7 @@
     case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:
     case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:
       beginEndTagName();
-      tagnamebuf.push(c + 0x0020);
+      tagnamebuf += String.fromCharCode(c + 0x0020);
       tempbuf.push(c);
       tokenizer = script_data_end_tag_name_state;
       break;
@@ -3537,7 +3561,7 @@
     case 0x0071:case 0x0072:case 0x0073:case 0x0074:case 0x0075:
     case 0x0076:case 0x0077:case 0x0078:case 0x0079:case 0x007A:
       beginEndTagName();
-      tagnamebuf.push(c);
+      tagnamebuf += String.fromCharCode(c);
       tempbuf.push(c);
       tokenizer = script_data_end_tag_name_state;
       break;
@@ -3582,7 +3606,7 @@
     case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:
     case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:
 
-      tagnamebuf.push(c + 0x0020);
+      tagnamebuf += String.fromCharCode(c + 0x0020);
       tempbuf.push(c);
       return;
     case 0x0061:  // [a-z]
@@ -3592,7 +3616,7 @@
     case 0x0071:case 0x0072:case 0x0073:case 0x0074:case 0x0075:
     case 0x0076:case 0x0077:case 0x0078:case 0x0079:case 0x007A:
 
-      tagnamebuf.push(c);
+      tagnamebuf += String.fromCharCode(c);
       tempbuf.push(c);
       return;
     default:
@@ -3751,7 +3775,7 @@
     case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:
     case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:
       beginEndTagName();
-      tagnamebuf.push(c + 0x0020);
+      tagnamebuf += String.fromCharCode(c + 0x0020);
       tempbuf.push(c);
       tokenizer = script_data_escaped_end_tag_name_state;
       break;
@@ -3762,7 +3786,7 @@
     case 0x0071:case 0x0072:case 0x0073:case 0x0074:case 0x0075:
     case 0x0076:case 0x0077:case 0x0078:case 0x0079:case 0x007A:
       beginEndTagName();
-      tagnamebuf.push(c);
+      tagnamebuf += String.fromCharCode(c);
       tempbuf.push(c);
       tokenizer = script_data_escaped_end_tag_name_state;
       break;
@@ -3805,7 +3829,7 @@
     case 0x004C:case 0x004D:case 0x004E:case 0x004F:case 0x0050:
     case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:
     case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:
-      tagnamebuf.push(c + 0x0020);
+      tagnamebuf += String.fromCharCode(c + 0x0020);
       tempbuf.push(c);
       return;
     case 0x0061:  // [a-z]
@@ -3814,7 +3838,7 @@
     case 0x006C:case 0x006D:case 0x006E:case 0x006F:case 0x0070:
     case 0x0071:case 0x0072:case 0x0073:case 0x0074:case 0x0075:
     case 0x0076:case 0x0077:case 0x0078:case 0x0079:case 0x007A:
-      tagnamebuf.push(c);
+      tagnamebuf += String.fromCharCode(c);
       tempbuf.push(c);
       return;
     default:
@@ -4022,12 +4046,12 @@
     case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:
     case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:
       beginAttrName();
-      attrnamebuf.push(c + 0x0020);
+      attrnamebuf += String.fromCharCode(c + 0x0020);
       tokenizer = attribute_name_state;
       break;
     case 0x0000: // NULL
       beginAttrName();
-      attrnamebuf.push(0xFFFD);
+      attrnamebuf += String.fromCharCode(0xFFFD);
       tokenizer = attribute_name_state;
       break;
     case -1: // EOF
@@ -4042,7 +4066,11 @@
     default:
       if (handleSimpleAttribute()) break;
       beginAttrName();
-      attrnamebuf.push(c);
+      if (c === 0x003D) {
+        attrnamebuf += '='; // not valid elsewhere in attribute_name_state!
+      } else {
+        attrnamebuf += getMatchingChars(ATTRNAME);
+      }
       tokenizer = attribute_name_state;
       break;
     }
@@ -4075,10 +4103,10 @@
     case 0x004C:case 0x004D:case 0x004E:case 0x004F:case 0x0050:
     case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:
     case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:
-      attrnamebuf.push(c + 0x0020);
+      attrnamebuf += String.fromCharCode(c + 0x0020);
       break;
     case 0x0000: // NULL
-      attrnamebuf.push(0xFFFD /* REPLACEMENT CHARACTER */);
+      attrnamebuf += String.fromCharCode(0xFFFD /* REPLACEMENT CHARACTER */);
       break;
     case -1: // EOF
       nextchar--; // pushback
@@ -4089,7 +4117,7 @@
     case 0x003C: // LESS-THAN SIGN
       /* falls through */
     default:
-      attrnamebuf.push(c);
+      attrnamebuf += getMatchingChars(ATTRNAME);
       break;
     }
   }
@@ -4123,13 +4151,13 @@
     case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:
       addAttribute(attrnamebuf);
       beginAttrName();
-      attrnamebuf.push(c + 0x0020);
+      attrnamebuf += String.fromCharCode(c + 0x0020);
       tokenizer = attribute_name_state;
       break;
     case 0x0000: // NULL
       addAttribute(attrnamebuf);
       beginAttrName();
-      attrnamebuf.push(0xFFFD);
+      attrnamebuf += String.fromCharCode(0xFFFD);
       tokenizer = attribute_name_state;
       break;
     case -1: // EOF
@@ -4143,7 +4171,7 @@
     default:
       addAttribute(attrnamebuf);
       beginAttrName();
-      attrnamebuf.push(c);
+      attrnamebuf += getMatchingChars(ATTRNAME);
       tokenizer = attribute_name_state;
       break;
     }
@@ -4168,7 +4196,7 @@
       tokenizer = attribute_value_single_quoted_state;
       break;
     case 0x0000: // NULL
-      attrvaluebuf.push(0xFFFD /* REPLACEMENT CHARACTER */);
+      attrvaluebuf += String.fromCharCode(0xFFFD /* REPLACEMENT CHARACTER */);
       tokenizer = attribute_value_unquoted_state;
       break;
     case 0x003E: // GREATER-THAN SIGN
@@ -4185,7 +4213,7 @@
     case 0x0060: // GRAVE ACCENT
       /* falls through */
     default:
-      attrvaluebuf.push(c);
+      attrvaluebuf += getMatchingChars(UNQUOTEDATTRVAL);
       tokenizer = attribute_value_unquoted_state;
       break;
     }
@@ -4202,15 +4230,18 @@
       tokenizer = character_reference_in_attribute_value_state;
       break;
     case 0x0000: // NULL
-      attrvaluebuf.push(0xFFFD /* REPLACEMENT CHARACTER */);
+      attrvaluebuf += String.fromCharCode(0xFFFD /* REPLACEMENT CHARACTER */);
       break;
     case -1: // EOF
       nextchar--; // pushback
       tokenizer = data_state;
       break;
+    case 0x000A: // LF
+      // this could be a converted \r, so don't use getMatchingChars
+      attrvaluebuf += String.fromCharCode(c);
+      break;
     default:
-      attrvaluebuf.push(c);
-      // appendCharsWhile(attrvaluebuf, DBLQUOTEATTRVAL);
+      attrvaluebuf += getMatchingChars(DBLQUOTEATTRVAL);
       break;
     }
   }
@@ -4226,15 +4257,18 @@
       tokenizer = character_reference_in_attribute_value_state;
       break;
     case 0x0000: // NULL
-      attrvaluebuf.push(0xFFFD /* REPLACEMENT CHARACTER */);
+      attrvaluebuf += String.fromCharCode(0xFFFD /* REPLACEMENT CHARACTER */);
       break;
     case -1: // EOF
       nextchar--; // pushback
       tokenizer = data_state;
       break;
+    case 0x000A: // LF
+      // this could be a converted \r, so don't use getMatchingChars
+      attrvaluebuf += String.fromCharCode(c);
+      break;
     default:
-      attrvaluebuf.push(c);
-      // appendCharsWhile(attrvaluebuf, SINGLEQUOTEATTRVAL);
+      attrvaluebuf += getMatchingChars(SINGLEQUOTEATTRVAL);
       break;
     }
   }
@@ -4258,7 +4292,7 @@
       emitTag();
       break;
     case 0x0000: // NULL
-      attrvaluebuf.push(0xFFFD /* REPLACEMENT CHARACTER */);
+      attrvaluebuf += String.fromCharCode(0xFFFD /* REPLACEMENT CHARACTER */);
       break;
     case -1: // EOF
       nextchar--; // pushback
@@ -4271,8 +4305,7 @@
     case 0x0060: // GRAVE ACCENT
       /* falls through */
     default:
-      attrvaluebuf.push(c);
-      // appendCharsWhile(attrvaluebuf, UNQUOTEDATTRVAL);
+      attrvaluebuf += getMatchingChars(UNQUOTEDATTRVAL);
       break;
     }
   }
@@ -4281,16 +4314,14 @@
     var char = parseCharRef(lookahead, true);
     if (char !== null) {
       if (typeof char === "number")
-        attrvaluebuf.push(char);
+        attrvaluebuf += String.fromCharCode(char);
       else {
         // An array of numbers
-        for(var i = 0; i < char.length; i++) {
-          attrvaluebuf.push(char[i]);
-        }
+        attrvaluebuf += String.fromCharCode.apply(String, char);
       }
     }
     else {
-      attrvaluebuf.push(0x0026); // AMPERSAND;
+      attrvaluebuf += '&'; // AMPERSAND;
     }
 
     popState();
diff --git a/node_modules/domino/lib/Node.js b/node_modules/domino/lib/Node.js
index 5cc083d..6b13422 100644
--- a/node_modules/domino/lib/Node.js
+++ b/node_modules/domino/lib/Node.js
@@ -614,13 +614,19 @@
 }
 
 function escapeAttr(s) {
-  return s.replace(/[&"\u00A0]/g, function(c) {
-    switch(c) {
-    case '&': return '&amp;';
-    case '"': return '&quot;';
-    case '\u00A0': return '&nbsp;';
-    }
-  });
+  var toEscape = /[&"\u00A0]/g;
+  if (!toEscape.test(s)) {
+         // nothing to do, fast path
+         return s;
+  } else {
+         return s.replace(toEscape, function(c) {
+               switch(c) {
+               case '&': return '&amp;';
+               case '"': return '&quot;';
+               case '\u00A0': return '&nbsp;';
+               }
+         });
+  }
 }
 
 function attrname(a) {
diff --git a/node_modules/domino/package.json b/node_modules/domino/package.json
index 622be37..72b12af 100644
--- a/node_modules/domino/package.json
+++ b/node_modules/domino/package.json
@@ -1,6 +1,6 @@
 {
   "name": "domino",
-  "version": "1.0.15",
+  "version": "1.0.17",
   "author": {
     "name": "Felix Gnass",
     "email": "fgn...@gmail.com"
@@ -17,18 +17,18 @@
     "test-spec": "./node_modules/.bin/mocha -R spec"
   },
   "devDependencies": {
-    "mocha": "~1.17.0",
-    "should": "~2.1.0"
+    "mocha": "~1.18.2",
+    "should": "~3.3.1"
   },
   "readme": "# Server-side DOM implementation based on Mozilla's 
dom.js\n\n[![Build Status][1]][2] [![dependency status][3]][4] [![dev 
dependency status][5]][6]\n\nAs the name might suggest, domino's goal is to 
provide a <b>DOM in No</b>de.\n\nIn contrast to the original 
[dom.js](https://github.com/andreasgal/dom.js) project, domino was not designed 
to run untrusted code. Hence it doesn't have to hide its internals behind a 
proxy facade which makes the code not only simpler, but also [more 
performant](https://github.com/fgnass/dombench).\n\nDomino currently doesn't 
use any harmony features like proxies or WeakMaps and therefore also runs in 
older Node versions.\n\n## Speed over Compliance\n\nDomino is intended for 
_building_ pages rather than scraping them. Hence Domino doesn't execute 
scripts nor does it download external resources.\n\nAlso Domino doesn't 
implement any properties which have been deprecated in HTML5.\n\nDomino sticks 
to the [DOM level 
4](http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#interface-attr) 
working draft, which means that Attributes do not inherit the Node interface. 
Also 
[Element.attributes](http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#dom-element-attributes)
 returns a read-only array instead of a NamedNodeMap.\n\n<b>Note that</b> 
because domino does not use proxies,\n`Element.attributes` is not a true 
JavaScript array; it is an object\nwith a `length` property and an `item(n)` 
accessor method.  See\n[github issue 
#27](https://github.com/fgnass/domino/issues/27) for\nfurther discussion.\n\n## 
CSS Selector Support\n\nDomino provides support for `querySelector()`, 
`querySelectorAll()`, and `matches()` backed by the 
[Zest](https://github.com/chjj/zest) selector engine.\n\n## 
Usage\n\n```javascript\nvar domino = require('domino');\n\nvar window = 
domino.createWindow('<h1>Hello world</h1>');\nvar document = 
window.document;\n\nvar h1 = 
document.querySelector('h1');\nconsole.log(h1.innerHTML);\n```\n\n## 
Tests\n\nDomino includes test from the [W3C DOM Conformance 
Suites](http://www.w3.org/DOM/Test/)\nas well as tests from [HTML Working 
Group](http://www.w3.org/html/wg/wiki/Testing).\n\nThe tests can be run via 
`npm test` or directly though the [Mocha](http://visionmedia.github.com/mocha/) 
command 
line:\n\n![Screenshot](http://fgnass.github.com/images/domino.png)\n\n## 
License and Credits\n\nThe majority of the code was written by [Andreas 
Gal](https://github.com/andreasgal/) and [David 
Flanagan](https://github.com/davidflanagan) as part of the 
[dom.js](https://github.com/andreasgal/dom.js) project. Please refer to the 
included LICENSE file for the original copyright notice and disclaimer.\n\n[1]: 
https://travis-ci.org/fgnass/domino.png\n[2]: 
https://travis-ci.org/fgnass/domino\n[3]: 
https://david-dm.org/fgnass/domino.png\n[4]: 
https://david-dm.org/fgnass/domino\n[5]: 
https://david-dm.org/fgnass/domino/dev-status.png\n[6]: 
https://david-dm.org/fgnass/domino#info=devDependencies\n";,
   "readmeFilename": "README.md",
   "bugs": {
     "url": "https://github.com/fgnass/domino/issues";
   },
-  "_id": "domino@1.0.15",
+  "_id": "domino@1.0.17",
   "dist": {
-    "shasum": "07cf0b618f918ed5d0bacf3d589031e915802f45"
+    "shasum": "59bea71fa864ff5c02e3baf1f65fc13fbeb31848"
   },
-  "_from": "domino@~1.0.15",
-  "_resolved": "https://registry.npmjs.org/domino/-/domino-1.0.15.tgz";
+  "_from": "domino@1.0.17",
+  "_resolved": "https://registry.npmjs.org/domino/-/domino-1.0.17.tgz";
 }
diff --git a/node_modules/domino/test/domino.js 
b/node_modules/domino/test/domino.js
index b83360d..ebf203a 100644
--- a/node_modules/domino/test/domino.js
+++ b/node_modules/domino/test/domino.js
@@ -126,7 +126,7 @@
   var d = domino.createDocument(html);
   var c = d.body.children;
   c.should.have.length(4);
-  c.should.have.property(0);
+  c.should.have.property('0');
   var a = Array.prototype.slice.call(c);
   a.should.be.an.instanceof(Array);
   a.should.have.length(4);
@@ -178,7 +178,7 @@
   div.attributes.should.have.property('onclick');
   div.attributes.onclick.should.have.property('value', 't');
   div.removeAttribute('onclick');
-  div.attributes.should.not.have.property('onclick');
+  (div.attributes.onclick === undefined).should.be.true;
 }
 
 exports.jquery = function() {
@@ -305,3 +305,44 @@
 
   h1.matches('*[isHTML]').should.equal(false);
 };
+
+exports.crHandling = function() {
+  var html = '<div\rid=a data-test=1\rfoo="\r"\rbar=\'\r\'\rbat=\r>\r</div\r>';
+  var doc = domino.createDocument(html);
+  var div = doc.querySelector('#a');
+  (div != null).should.be.true;
+  // all \r should be converted to \n
+  div.outerHTML.should.equal('<div id="a" data-test="1" foo="\n" bar="\n" 
bat="">\n</div>');
+};
+
+exports.eqAttr = function() {
+  var html = "<div id=a ==x><a=B></A=b></div>";
+  var doc = domino.createDocument(html);
+  var div = doc.querySelector('#a');
+  (div != null).should.be.true;
+  div.attributes.length.should.equal(2);
+  div.attributes.item(1).name.should.equal('=');
+  div.children.length.should.equal(1);
+  div.children[0].tagName.should.equal('A=B');
+};
+
+exports.tagNameCase = function() {
+  // See https://github.com/fgnass/domino/pull/41
+  var impl = domino.createDOMImplementation();
+  var namespace = 'http://schemas.xmlsoap.org/soap/envelope/';
+  var qualifiedName = 'Envelope';
+  var doc = impl.createDocument(namespace, qualifiedName, null);
+  doc.documentElement.tagName.should.equal(qualifiedName);
+};
+
+exports.fastAttributes = function() {
+  // test the SIMPLETAG/SIMPLEATTR path in HTMLParser
+  var html = "<div id=a b=\"x &quot;y\" c='a \rb'><\np></div>";
+  var doc = domino.createDocument(html);
+  var div = doc.querySelector('#a');
+  (div != null).should.be.true;
+  div.attributes.length.should.equal(3);
+  div.attributes.item(1).value.should.equal('x "y');
+  div.attributes.item(2).value.should.equal('a \nb');
+  div.children.length.should.equal(0);
+};
diff --git a/node_modules/gammalatex/node_modules/.bin/rimraf 
b/node_modules/gammalatex/node_modules/.bin/rimraf
new file mode 120000
index 0000000..4cd49a4
--- /dev/null
+++ b/node_modules/gammalatex/node_modules/.bin/rimraf
@@ -0,0 +1 @@
+../rimraf/bin.js
\ No newline at end of file
diff --git a/node_modules/rimraf/package.json b/node_modules/rimraf/package.json
index a4dff2f..adb3a65 100644
--- a/node_modules/rimraf/package.json
+++ b/node_modules/rimraf/package.json
@@ -1,6 +1,6 @@
 {
   "name": "rimraf",
-  "version": "2.2.6",
+  "version": "2.2.8",
   "main": "rimraf.js",
   "description": "A deep deletion module for node (like `rm -rf`)",
   "author": {
@@ -50,10 +50,10 @@
   "bugs": {
     "url": "https://github.com/isaacs/rimraf/issues";
   },
-  "_id": "rimraf@2.2.6",
+  "_id": "rimraf@2.2.8",
   "dist": {
-    "shasum": "c1fa09fbd011d9d771fda1bf3a83f71330672dd6"
+    "shasum": "43e67e90396f05b9425d2d3c0ea58a691df523fa"
   },
-  "_from": "rimraf@~2.2.2",
-  "_resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.6.tgz";
+  "_from": "rimraf@2.2.8",
+  "_resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz";
 }
diff --git a/node_modules/rimraf/rimraf.js b/node_modules/rimraf/rimraf.js
index ce62051..eb96c46 100644
--- a/node_modules/rimraf/rimraf.js
+++ b/node_modules/rimraf/rimraf.js
@@ -1,6 +1,7 @@
 module.exports = rimraf
 rimraf.sync = rimrafSync
 
+var assert = require("assert")
 var path = require("path")
 var fs = require("fs")
 
@@ -11,11 +12,36 @@
 
 var isWindows = (process.platform === "win32")
 
-function rimraf (p, cb) {
+function defaults (options) {
+  var methods = [
+    'unlink',
+    'chmod',
+    'stat',
+    'rmdir',
+    'readdir'
+  ]
+  methods.forEach(function(m) {
+    options[m] = options[m] || fs[m]
+    m = m + 'Sync'
+    options[m] = options[m] || fs[m]
+  })
+}
+
+function rimraf (p, options, cb) {
+  if (typeof options === 'function') {
+    cb = options
+    options = {}
+  }
+  assert(p)
+  assert(options)
+  assert(typeof cb === 'function')
+
+  defaults(options)
+
   if (!cb) throw new Error("No callback passed to rimraf()")
 
   var busyTries = 0
-  rimraf_(p, function CB (er) {
+  rimraf_(p, options, function CB (er) {
     if (er) {
       if (isWindows && (er.code === "EBUSY" || er.code === "ENOTEMPTY") &&
           busyTries < exports.BUSYTRIES_MAX) {
@@ -23,14 +49,14 @@
         var time = busyTries * 100
         // try again, with the same exact callback as this one.
         return setTimeout(function () {
-          rimraf_(p, CB)
+          rimraf_(p, options, CB)
         }, time)
       }
 
       // this one won't happen if graceful-fs is used.
       if (er.code === "EMFILE" && timeout < exports.EMFILE_MAX) {
         return setTimeout(function () {
-          rimraf_(p, CB)
+          rimraf_(p, options, CB)
         }, timeout ++)
       }
 
@@ -54,64 +80,91 @@
 //
 // If anyone ever complains about this, then I guess the strategy could
 // be made configurable somehow.  But until then, YAGNI.
-function rimraf_ (p, cb) {
-  fs.unlink(p, function (er) {
+function rimraf_ (p, options, cb) {
+  assert(p)
+  assert(options)
+  assert(typeof cb === 'function')
+
+  options.unlink(p, function (er) {
     if (er) {
       if (er.code === "ENOENT")
         return cb(null)
       if (er.code === "EPERM")
-        return (isWindows) ? fixWinEPERM(p, er, cb) : rmdir(p, er, cb)
+        return (isWindows)
+          ? fixWinEPERM(p, options, er, cb)
+          : rmdir(p, options, er, cb)
       if (er.code === "EISDIR")
-        return rmdir(p, er, cb)
+        return rmdir(p, options, er, cb)
     }
     return cb(er)
   })
 }
 
-function fixWinEPERM (p, er, cb) {
-  fs.chmod(p, 666, function (er2) {
+function fixWinEPERM (p, options, er, cb) {
+  assert(p)
+  assert(options)
+  assert(typeof cb === 'function')
+  if (er)
+    assert(er instanceof Error)
+
+  options.chmod(p, 666, function (er2) {
     if (er2)
       cb(er2.code === "ENOENT" ? null : er)
     else
-      fs.stat(p, function(er3, stats) {
+      options.stat(p, function(er3, stats) {
         if (er3)
           cb(er3.code === "ENOENT" ? null : er)
         else if (stats.isDirectory())
-          rmdir(p, er, cb)
+          rmdir(p, options, er, cb)
         else
-          fs.unlink(p, cb)
+          options.unlink(p, cb)
       })
   })
 }
 
-function fixWinEPERMSync (p, er, cb) {
+function fixWinEPERMSync (p, options, er) {
+  assert(p)
+  assert(options)
+  if (er)
+    assert(er instanceof Error)
+
   try {
-    fs.chmodSync(p, 666)
+    options.chmodSync(p, 666)
   } catch (er2) {
-    if (er2.code !== "ENOENT")
+    if (er2.code === "ENOENT")
+      return
+    else
       throw er
   }
 
   try {
-    var stats = fs.statSync(p)
+    var stats = options.statSync(p)
   } catch (er3) {
-    if (er3 !== "ENOENT")
+    if (er3.code === "ENOENT")
+      return
+    else
       throw er
   }
 
   if (stats.isDirectory())
-    rmdirSync(p, er)
+    rmdirSync(p, options, er)
   else
-    fs.unlinkSync(p)
+    options.unlinkSync(p)
 }
 
-function rmdir (p, originalEr, cb) {
+function rmdir (p, options, originalEr, cb) {
+  assert(p)
+  assert(options)
+  if (originalEr)
+    assert(originalEr instanceof Error)
+  assert(typeof cb === 'function')
+
   // try to rmdir first, and only readdir on ENOTEMPTY or EEXIST (SunOS)
   // if we guessed wrong, and it's not a directory, then
   // raise the original error.
-  fs.rmdir(p, function (er) {
+  options.rmdir(p, function (er) {
     if (er && (er.code === "ENOTEMPTY" || er.code === "EEXIST" || er.code === 
"EPERM"))
-      rmkids(p, cb)
+      rmkids(p, options, cb)
     else if (er && er.code === "ENOTDIR")
       cb(originalEr)
     else
@@ -119,22 +172,26 @@
   })
 }
 
-function rmkids(p, cb) {
-  fs.readdir(p, function (er, files) {
+function rmkids(p, options, cb) {
+  assert(p)
+  assert(options)
+  assert(typeof cb === 'function')
+
+  options.readdir(p, function (er, files) {
     if (er)
       return cb(er)
     var n = files.length
     if (n === 0)
-      return fs.rmdir(p, cb)
+      return options.rmdir(p, cb)
     var errState
     files.forEach(function (f) {
-      rimraf(path.join(p, f), function (er) {
+      rimraf(path.join(p, f), options, function (er) {
         if (errState)
           return
         if (er)
           return cb(errState = er)
         if (--n === 0)
-          fs.rmdir(p, cb)
+          options.rmdir(p, cb)
       })
     })
   })
@@ -143,36 +200,49 @@
 // this looks simpler, and is strictly *faster*, but will
 // tie up the JavaScript thread and fail on excessively
 // deep directory trees.
-function rimrafSync (p) {
+function rimrafSync (p, options) {
+  options = options || {}
+  defaults(options)
+
+  assert(p)
+  assert(options)
+
   try {
-    fs.unlinkSync(p)
+    options.unlinkSync(p)
   } catch (er) {
     if (er.code === "ENOENT")
       return
     if (er.code === "EPERM")
-      return isWindows ? fixWinEPERMSync(p, er) : rmdirSync(p, er)
+      return isWindows ? fixWinEPERMSync(p, options, er) : rmdirSync(p, 
options, er)
     if (er.code !== "EISDIR")
       throw er
-    rmdirSync(p, er)
+    rmdirSync(p, options, er)
   }
 }
 
-function rmdirSync (p, originalEr) {
+function rmdirSync (p, options, originalEr) {
+  assert(p)
+  assert(options)
+  if (originalEr)
+    assert(originalEr instanceof Error)
+
   try {
-    fs.rmdirSync(p)
+    options.rmdirSync(p)
   } catch (er) {
     if (er.code === "ENOENT")
       return
     if (er.code === "ENOTDIR")
       throw originalEr
     if (er.code === "ENOTEMPTY" || er.code === "EEXIST" || er.code === "EPERM")
-      rmkidsSync(p)
+      rmkidsSync(p, options)
   }
 }
 
-function rmkidsSync (p) {
-  fs.readdirSync(p).forEach(function (f) {
-    rimrafSync(path.join(p, f))
+function rmkidsSync (p, options) {
+  assert(p)
+  assert(options)
+  options.readdirSync(p).forEach(function (f) {
+    rimrafSync(path.join(p, f), options)
   })
-  fs.rmdirSync(p)
+  options.rmdirSync(p, options)
 }
diff --git a/node_modules/rimraf/test/run.sh b/node_modules/rimraf/test/run.sh
index 598f016..653ff9b 100644
--- a/node_modules/rimraf/test/run.sh
+++ b/node_modules/rimraf/test/run.sh
@@ -1,10 +1,16 @@
 #!/bin/bash
 set -e
+code=0
 for i in test-*.js; do
   echo -n $i ...
   bash setup.sh
   node $i
-  ! [ -d target ]
-  echo "pass"
+  if [ -d target ]; then
+    echo "fail"
+    code=1
+  else
+    echo "pass"
+  fi
 done
 rm -rf target
+exit $code
diff --git a/node_modules/when/package.json b/node_modules/when/package.json
index f9142f5..d0bb968 100644
--- a/node_modules/when/package.json
+++ b/node_modules/when/package.json
@@ -90,6 +90,6 @@
   "dist": {
     "shasum": "921e13e7f813710a9ae91c5c0ddc5b19cf20f167"
   },
-  "_from": "when@",
+  "_from": "when@~3.1.0",
   "_resolved": "https://registry.npmjs.org/when/-/when-3.1.0.tgz";
 }

-- 
To view, visit https://gerrit.wikimedia.org/r/136162
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I8735984d093047127358bfb57eee99daf04fc8cb
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/services/ocg-collection
Gerrit-Branch: wmf-deploy
Gerrit-Owner: Mwalker <mwal...@wikimedia.org>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to