diff --git a/lib/ace/mode/html/saxparser.js b/lib/ace/mode/html/saxparser.js index 079f2e5c..eb4cadca 100644 --- a/lib/ace/mode/html/saxparser.js +++ b/lib/ace/mode/html/saxparser.js @@ -1,5 +1,6 @@ -define(function(require, exports, module){ -var req = require=(function(e,t,n){function i(n,s){if(!t[n]){if(!e[n]){var o=typeof require=="function"&&require;if(!s&&o)return o(n,!0);if(r)return r(n,!0);throw new Error("Cannot find module '"+n+"'")}var u=t[n]={exports:{}};e[n][0].call(u.exports,function(t){var r=e[n][1][t];return i(r?r:t)},u,u.exports)}return t[n].exports}var r=typeof require=="function"&&require;for(var s=0;s= 0; i--) { var node = this.elements[i]; @@ -126,6 +138,10 @@ ElementStack.prototype.remove = function(item) { this.elements.splice(this.elements.indexOf(item), 1); }; +/** + * Pops until an element with a given localName is popped + * @param {String} localName + */ ElementStack.prototype.popUntilPopped = function(localName) { var element; do { @@ -148,34 +164,73 @@ ElementStack.prototype.popUntilTableRowScopeMarker = function() { this.pop(); }; +/** + * + * @param {Number} index + * @return {StackItem} + */ ElementStack.prototype.item = function(index) { return this.elements[index]; }; +/** + * + * @param {StackItem} element + * @return {Boolean} + */ ElementStack.prototype.contains = function(element) { return this.elements.indexOf(element) !== -1; }; +/** + * + * @param {String} localName + * @return {Boolean} + */ ElementStack.prototype.inScope = function(localName) { return this._inScope(localName, isScopeMarker); }; +/** + * + * @param {String} localName + * @return {Boolean} + */ ElementStack.prototype.inListItemScope = function(localName) { return this._inScope(localName, isListItemScopeMarker); }; +/** + * + * @param {String} localName + * @return {Boolean} + */ ElementStack.prototype.inTableScope = function(localName) { return this._inScope(localName, isTableScopeMarker); }; +/** + * + * @param {String} localName + * @return {Boolean} + */ ElementStack.prototype.inButtonScope = function(localName) { return this._inScope(localName, isButtonScopeMarker); }; +/** + * + * @param {String} localName + * @return {Boolean} + */ ElementStack.prototype.inSelectScope = function(localName) { return this._inScope(localName, isSelectScopeMarker); }; +/** + * + * @return {Boolean} + */ ElementStack.prototype.hasNumberedHeaderElementInScope = function() { for (var i = this.elements.length - 1; i >= 0; i--) { var node = this.elements[i]; @@ -186,22 +241,34 @@ ElementStack.prototype.hasNumberedHeaderElementInScope = function() { } }; +/** + * + * @param {Object} element + * @return {StackItem} + */ ElementStack.prototype.furthestBlockForFormattingElement = function(element) { var furthestBlock = null; for (var i = this.elements.length - 1; i >= 0; i--) { var node = this.elements[i]; if (node.node === element) - return furthestBlock; + break; if (node.isSpecial()) furthestBlock = node; } + return furthestBlock; }; +/** + * + * @param {String} localName + * @return {Number} + */ ElementStack.prototype.findIndex = function(localName) { for (var i = this.elements.length - 1; i >= 0; i--) { if (this.elements[i].localName == localName) return i; } + return -1; }; ElementStack.prototype.remove_openElements_until = function(callback) { @@ -228,14 +295,11 @@ Object.defineProperty(ElementStack.prototype, 'length', { exports.ElementStack = ElementStack; -},{}],2:[function(req,module,exports){ -var entities = req('html5-entities'); -var InputStream = req('./InputStream').InputStream; - -/** - * Magic value for UTF-16 operations. - */ -var LEAD_OFFSET = (0xD800 - (0x10000 >> 10)); +}, +{}], +2:[function(_dereq_,module,exports){ +var entities = _dereq_('html5-entities'); +var InputStream = _dereq_('./InputStream').InputStream; var namedEntityPrefixes = {}; Object.keys(entities).forEach(function (entityKey) { @@ -306,11 +370,17 @@ EntityParser.consumeEntity = function(buffer, tokenizer, additionalAllowedCharac tokenizer._parseError("invalid-numeric-entity-replaced"); code = replacement; } - if (code > 0xFFFF && code < 0x10FFFF) { - var astralChar = ""; - astralChar += String.fromCharCode(LEAD_OFFSET + (code >> 10)); - astralChar += String.fromCharCode(0xDC00 + (code & 0x3FF)); - decodedCharacter = astralChar; + if (code > 0xFFFF && code <= 0x10FFFF) { + // we substract 0x10000 from cp to get a 20-bits number + // in the range 0..0xFFFF + code -= 0x10000; + // we add 0xD800 to the number formed by the first 10 bits + // to give the first byte + var first = ((0xffc00 & code) >> 10) + 0xD800; + // we add 0xDC00 to the number formed by the low 10 bits + // to give the second byte + var second = (0x3ff & code) + 0xDC00; + decodedCharacter = String.fromCharCode(first, second); } else decodedCharacter = String.fromCharCode(code); if (ch !== ';') { @@ -393,7 +463,7 @@ EntityParser.replaceEntityNumbers = function(c) { case 0x9E: return 0x017E; // LATIN SMALL LETTER Z WITH CARON case 0x9F: return 0x0178; // LATIN CAPITAL LETTER Y WITH DIAERESIS default: - if ((c >= 0xD800 && c <= 0xDFFF) || c >= 0x10FFFF) { /// @todo. The spec says > 0x10FFFF, not >=. Section 8.2.4.69. + if ((c >= 0xD800 && c <= 0xDFFF) || c > 0x10FFFF) { return 0xFFFD; } else if ((c >= 0x0001 && c <= 0x0008) || (c >= 0x000E && c <= 0x001F) || (c >= 0x007F && c <= 0x009F) || (c >= 0xFDD0 && c <= 0xFDEF) || @@ -413,7 +483,9 @@ EntityParser.replaceEntityNumbers = function(c) { exports.EntityParser = EntityParser; -},{"./InputStream":3,"html5-entities":12}],3:[function(req,module,exports){ +}, +{"./InputStream":3,"html5-entities":12}], +3:[function(_dereq_,module,exports){ // FIXME convert CR to LF http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#input-stream function InputStream() { this.data = ''; @@ -440,7 +512,10 @@ InputStream.prototype = { if(this.start >= this.data.length) { return InputStream.EOF; } - return this.data[this.start++]; + var ch = this.data[this.start++]; + if (ch === '\r') + ch = '\n'; + return ch; }, advance: function(amount) { this.start += amount; @@ -477,7 +552,7 @@ InputStream.prototype = { } else if(m = new RegExp(re + (this.eof ? "|$" : "")).exec(s)) { var t = this.data.slice(this.start, this.start + m.index); this.advance(m.index); - return t.toString(); + return t.replace(/\r/g, '\n').replace(/\n{2,}/g, '\n'); } else { throw InputStream.DRAIN; } @@ -523,7 +598,9 @@ InputStream.prototype = { exports.InputStream = InputStream; -},{}],4:[function(req,module,exports){ +}, +{}], +4:[function(_dereq_,module,exports){ var SpecialElements = { "http://www.w3.org/1999/xhtml": [ 'address', @@ -704,9 +781,11 @@ StackItem.prototype.isMathMLTextIntegrationPoint = function() { exports.StackItem = StackItem; -},{}],5:[function(req,module,exports){ -var InputStream = req('./InputStream').InputStream; -var EntityParser = req('./EntityParser').EntityParser; +}, +{}], +5:[function(_dereq_,module,exports){ +var InputStream = _dereq_('./InputStream').InputStream; +var EntityParser = _dereq_('./EntityParser').EntityParser; function isWhitespace(c){ return c === " " || c === "\n" || c === "\t" || c === "\r" || c === "\f"; @@ -2255,19 +2334,33 @@ Tokenizer.prototype.tokenize = function(source) { } }; +Object.defineProperty(Tokenizer.prototype, 'lineNumber', { + get: function() { + return this._inputStream.location().line; + } +}); + +Object.defineProperty(Tokenizer.prototype, 'columnNumber', { + get: function() { + return this._inputStream.location().column; + } +}); + exports.Tokenizer = Tokenizer; -},{"./EntityParser":2,"./InputStream":3}],6:[function(req,module,exports){ -(function(){var assert = req('assert'); +}, +{"./EntityParser":2,"./InputStream":3}], +6:[function(_dereq_,module,exports){ +var assert = _dereq_('assert'); -var messages = req('./messages.json'); -var constants = req('./constants'); +var messages = _dereq_('./messages.json'); +var constants = _dereq_('./constants'); -var EventEmitter = req('events').EventEmitter; +var EventEmitter = _dereq_('events').EventEmitter; -var Tokenizer = req('./Tokenizer').Tokenizer; -var ElementStack = req('./ElementStack').ElementStack; -var StackItem = req('./StackItem').StackItem; +var Tokenizer = _dereq_('./Tokenizer').Tokenizer; +var ElementStack = _dereq_('./ElementStack').ElementStack; +var StackItem = _dereq_('./StackItem').StackItem; var Marker = {}; @@ -2372,7 +2465,6 @@ function TreeBuilder() { this.redirectAttachToFosterParent = false; this.selfClosingFlagAcknowledged = false; this.context = ""; - this.firstStartTag = false; this.pendingTableCharacters = []; this.shouldSkipLeadingNewline = false; @@ -2421,11 +2513,7 @@ function TreeBuilder() { } }, startTagHtml: function(name, attributes) { - if (!tree.firstStartTag && name == 'html') { - tree.parseError('non-html-root'); - } - tree.addAttributesToElement(tree.openElements.rootNode, attributes); - tree.firstStartTag = false; + modes.inBody.startTagHtml(name, attributes); } }; @@ -2606,7 +2694,6 @@ function TreeBuilder() { }; modes.beforeHTML.startTagHtml = function(name, attributes, selfClosing) { - tree.firstStartTag = true; tree.insertHtmlElement(attributes); tree.setInsertionMode('beforeHead'); }; @@ -2815,11 +2902,10 @@ function TreeBuilder() { style: 'startTagNoFramesStyle', noscript: 'startTagNoScript', noframes: 'startTagNoFramesStyle', - base: 'startTagBaseLinkCommand', - basefont: 'startTagBaseLinkCommand', - bgsound: 'startTagBaseLinkCommand', - command: 'startTagBaseLinkCommand', //FIXME drop command tag? - link: 'startTagBaseLinkCommand', + base: 'startTagBaseBasefontBgsoundLink', + basefont: 'startTagBaseBasefontBgsoundLink', + bgsound: 'startTagBaseBasefontBgsoundLink', + link: 'startTagBaseBasefontBgsoundLink', meta: 'startTagMeta', "-default": 'startTagOther' }; @@ -2885,7 +2971,7 @@ function TreeBuilder() { tree.setInsertionMode('text'); }; - modes.inHead.startTagBaseLinkCommand = function(name, attributes) { + modes.inHead.startTagBaseBasefontBgsoundLink = function(name, attributes) { tree.insertSelfClosingElement(name, attributes); }; @@ -3015,7 +3101,6 @@ function TreeBuilder() { base: 'startTagProcessInHead', basefont: 'startTagProcessInHead', bgsound: 'startTagProcessInHead', - command: 'startTagProcessInHead', link: 'startTagProcessInHead', meta: 'startTagProcessInHead', noframes: 'startTagProcessInHead', @@ -3196,6 +3281,11 @@ function TreeBuilder() { tree.framesetOk = false; }; + modes.inBody.startTagHtml = function(name, attributes) { + tree.parseError('non-html-root'); + tree.addAttributesToElement(tree.openElements.rootNode, attributes); + }; + modes.inBody.startTagProcessInHead = function(name, attributes) { modes.inHead.processStartTag(name, attributes); }; @@ -3560,7 +3650,7 @@ function TreeBuilder() { } else { tree.generateImpliedEndTags('p'); if (tree.currentStackItem().localName != 'p') - tree.parseError('unexpected-end-tag', {name: 'p'}); + tree.parseError('unexpected-implied-end-tag', {name: 'p'}); tree.openElements.popUntilPopped(name); } }; @@ -3988,10 +4078,6 @@ function TreeBuilder() { modes.inHead.processComment(data); }; - modes.inHeadNoscript.startTagHtml = function(name, attributes) { - modes.inBody.processStartTag(name, attributes); - }; - modes.inHeadNoscript.startTagBasefontBgsoundLinkMetaNoframesStyle = function(name, attributes) { modes.inHead.processStartTag(name, attributes); }; @@ -4683,10 +4769,6 @@ function TreeBuilder() { tree.parseError('expected-eof-but-got-char'); }; - modes.afterAfterFrameset.startTagHtml = function(name, attributes) { - modes.inBody.processStartTag(name, attributes); - }; - modes.afterAfterFrameset.startTagNoFrames = function(name, attributes) { modes.inHead.processStartTag(name, attributes); }; @@ -4946,10 +5028,18 @@ TreeBuilder.prototype.processToken = function(token) { } }; +/** + * + * @return {Boolean} + */ TreeBuilder.prototype.isCdataSectionAllowed = function() { return this.openElements.length > 0 && this.currentStackItem().isForeign(); }; +/** + * + * @return {Boolean} + */ TreeBuilder.prototype.isSelfClosingFlagAcknowledged = function() { return this.selfClosingFlagAcknowledged; }; @@ -5062,7 +5152,7 @@ TreeBuilder.prototype.popElement = function() { /** * Returns true if redirect is required and current open element causes foster parenting - * @return {*} + * @return {Boolean} */ TreeBuilder.prototype.shouldFosterParent = function() { return this.redirectAttachToFosterParent && this.currentStackItem().isFosterParenting(); @@ -5118,6 +5208,10 @@ TreeBuilder.prototype.reconstructActiveFormattingElements = function() { }; +/** + * + * @param {StackItem} item + */ TreeBuilder.prototype.ensureNoahsArkCondition = function(item) { var kNoahsArkCapacity = 3; if (this.activeFormattingElements.length < kNoahsArkCapacity) @@ -5160,11 +5254,19 @@ TreeBuilder.prototype.ensureNoahsArkCondition = function(item) { this.removeElementFromActiveFormattingElements(candidates[i]); }; +/** + * + * @param {StackItem} item + */ TreeBuilder.prototype.appendElementToActiveFormattingElements = function(item) { this.ensureNoahsArkCondition(item); this.activeFormattingElements.push(item); }; +/** + * + * @param {StackItem} item + */ TreeBuilder.prototype.removeElementFromActiveFormattingElements = function(item) { var index = this.activeFormattingElements.indexOf(item); if (index >= 0) @@ -5180,12 +5282,12 @@ TreeBuilder.prototype.elementInActiveFormattingElements = function(name) { return false; }; -TreeBuilder.prototype.reparentChildren = function(oldParent, newParent) { - throw new Error("Not implemented"); +TreeBuilder.prototype.clearActiveFormattingElements = function() { + while (!(this.activeFormattingElements.length === 0 || this.activeFormattingElements.pop() == Marker)); }; -TreeBuilder.prototype.clearActiveFormattingElements = function() { - while (!(this.activeFormattingElements.length === 0 || this.activeFormattingElements.pop() == Marker)); +TreeBuilder.prototype.reparentChildren = function(oldParent, newParent) { + throw new Error("Not implemented"); }; /** @@ -5204,10 +5306,9 @@ TreeBuilder.prototype.setFragmentContext = function(context) { /** * * @param {String} code - * @param {Object} args - * @param isWarning + * @param {Object} [args] */ -TreeBuilder.prototype.parseError = function(code, args, isWarning) { +TreeBuilder.prototype.parseError = function(code, args) { // FIXME: this.errors.push([this.tokenizer.position, code, data]); if (!this.errorHandler) return; @@ -5321,8 +5422,9 @@ function formatMessage(format, args) { exports.TreeBuilder = TreeBuilder; -})() -},{"./ElementStack":1,"./StackItem":4,"./Tokenizer":5,"./constants":7,"./messages.json":8,"assert":13,"events":14}],7:[function(req,module,exports){ +}, +{"./ElementStack":1,"./StackItem":4,"./Tokenizer":5,"./constants":7,"./messages.json":8,"assert":13,"events":16}], +7:[function(_dereq_,module,exports){ exports.SVGTagMap = { "altglyph": "altGlyph", "altglyphdef": "altGlyphDef", @@ -5445,7 +5547,9 @@ exports.ForeignAttributeMap = { "xmlns": {prefix: null, localName: "xmlns", namespaceURI: "http://www.w3.org/2000/xmlns/"}, "xmlns:xlink": {prefix: "xmlns", localName: "xlink", namespaceURI: "http://www.w3.org/2000/xmlns/"}, }; -},{}],8:[function(req,module,exports){ +}, +{}], +8:[function(_dereq_,module,exports){ module.exports={ "null-character": "Null character in input stream, replaced with U+FFFD.", @@ -5589,6 +5693,8 @@ module.exports={ "Unexpected start tag head in existing head. Ignored.", "unexpected-end-tag": "Unexpected end tag ({name}). Ignored.", + "unexpected-implied-end-tag": + "End tag {name} implied, but there were open elements.", "unexpected-start-tag-out-of-my-head": "Unexpected start tag ({name}) that can be in head. Moved.", "unexpected-start-tag": @@ -5702,10 +5808,12 @@ module.exports={ "unexpected-start-tag-in-table": "Unexpected {name}. Expected table content." } -},{}],"DaboPu":[function(req,module,exports){ -var SAXTreeBuilder = req('./SAXTreeBuilder').SAXTreeBuilder; -var Tokenizer = req('../Tokenizer').Tokenizer; -var TreeParser = req('./TreeParser').TreeParser; +}, +{}], +9:[function(_dereq_,module,exports){ +var SAXTreeBuilder = _dereq_('./SAXTreeBuilder').SAXTreeBuilder; +var Tokenizer = _dereq_('../Tokenizer').Tokenizer; +var TreeParser = _dereq_('./TreeParser').TreeParser; function SAXParser() { this.contentHandler = null; @@ -5754,9 +5862,11 @@ Object.defineProperty(SAXParser.prototype, 'errorHandler', { exports.SAXParser = SAXParser; -},{"../Tokenizer":5,"./SAXTreeBuilder":10,"./TreeParser":11}],10:[function(req,module,exports){ -var util = req('util'); -var TreeBuilder = req('../TreeBuilder').TreeBuilder; +}, +{"../Tokenizer":5,"./SAXTreeBuilder":10,"./TreeParser":11}], +10:[function(_dereq_,module,exports){ +var util = _dereq_('util'); +var TreeBuilder = _dereq_('../TreeBuilder').TreeBuilder; function SAXTreeBuilder() { TreeBuilder.call(this); @@ -5765,28 +5875,33 @@ function SAXTreeBuilder() { util.inherits(SAXTreeBuilder, TreeBuilder); SAXTreeBuilder.prototype.start = function(tokenizer) { - this.document = new Document(); + this.document = new Document(this.tokenizer); +}; + +SAXTreeBuilder.prototype.end = function() { + this.document.endLocator = this.tokenizer; }; SAXTreeBuilder.prototype.insertDoctype = function(name, publicId, systemId) { - var doctype = new DTD(name, publicId, systemId); + var doctype = new DTD(this.tokenizer, name, publicId, systemId); + doctype.endLocator = this.tokenizer; this.document.appendChild(doctype); }; SAXTreeBuilder.prototype.createElement = function(namespaceURI, localName, attributes) { - var element = new Element(namespaceURI, localName, localName, attributes); + var element = new Element(this.tokenizer, namespaceURI, localName, localName, attributes || []); return element; }; SAXTreeBuilder.prototype.insertComment = function(data, parent) { if (!parent) parent = this.currentStackItem(); - var comment = new Comment(data); + var comment = new Comment(this.tokenizer, data); parent.appendChild(comment); }; SAXTreeBuilder.prototype.appendCharacters = function(parent, data) { - var text = new Characters(data); + var text = new Characters(this.tokenizer, data); parent.appendChild(text); }; @@ -5798,7 +5913,7 @@ SAXTreeBuilder.prototype.insertText = function(data) { if (tableIndex === 0) { return this.appendCharacters(table, data); } - var text = new Characters(data); + var text = new Characters(this.tokenizer, data); var parent = table.parentNode; if (parent) { parent.insertBetween(text, table.previousSibling, table); @@ -5904,7 +6019,14 @@ var NodeType = { * @version $Id$ * @author hsivonen */ -function Node() { +function Node(locator) { + if (!locator) { + this.columnNumber = -1; + this.lineNumber = -1; + } else { + this.columnNumber = locator.columnNumber; + this.lineNumber = locator.lineNumber; + } this.parentNode = null; this.nextSibling = null; this.firstChild = null; @@ -5959,9 +6081,10 @@ Object.defineProperty(Node.prototype, 'previousSibling', { }); -function ParentNode() { - Node.call(this); +function ParentNode(locator) { + Node.call(this, locator); this.lastChild = null; + this._endLocator = null; } ParentNode.prototype = Object.create(Node.prototype); @@ -6083,13 +6206,25 @@ ParentNode.prototype.removeChild = function(node) { return node; }; +Object.defineProperty(ParentNode.prototype, 'endLocator', { + get: function() { + return this._endLocator; + }, + set: function(endLocator) { + this._endLocator = { + lineNumber: endLocator.lineNumber, + columnNumber: endLocator.columnNumber + }; + } +}); + /** * A document. * @version $Id$ * @author hsivonen */ -function Document () { - Node.call(this); +function Document (locator) { + ParentNode.call(this, locator); this.nodeType = NodeType.DOCUMENT; } @@ -6107,7 +6242,7 @@ Document.prototype.visit = function(treeParser) { * @see nu.validator.saxtree.Node#revisit(nu.validator.saxtree.TreeParser) */ Document.prototype.revisit = function(treeParser) { - treeParser.endDocument(); + treeParser.endDocument(this.endLocator); }; /** @@ -6121,7 +6256,7 @@ Document.prototype.revisit = function(treeParser) { * The constructor. */ function DocumentFragment() { - ParentNode.call(this); + ParentNode.call(this, new Locator()); this.nodeType = NodeType.DOCUMENT_FRAGMENT; } @@ -6139,9 +6274,8 @@ DocumentFragment.prototype.visit = function(treeParser) { * @version $Id$ * @author hsivonen */ -function Element(uri, localName, qName, atts, prefixMappings) { - ParentNode.call(this); - +function Element(locator, uri, localName, qName, atts, prefixMappings) { + ParentNode.call(this, locator); this.uri = uri; this.localName = localName; this.qName = qName; @@ -6171,11 +6305,11 @@ Element.prototype.visit = function(treeParser) { * @see nu.validator.saxtree.Node#revisit(nu.validator.saxtree.TreeParser) */ Element.prototype.revisit = function(treeParser) { - treeParser.endElement(this.uri, this.localName, this.qName); + treeParser.endElement(this.uri, this.localName, this.qName, this.endLocator); if (this.prefixMappings) { for (var key in prefixMappings) { var mapping = prefixMappings[key]; - treeParser.endPrefixMapping(mapping.getPrefix()); + treeParser.endPrefixMapping(mapping.getPrefix(), this.endLocator); } } }; @@ -6183,12 +6317,10 @@ Element.prototype.revisit = function(treeParser) { /** * The constructor. * @param locator the locator - * @param buf the buffer - * @param start the offset in the buffer - * @param length the length + * @param {String} data the buffer */ -function Characters(data){ - Node.call(this); +function Characters(locator, data){ + Node.call(this, locator); this.data = data; this.nodeType = NodeType.CHARACTERS; } @@ -6209,8 +6341,8 @@ Characters.prototype.visit = function (treeParser) { * @param start the offset * @param length the length */ -function IgnorableWhitespace(data) { - Node.call(this); +function IgnorableWhitespace(locator, data) { + Node.call(this, locator); this.data = data; this.nodeType = NodeType.IGNORABLE_WHITESPACE; } @@ -6239,8 +6371,8 @@ IgnorableWhitespace.prototype.visit = function(treeParser) { * @param start the offset * @param length the length */ -function Comment(data) { - Node.call(this); +function Comment(locator, data) { + Node.call(this, locator); this.data = data; this.nodeType = NodeType.COMMENT; } @@ -6264,8 +6396,8 @@ Comment.prototype.visit = function(treeParser) { * The constructor. * @param locator the locator */ -function CDATA() { - ParentNode.call(this); +function CDATA(locator) { + ParentNode.call(this, locator); this.nodeType = NodeType.CDATA; } @@ -6284,7 +6416,7 @@ CDATA.prototype.visit = function(treeParser) { * @see nu.validator.saxtree.Node#revisit(nu.validator.saxtree.TreeParser) */ CDATA.prototype.revisit = function(treeParser) { - treeParser.endCDATA(); + treeParser.endCDATA(this.endLocator); }; /** @@ -6429,7 +6561,9 @@ DTD.prototype.revisit = function(treeParser) { exports.SAXTreeBuilder = SAXTreeBuilder; -},{"../TreeBuilder":6,"util":15}],11:[function(req,module,exports){ +}, +{"../TreeBuilder":6,"util":20}], +11:[function(_dereq_,module,exports){ /** * A tree visitor that replays a tree as SAX events. * @version $Id$ @@ -6445,31 +6579,31 @@ exports.SAXTreeBuilder = SAXTreeBuilder; * may be null */ function TreeParser(contentHandler, lexicalHandler){ - - /** - * The content handler. - */ - this.contentHandler; - /** - * The lexical handler. - */ - this.lexicalHandler; + /** + * The content handler. + */ + this.contentHandler; - /** - * The current locator. - */ - this.locatorDelegate; + /** + * The lexical handler. + */ + this.lexicalHandler; - if (!contentHandler) { - throw new IllegalArgumentException("contentHandler was null."); - } - this.contentHandler = contentHandler; - if (!lexicalHandler) { - this.lexicalHandler = new NullLexicalHandler(); - } else { - this.lexicalHandler = lexicalHandler; - } + /** + * The current locator. + */ + this.locatorDelegate; + + if (!contentHandler) { + throw new IllegalArgumentException("contentHandler was null."); + } + this.contentHandler = contentHandler; + if (!lexicalHandler) { + this.lexicalHandler = new NullLexicalHandler(); + } else { + this.lexicalHandler = lexicalHandler; + } } /** @@ -6482,43 +6616,43 @@ function TreeParser(contentHandler, lexicalHandler){ * @throws SAXException */ TreeParser.prototype.parse = function(node) { - // this.contentHandler.setDocumentLocator(this); - var current = node; - var next; - for (;;) { - current.visit(this); - if ((next = current.firstChild) != null) { - current = next; - continue; - } - for (;;) { - current.revisit(this); - if (current == node) { - return; - } - if ((next = current.nextSibling) != null) { - current = next; - break; - } - current = current.parentNode; - } - } + this.contentHandler.documentLocator = this; + var current = node; + var next; + for (;;) { + current.visit(this); + if (next = current.firstChild) { + current = next; + continue; + } + for (;;) { + current.revisit(this); + if (current == node) { + return; + } + if (next = current.nextSibling) { + current = next; + break; + } + current = current.parentNode; + } + } }; /** * @see org.xml.sax.ContentHandler#characters(char[], int, int) */ TreeParser.prototype.characters = function(ch, start, length, locator) { - this.locatorDelegate = locator; - this.contentHandler.characters(ch, start, length); + this.locatorDelegate = locator; + this.contentHandler.characters(ch, start, length); }; /** * @see org.xml.sax.ContentHandler#endDocument() */ TreeParser.prototype.endDocument = function(locator) { - this.locatorDelegate = locator; - this.contentHandler.endDocument(); + this.locatorDelegate = locator; + this.contentHandler.endDocument(); }; /** @@ -6526,24 +6660,24 @@ TreeParser.prototype.endDocument = function(locator) { * java.lang.String, java.lang.String) */ TreeParser.prototype.endElement = function(uri, localName, qName, locator) { - this.locatorDelegate = locator; - this.contentHandler.endElement(uri, localName, qName); + this.locatorDelegate = locator; + this.contentHandler.endElement(uri, localName, qName); }; /** * @see org.xml.sax.ContentHandler#endPrefixMapping(java.lang.String) */ TreeParser.prototype.endPrefixMapping = function(prefix, locator) { - this.locatorDelegate = locator; - this.contentHandler.endPrefixMapping(prefix); + this.locatorDelegate = locator; + this.contentHandler.endPrefixMapping(prefix); }; /** * @see org.xml.sax.ContentHandler#ignorableWhitespace(char[], int, int) */ TreeParser.prototype.ignorableWhitespace = function(ch, start, length, locator) { - this.locatorDelegate = locator; - this.contentHandler.ignorableWhitespace(ch, start, length); + this.locatorDelegate = locator; + this.contentHandler.ignorableWhitespace(ch, start, length); }; /** @@ -6551,24 +6685,24 @@ TreeParser.prototype.ignorableWhitespace = function(ch, start, length, locator) * java.lang.String) */ TreeParser.prototype.processingInstruction = function(target, data, locator) { - this.locatorDelegate = locator; - this.contentHandler.processingInstruction(target, data); + this.locatorDelegate = locator; + this.contentHandler.processingInstruction(target, data); }; /** * @see org.xml.sax.ContentHandler#skippedEntity(java.lang.String) */ TreeParser.prototype.skippedEntity = function(name, locator) { - this.locatorDelegate = locator; - this.contentHandler.skippedEntity(name); + this.locatorDelegate = locator; + this.contentHandler.skippedEntity(name); }; /** * @see org.xml.sax.ContentHandler#startDocument() */ TreeParser.prototype.startDocument = function(locator) { - this.locatorDelegate = locator; - this.contentHandler.startDocument(); + this.locatorDelegate = locator; + this.contentHandler.startDocument(); }; /** @@ -6576,8 +6710,8 @@ TreeParser.prototype.startDocument = function(locator) { * java.lang.String, java.lang.String, org.xml.sax.Attributes) */ TreeParser.prototype.startElement = function(uri, localName, qName, atts, locator) { - this.locatorDelegate = locator; - this.contentHandler.startElement(uri, localName, qName, atts); + this.locatorDelegate = locator; + this.contentHandler.startElement(uri, localName, qName, atts); }; /** @@ -6585,48 +6719,48 @@ TreeParser.prototype.startElement = function(uri, localName, qName, atts, locato * java.lang.String) */ TreeParser.prototype.startPrefixMapping = function(prefix, uri, locator) { - this.locatorDelegate = locator; - this.contentHandler.startPrefixMapping(prefix, uri); + this.locatorDelegate = locator; + this.contentHandler.startPrefixMapping(prefix, uri); }; /** * @see org.xml.sax.ext.LexicalHandler#comment(char[], int, int) */ TreeParser.prototype.comment = function(ch, start, length, locator) { - this.locatorDelegate = locator; - this.lexicalHandler.comment(ch, start, length); + this.locatorDelegate = locator; + this.lexicalHandler.comment(ch, start, length); }; /** * @see org.xml.sax.ext.LexicalHandler#endCDATA() */ TreeParser.prototype.endCDATA = function(locator) { - this.locatorDelegate = locator; - this.lexicalHandler.endCDATA(); + this.locatorDelegate = locator; + this.lexicalHandler.endCDATA(); }; /** * @see org.xml.sax.ext.LexicalHandler#endDTD() */ TreeParser.prototype.endDTD = function(locator) { - this.locatorDelegate = locator; - this.lexicalHandler.endDTD(); + this.locatorDelegate = locator; + this.lexicalHandler.endDTD(); }; /** * @see org.xml.sax.ext.LexicalHandler#endEntity(java.lang.String) */ TreeParser.prototype.endEntity = function(name, locator) { - this.locatorDelegate = locator; - this.lexicalHandler.endEntity(name); + this.locatorDelegate = locator; + this.lexicalHandler.endEntity(name); }; /** * @see org.xml.sax.ext.LexicalHandler#startCDATA() */ TreeParser.prototype.startCDATA = function(locator) { - this.locatorDelegate = locator; - this.lexicalHandler.startCDATA(); + this.locatorDelegate = locator; + this.lexicalHandler.startCDATA(); }; /** @@ -6634,63 +6768,35 @@ TreeParser.prototype.startCDATA = function(locator) { * java.lang.String, java.lang.String) */ TreeParser.prototype.startDTD = function(name, publicId, systemId, locator) { - this.locatorDelegate = locator; - this.lexicalHandler.startDTD(name, publicId, systemId); + this.locatorDelegate = locator; + this.lexicalHandler.startDTD(name, publicId, systemId); }; /** * @see org.xml.sax.ext.LexicalHandler#startEntity(java.lang.String) */ TreeParser.prototype.startEntity = function(name, locator) { - this.locatorDelegate = locator; - this.lexicalHandler.startEntity(name); + this.locatorDelegate = locator; + this.lexicalHandler.startEntity(name); }; -// /** -// * @see org.xml.sax.Locator#getColumnNumber() -// */ -// public int getColumnNumber() { -// if (locatorDelegate == null) { -// return -1; -// } else { -// return locatorDelegate.getColumnNumber(); -// } -// } - -// /** -// * @see org.xml.sax.Locator#getLineNumber() -// */ -// public int getLineNumber() { -// if (locatorDelegate == null) { -// return -1; -// } else { -// return locatorDelegate.getLineNumber(); -// } -// } - -// /** -// * @see org.xml.sax.Locator#getPublicId() -// */ -// public String getPublicId() { -// if (locatorDelegate == null) { -// return null; -// } else { - -// return locatorDelegate.getPublicId(); -// } -// } - -// /** -// * @see org.xml.sax.Locator#getSystemId() -// */ -// public String getSystemId() { -// if (locatorDelegate == null) { -// return null; -// } else { -// return locatorDelegate.getSystemId(); -// } -// } +Object.defineProperty(TreeParser.prototype, 'columnNumber', { + get: function() { + if (!this.locatorDelegate) + return -1; + else + return this.locatorDelegate.columnNumber; + } +}); +Object.defineProperty(TreeParser.prototype, 'lineNumber', { + get: function() { + if (!this.locatorDelegate) + return -1; + else + return this.locatorDelegate.lineNumber; + } +}); /** * A lexical handler that does nothing. @@ -6712,675 +6818,58 @@ NullLexicalHandler.prototype.startEntity = function() {}; exports.TreeParser = TreeParser; -},{}],12:[function(req,module,exports){ +}, +{}], +12:[function(_dereq_,module,exports){ module.exports = { - "AElig": "\u00C6", - "AElig;": "\u00C6", - "AMP": "&", - "AMP;": "&", - "Aacute": "\u00C1", "Aacute;": "\u00C1", - "Abreve;": "\u0102", - "Acirc": "\u00C2", - "Acirc;": "\u00C2", - "Acy;": "\u0410", - "Afr;": "\u1D504", - "Agrave": "\u00C0", - "Agrave;": "\u00C0", - "Alpha;": "\u0391", - "Amacr;": "\u0100", - "And;": "\u2A53", - "Aogon;": "\u0104", - "Aopf;": "\u1D538", - "ApplyFunction;": "\u2061", - "Aring": "\u00C5", - "Aring;": "\u00C5", - "Ascr;": "\u1D49C", - "Assign;": "\u2254", - "Atilde": "\u00C3", - "Atilde;": "\u00C3", - "Auml": "\u00C4", - "Auml;": "\u00C4", - "Backslash;": "\u2216", - "Barv;": "\u2AE7", - "Barwed;": "\u2306", - "Bcy;": "\u0411", - "Because;": "\u2235", - "Bernoullis;": "\u212C", - "Beta;": "\u0392", - "Bfr;": "\u1D505", - "Bopf;": "\u1D539", - "Breve;": "\u02D8", - "Bscr;": "\u212C", - "Bumpeq;": "\u224E", - "CHcy;": "\u0427", - "COPY": "\u00A9", - "COPY;": "\u00A9", - "Cacute;": "\u0106", - "Cap;": "\u22D2", - "CapitalDifferentialD;": "\u2145", - "Cayleys;": "\u212D", - "Ccaron;": "\u010C", - "Ccedil": "\u00C7", - "Ccedil;": "\u00C7", - "Ccirc;": "\u0108", - "Cconint;": "\u2230", - "Cdot;": "\u010A", - "Cedilla;": "\u00B8", - "CenterDot;": "\u00B7", - "Cfr;": "\u212D", - "Chi;": "\u03A7", - "CircleDot;": "\u2299", - "CircleMinus;": "\u2296", - "CirclePlus;": "\u2295", - "CircleTimes;": "\u2297", - "ClockwiseContourIntegral;": "\u2232", - "CloseCurlyDoubleQuote;": "\u201D", - "CloseCurlyQuote;": "\u2019", - "Colon;": "\u2237", - "Colone;": "\u2A74", - "Congruent;": "\u2261", - "Conint;": "\u222F", - "ContourIntegral;": "\u222E", - "Copf;": "\u2102", - "Coproduct;": "\u2210", - "CounterClockwiseContourIntegral;": "\u2233", - "Cross;": "\u2A2F", - "Cscr;": "\u1D49E", - "Cup;": "\u22D3", - "CupCap;": "\u224D", - "DD;": "\u2145", - "DDotrahd;": "\u2911", - "DJcy;": "\u0402", - "DScy;": "\u0405", - "DZcy;": "\u040F", - "Dagger;": "\u2021", - "Darr;": "\u21A1", - "Dashv;": "\u2AE4", - "Dcaron;": "\u010E", - "Dcy;": "\u0414", - "Del;": "\u2207", - "Delta;": "\u0394", - "Dfr;": "\u1D507", - "DiacriticalAcute;": "\u00B4", - "DiacriticalDot;": "\u02D9", - "DiacriticalDoubleAcute;": "\u02DD", - "DiacriticalGrave;": "`", - "DiacriticalTilde;": "\u02DC", - "Diamond;": "\u22C4", - "DifferentialD;": "\u2146", - "Dopf;": "\u1D53B", - "Dot;": "\u00A8", - "DotDot;": "\u20DC", - "DotEqual;": "\u2250", - "DoubleContourIntegral;": "\u222F", - "DoubleDot;": "\u00A8", - "DoubleDownArrow;": "\u21D3", - "DoubleLeftArrow;": "\u21D0", - "DoubleLeftRightArrow;": "\u21D4", - "DoubleLeftTee;": "\u2AE4", - "DoubleLongLeftArrow;": "\u27F8", - "DoubleLongLeftRightArrow;": "\u27FA", - "DoubleLongRightArrow;": "\u27F9", - "DoubleRightArrow;": "\u21D2", - "DoubleRightTee;": "\u22A8", - "DoubleUpArrow;": "\u21D1", - "DoubleUpDownArrow;": "\u21D5", - "DoubleVerticalBar;": "\u2225", - "DownArrow;": "\u2193", - "DownArrowBar;": "\u2913", - "DownArrowUpArrow;": "\u21F5", - "DownBreve;": "\u0311", - "DownLeftRightVector;": "\u2950", - "DownLeftTeeVector;": "\u295E", - "DownLeftVector;": "\u21BD", - "DownLeftVectorBar;": "\u2956", - "DownRightTeeVector;": "\u295F", - "DownRightVector;": "\u21C1", - "DownRightVectorBar;": "\u2957", - "DownTee;": "\u22A4", - "DownTeeArrow;": "\u21A7", - "Downarrow;": "\u21D3", - "Dscr;": "\u1D49F", - "Dstrok;": "\u0110", - "ENG;": "\u014A", - "ETH": "\u00D0", - "ETH;": "\u00D0", - "Eacute": "\u00C9", - "Eacute;": "\u00C9", - "Ecaron;": "\u011A", - "Ecirc": "\u00CA", - "Ecirc;": "\u00CA", - "Ecy;": "\u042D", - "Edot;": "\u0116", - "Efr;": "\u1D508", - "Egrave": "\u00C8", - "Egrave;": "\u00C8", - "Element;": "\u2208", - "Emacr;": "\u0112", - "EmptySmallSquare;": "\u25FB", - "EmptyVerySmallSquare;": "\u25AB", - "Eogon;": "\u0118", - "Eopf;": "\u1D53C", - "Epsilon;": "\u0395", - "Equal;": "\u2A75", - "EqualTilde;": "\u2242", - "Equilibrium;": "\u21CC", - "Escr;": "\u2130", - "Esim;": "\u2A73", - "Eta;": "\u0397", - "Euml": "\u00CB", - "Euml;": "\u00CB", - "Exists;": "\u2203", - "ExponentialE;": "\u2147", - "Fcy;": "\u0424", - "Ffr;": "\u1D509", - "FilledSmallSquare;": "\u25FC", - "FilledVerySmallSquare;": "\u25AA", - "Fopf;": "\u1D53D", - "ForAll;": "\u2200", - "Fouriertrf;": "\u2131", - "Fscr;": "\u2131", - "GJcy;": "\u0403", - "GT": ">", - "GT;": ">", - "Gamma;": "\u0393", - "Gammad;": "\u03DC", - "Gbreve;": "\u011E", - "Gcedil;": "\u0122", - "Gcirc;": "\u011C", - "Gcy;": "\u0413", - "Gdot;": "\u0120", - "Gfr;": "\u1D50A", - "Gg;": "\u22D9", - "Gopf;": "\u1D53E", - "GreaterEqual;": "\u2265", - "GreaterEqualLess;": "\u22DB", - "GreaterFullEqual;": "\u2267", - "GreaterGreater;": "\u2AA2", - "GreaterLess;": "\u2277", - "GreaterSlantEqual;": "\u2A7E", - "GreaterTilde;": "\u2273", - "Gscr;": "\u1D4A2", - "Gt;": "\u226B", - "HARDcy;": "\u042A", - "Hacek;": "\u02C7", - "Hat;": "^", - "Hcirc;": "\u0124", - "Hfr;": "\u210C", - "HilbertSpace;": "\u210B", - "Hopf;": "\u210D", - "HorizontalLine;": "\u2500", - "Hscr;": "\u210B", - "Hstrok;": "\u0126", - "HumpDownHump;": "\u224E", - "HumpEqual;": "\u224F", - "IEcy;": "\u0415", - "IJlig;": "\u0132", - "IOcy;": "\u0401", - "Iacute": "\u00CD", - "Iacute;": "\u00CD", - "Icirc": "\u00CE", - "Icirc;": "\u00CE", - "Icy;": "\u0418", - "Idot;": "\u0130", - "Ifr;": "\u2111", - "Igrave": "\u00CC", - "Igrave;": "\u00CC", - "Im;": "\u2111", - "Imacr;": "\u012A", - "ImaginaryI;": "\u2148", - "Implies;": "\u21D2", - "Int;": "\u222C", - "Integral;": "\u222B", - "Intersection;": "\u22C2", - "InvisibleComma;": "\u2063", - "InvisibleTimes;": "\u2062", - "Iogon;": "\u012E", - "Iopf;": "\u1D540", - "Iota;": "\u0399", - "Iscr;": "\u2110", - "Itilde;": "\u0128", - "Iukcy;": "\u0406", - "Iuml": "\u00CF", - "Iuml;": "\u00CF", - "Jcirc;": "\u0134", - "Jcy;": "\u0419", - "Jfr;": "\u1D50D", - "Jopf;": "\u1D541", - "Jscr;": "\u1D4A5", - "Jsercy;": "\u0408", - "Jukcy;": "\u0404", - "KHcy;": "\u0425", - "KJcy;": "\u040C", - "Kappa;": "\u039A", - "Kcedil;": "\u0136", - "Kcy;": "\u041A", - "Kfr;": "\u1D50E", - "Kopf;": "\u1D542", - "Kscr;": "\u1D4A6", - "LJcy;": "\u0409", - "LT": "<", - "LT;": "<", - "Lacute;": "\u0139", - "Lambda;": "\u039B", - "Lang;": "\u27EA", - "Laplacetrf;": "\u2112", - "Larr;": "\u219E", - "Lcaron;": "\u013D", - "Lcedil;": "\u013B", - "Lcy;": "\u041B", - "LeftAngleBracket;": "\u27E8", - "LeftArrow;": "\u2190", - "LeftArrowBar;": "\u21E4", - "LeftArrowRightArrow;": "\u21C6", - "LeftCeiling;": "\u2308", - "LeftDoubleBracket;": "\u27E6", - "LeftDownTeeVector;": "\u2961", - "LeftDownVector;": "\u21C3", - "LeftDownVectorBar;": "\u2959", - "LeftFloor;": "\u230A", - "LeftRightArrow;": "\u2194", - "LeftRightVector;": "\u294E", - "LeftTee;": "\u22A3", - "LeftTeeArrow;": "\u21A4", - "LeftTeeVector;": "\u295A", - "LeftTriangle;": "\u22B2", - "LeftTriangleBar;": "\u29CF", - "LeftTriangleEqual;": "\u22B4", - "LeftUpDownVector;": "\u2951", - "LeftUpTeeVector;": "\u2960", - "LeftUpVector;": "\u21BF", - "LeftUpVectorBar;": "\u2958", - "LeftVector;": "\u21BC", - "LeftVectorBar;": "\u2952", - "Leftarrow;": "\u21D0", - "Leftrightarrow;": "\u21D4", - "LessEqualGreater;": "\u22DA", - "LessFullEqual;": "\u2266", - "LessGreater;": "\u2276", - "LessLess;": "\u2AA1", - "LessSlantEqual;": "\u2A7D", - "LessTilde;": "\u2272", - "Lfr;": "\u1D50F", - "Ll;": "\u22D8", - "Lleftarrow;": "\u21DA", - "Lmidot;": "\u013F", - "LongLeftArrow;": "\u27F5", - "LongLeftRightArrow;": "\u27F7", - "LongRightArrow;": "\u27F6", - "Longleftarrow;": "\u27F8", - "Longleftrightarrow;": "\u27FA", - "Longrightarrow;": "\u27F9", - "Lopf;": "\u1D543", - "LowerLeftArrow;": "\u2199", - "LowerRightArrow;": "\u2198", - "Lscr;": "\u2112", - "Lsh;": "\u21B0", - "Lstrok;": "\u0141", - "Lt;": "\u226A", - "Map;": "\u2905", - "Mcy;": "\u041C", - "MediumSpace;": "\u205F", - "Mellintrf;": "\u2133", - "Mfr;": "\u1D510", - "MinusPlus;": "\u2213", - "Mopf;": "\u1D544", - "Mscr;": "\u2133", - "Mu;": "\u039C", - "NJcy;": "\u040A", - "Nacute;": "\u0143", - "Ncaron;": "\u0147", - "Ncedil;": "\u0145", - "Ncy;": "\u041D", - "NegativeMediumSpace;": "\u200B", - "NegativeThickSpace;": "\u200B", - "NegativeThinSpace;": "\u200B", - "NegativeVeryThinSpace;": "\u200B", - "NestedGreaterGreater;": "\u226B", - "NestedLessLess;": "\u226A", - "NewLine;": "\u000A", - "Nfr;": "\u1D511", - "NoBreak;": "\u2060", - "NonBreakingSpace;": "\u00A0", - "Nopf;": "\u2115", - "Not;": "\u2AEC", - "NotCongruent;": "\u2262", - "NotCupCap;": "\u226D", - "NotDoubleVerticalBar;": "\u2226", - "NotElement;": "\u2209", - "NotEqual;": "\u2260", - "NotEqualTilde;": "\u2242\u0338", - "NotExists;": "\u2204", - "NotGreater;": "\u226F", - "NotGreaterEqual;": "\u2271", - "NotGreaterFullEqual;": "\u2267\u0338", - "NotGreaterGreater;": "\u226B\u0338", - "NotGreaterLess;": "\u2279", - "NotGreaterSlantEqual;": "\u2A7E\u0338", - "NotGreaterTilde;": "\u2275", - "NotHumpDownHump;": "\u224E\u0338", - "NotHumpEqual;": "\u224F\u0338", - "NotLeftTriangle;": "\u22EA", - "NotLeftTriangleBar;": "\u29CF\u0338", - "NotLeftTriangleEqual;": "\u22EC", - "NotLess;": "\u226E", - "NotLessEqual;": "\u2270", - "NotLessGreater;": "\u2278", - "NotLessLess;": "\u226A\u0338", - "NotLessSlantEqual;": "\u2A7D\u0338", - "NotLessTilde;": "\u2274", - "NotNestedGreaterGreater;": "\u2AA2\u0338", - "NotNestedLessLess;": "\u2AA1\u0338", - "NotPrecedes;": "\u2280", - "NotPrecedesEqual;": "\u2AAF\u0338", - "NotPrecedesSlantEqual;": "\u22E0", - "NotReverseElement;": "\u220C", - "NotRightTriangle;": "\u22EB", - "NotRightTriangleBar;": "\u29D0\u0338", - "NotRightTriangleEqual;": "\u22ED", - "NotSquareSubset;": "\u228F\u0338", - "NotSquareSubsetEqual;": "\u22E2", - "NotSquareSuperset;": "\u2290\u0338", - "NotSquareSupersetEqual;": "\u22E3", - "NotSubset;": "\u2282\u20D2", - "NotSubsetEqual;": "\u2288", - "NotSucceeds;": "\u2281", - "NotSucceedsEqual;": "\u2AB0\u0338", - "NotSucceedsSlantEqual;": "\u22E1", - "NotSucceedsTilde;": "\u227F\u0338", - "NotSuperset;": "\u2283\u20D2", - "NotSupersetEqual;": "\u2289", - "NotTilde;": "\u2241", - "NotTildeEqual;": "\u2244", - "NotTildeFullEqual;": "\u2247", - "NotTildeTilde;": "\u2249", - "NotVerticalBar;": "\u2224", - "Nscr;": "\u1D4A9", - "Ntilde": "\u00D1", - "Ntilde;": "\u00D1", - "Nu;": "\u039D", - "OElig;": "\u0152", - "Oacute": "\u00D3", - "Oacute;": "\u00D3", - "Ocirc": "\u00D4", - "Ocirc;": "\u00D4", - "Ocy;": "\u041E", - "Odblac;": "\u0150", - "Ofr;": "\u1D512", - "Ograve": "\u00D2", - "Ograve;": "\u00D2", - "Omacr;": "\u014C", - "Omega;": "\u03A9", - "Omicron;": "\u039F", - "Oopf;": "\u1D546", - "OpenCurlyDoubleQuote;": "\u201C", - "OpenCurlyQuote;": "\u2018", - "Or;": "\u2A54", - "Oscr;": "\u1D4AA", - "Oslash": "\u00D8", - "Oslash;": "\u00D8", - "Otilde": "\u00D5", - "Otilde;": "\u00D5", - "Otimes;": "\u2A37", - "Ouml": "\u00D6", - "Ouml;": "\u00D6", - "OverBar;": "\u203E", - "OverBrace;": "\u23DE", - "OverBracket;": "\u23B4", - "OverParenthesis;": "\u23DC", - "PartialD;": "\u2202", - "Pcy;": "\u041F", - "Pfr;": "\u1D513", - "Phi;": "\u03A6", - "Pi;": "\u03A0", - "PlusMinus;": "\u00B1", - "Poincareplane;": "\u210C", - "Popf;": "\u2119", - "Pr;": "\u2ABB", - "Precedes;": "\u227A", - "PrecedesEqual;": "\u2AAF", - "PrecedesSlantEqual;": "\u227C", - "PrecedesTilde;": "\u227E", - "Prime;": "\u2033", - "Product;": "\u220F", - "Proportion;": "\u2237", - "Proportional;": "\u221D", - "Pscr;": "\u1D4AB", - "Psi;": "\u03A8", - "QUOT": "\u0022", - "QUOT;": "\u0022", - "Qfr;": "\u1D514", - "Qopf;": "\u211A", - "Qscr;": "\u1D4AC", - "RBarr;": "\u2910", - "REG": "\u00AE", - "REG;": "\u00AE", - "Racute;": "\u0154", - "Rang;": "\u27EB", - "Rarr;": "\u21A0", - "Rarrtl;": "\u2916", - "Rcaron;": "\u0158", - "Rcedil;": "\u0156", - "Rcy;": "\u0420", - "Re;": "\u211C", - "ReverseElement;": "\u220B", - "ReverseEquilibrium;": "\u21CB", - "ReverseUpEquilibrium;": "\u296F", - "Rfr;": "\u211C", - "Rho;": "\u03A1", - "RightAngleBracket;": "\u27E9", - "RightArrow;": "\u2192", - "RightArrowBar;": "\u21E5", - "RightArrowLeftArrow;": "\u21C4", - "RightCeiling;": "\u2309", - "RightDoubleBracket;": "\u27E7", - "RightDownTeeVector;": "\u295D", - "RightDownVector;": "\u21C2", - "RightDownVectorBar;": "\u2955", - "RightFloor;": "\u230B", - "RightTee;": "\u22A2", - "RightTeeArrow;": "\u21A6", - "RightTeeVector;": "\u295B", - "RightTriangle;": "\u22B3", - "RightTriangleBar;": "\u29D0", - "RightTriangleEqual;": "\u22B5", - "RightUpDownVector;": "\u294F", - "RightUpTeeVector;": "\u295C", - "RightUpVector;": "\u21BE", - "RightUpVectorBar;": "\u2954", - "RightVector;": "\u21C0", - "RightVectorBar;": "\u2953", - "Rightarrow;": "\u21D2", - "Ropf;": "\u211D", - "RoundImplies;": "\u2970", - "Rrightarrow;": "\u21DB", - "Rscr;": "\u211B", - "Rsh;": "\u21B1", - "RuleDelayed;": "\u29F4", - "SHCHcy;": "\u0429", - "SHcy;": "\u0428", - "SOFTcy;": "\u042C", - "Sacute;": "\u015A", - "Sc;": "\u2ABC", - "Scaron;": "\u0160", - "Scedil;": "\u015E", - "Scirc;": "\u015C", - "Scy;": "\u0421", - "Sfr;": "\u1D516", - "ShortDownArrow;": "\u2193", - "ShortLeftArrow;": "\u2190", - "ShortRightArrow;": "\u2192", - "ShortUpArrow;": "\u2191", - "Sigma;": "\u03A3", - "SmallCircle;": "\u2218", - "Sopf;": "\u1D54A", - "Sqrt;": "\u221A", - "Square;": "\u25A1", - "SquareIntersection;": "\u2293", - "SquareSubset;": "\u228F", - "SquareSubsetEqual;": "\u2291", - "SquareSuperset;": "\u2290", - "SquareSupersetEqual;": "\u2292", - "SquareUnion;": "\u2294", - "Sscr;": "\u1D4AE", - "Star;": "\u22C6", - "Sub;": "\u22D0", - "Subset;": "\u22D0", - "SubsetEqual;": "\u2286", - "Succeeds;": "\u227B", - "SucceedsEqual;": "\u2AB0", - "SucceedsSlantEqual;": "\u227D", - "SucceedsTilde;": "\u227F", - "SuchThat;": "\u220B", - "Sum;": "\u2211", - "Sup;": "\u22D1", - "Superset;": "\u2283", - "SupersetEqual;": "\u2287", - "Supset;": "\u22D1", - "THORN": "\u00DE", - "THORN;": "\u00DE", - "TRADE;": "\u2122", - "TSHcy;": "\u040B", - "TScy;": "\u0426", - "Tab;": "\u0009", - "Tau;": "\u03A4", - "Tcaron;": "\u0164", - "Tcedil;": "\u0162", - "Tcy;": "\u0422", - "Tfr;": "\u1D517", - "Therefore;": "\u2234", - "Theta;": "\u0398", - "ThickSpace;": "\u205F\u200A", - "ThinSpace;": "\u2009", - "Tilde;": "\u223C", - "TildeEqual;": "\u2243", - "TildeFullEqual;": "\u2245", - "TildeTilde;": "\u2248", - "Topf;": "\u1D54B", - "TripleDot;": "\u20DB", - "Tscr;": "\u1D4AF", - "Tstrok;": "\u0166", - "Uacute": "\u00DA", - "Uacute;": "\u00DA", - "Uarr;": "\u219F", - "Uarrocir;": "\u2949", - "Ubrcy;": "\u040E", - "Ubreve;": "\u016C", - "Ucirc": "\u00DB", - "Ucirc;": "\u00DB", - "Ucy;": "\u0423", - "Udblac;": "\u0170", - "Ufr;": "\u1D518", - "Ugrave": "\u00D9", - "Ugrave;": "\u00D9", - "Umacr;": "\u016A", - "UnderBar;": "_", - "UnderBrace;": "\u23DF", - "UnderBracket;": "\u23B5", - "UnderParenthesis;": "\u23DD", - "Union;": "\u22C3", - "UnionPlus;": "\u228E", - "Uogon;": "\u0172", - "Uopf;": "\u1D54C", - "UpArrow;": "\u2191", - "UpArrowBar;": "\u2912", - "UpArrowDownArrow;": "\u21C5", - "UpDownArrow;": "\u2195", - "UpEquilibrium;": "\u296E", - "UpTee;": "\u22A5", - "UpTeeArrow;": "\u21A5", - "Uparrow;": "\u21D1", - "Updownarrow;": "\u21D5", - "UpperLeftArrow;": "\u2196", - "UpperRightArrow;": "\u2197", - "Upsi;": "\u03D2", - "Upsilon;": "\u03A5", - "Uring;": "\u016E", - "Uscr;": "\u1D4B0", - "Utilde;": "\u0168", - "Uuml": "\u00DC", - "Uuml;": "\u00DC", - "VDash;": "\u22AB", - "Vbar;": "\u2AEB", - "Vcy;": "\u0412", - "Vdash;": "\u22A9", - "Vdashl;": "\u2AE6", - "Vee;": "\u22C1", - "Verbar;": "\u2016", - "Vert;": "\u2016", - "VerticalBar;": "\u2223", - "VerticalLine;": "|", - "VerticalSeparator;": "\u2758", - "VerticalTilde;": "\u2240", - "VeryThinSpace;": "\u200A", - "Vfr;": "\u1D519", - "Vopf;": "\u1D54D", - "Vscr;": "\u1D4B1", - "Vvdash;": "\u22AA", - "Wcirc;": "\u0174", - "Wedge;": "\u22C0", - "Wfr;": "\u1D51A", - "Wopf;": "\u1D54E", - "Wscr;": "\u1D4B2", - "Xfr;": "\u1D51B", - "Xi;": "\u039E", - "Xopf;": "\u1D54F", - "Xscr;": "\u1D4B3", - "YAcy;": "\u042F", - "YIcy;": "\u0407", - "YUcy;": "\u042E", - "Yacute": "\u00DD", - "Yacute;": "\u00DD", - "Ycirc;": "\u0176", - "Ycy;": "\u042B", - "Yfr;": "\u1D51C", - "Yopf;": "\u1D550", - "Yscr;": "\u1D4B4", - "Yuml;": "\u0178", - "ZHcy;": "\u0416", - "Zacute;": "\u0179", - "Zcaron;": "\u017D", - "Zcy;": "\u0417", - "Zdot;": "\u017B", - "ZeroWidthSpace;": "\u200B", - "Zeta;": "\u0396", - "Zfr;": "\u2128", - "Zopf;": "\u2124", - "Zscr;": "\u1D4B5", - "aacute": "\u00E1", + "Aacute": "\u00C1", "aacute;": "\u00E1", + "aacute": "\u00E1", + "Abreve;": "\u0102", "abreve;": "\u0103", "ac;": "\u223E", - "acE;": "\u223E\u0333", "acd;": "\u223F", - "acirc": "\u00E2", + "acE;": "\u223E\u0333", + "Acirc;": "\u00C2", + "Acirc": "\u00C2", "acirc;": "\u00E2", - "acute": "\u00B4", + "acirc": "\u00E2", "acute;": "\u00B4", + "acute": "\u00B4", + "Acy;": "\u0410", "acy;": "\u0430", - "aelig": "\u00E6", + "AElig;": "\u00C6", + "AElig": "\u00C6", "aelig;": "\u00E6", + "aelig": "\u00E6", "af;": "\u2061", - "afr;": "\u1D51E", - "agrave": "\u00E0", + "Afr;": "\uD835\uDD04", + "afr;": "\uD835\uDD1E", + "Agrave;": "\u00C0", + "Agrave": "\u00C0", "agrave;": "\u00E0", + "agrave": "\u00E0", "alefsym;": "\u2135", "aleph;": "\u2135", + "Alpha;": "\u0391", "alpha;": "\u03B1", + "Amacr;": "\u0100", "amacr;": "\u0101", "amalg;": "\u2A3F", - "amp": "&", - "amp;": "&", - "and;": "\u2227", + "amp;": "\u0026", + "amp": "\u0026", + "AMP;": "\u0026", + "AMP": "\u0026", "andand;": "\u2A55", + "And;": "\u2A53", + "and;": "\u2227", "andd;": "\u2A5C", "andslope;": "\u2A58", "andv;": "\u2A5A", "ang;": "\u2220", "ange;": "\u29A4", "angle;": "\u2220", - "angmsd;": "\u2221", "angmsdaa;": "\u29A8", "angmsdab;": "\u29A9", "angmsdac;": "\u29AA", @@ -7389,57 +6878,76 @@ module.exports = { "angmsdaf;": "\u29AD", "angmsdag;": "\u29AE", "angmsdah;": "\u29AF", + "angmsd;": "\u2221", "angrt;": "\u221F", "angrtvb;": "\u22BE", "angrtvbd;": "\u299D", "angsph;": "\u2222", "angst;": "\u00C5", "angzarr;": "\u237C", + "Aogon;": "\u0104", "aogon;": "\u0105", - "aopf;": "\u1D552", + "Aopf;": "\uD835\uDD38", + "aopf;": "\uD835\uDD52", + "apacir;": "\u2A6F", "ap;": "\u2248", "apE;": "\u2A70", - "apacir;": "\u2A6F", "ape;": "\u224A", "apid;": "\u224B", "apos;": "\u0027", + "ApplyFunction;": "\u2061", "approx;": "\u2248", "approxeq;": "\u224A", - "aring": "\u00E5", + "Aring;": "\u00C5", + "Aring": "\u00C5", "aring;": "\u00E5", - "ascr;": "\u1D4B6", - "ast;": "*", + "aring": "\u00E5", + "Ascr;": "\uD835\uDC9C", + "ascr;": "\uD835\uDCB6", + "Assign;": "\u2254", + "ast;": "\u002A", "asymp;": "\u2248", "asympeq;": "\u224D", - "atilde": "\u00E3", + "Atilde;": "\u00C3", + "Atilde": "\u00C3", "atilde;": "\u00E3", - "auml": "\u00E4", + "atilde": "\u00E3", + "Auml;": "\u00C4", + "Auml": "\u00C4", "auml;": "\u00E4", + "auml": "\u00E4", "awconint;": "\u2233", "awint;": "\u2A11", - "bNot;": "\u2AED", "backcong;": "\u224C", "backepsilon;": "\u03F6", "backprime;": "\u2035", "backsim;": "\u223D", "backsimeq;": "\u22CD", + "Backslash;": "\u2216", + "Barv;": "\u2AE7", "barvee;": "\u22BD", "barwed;": "\u2305", + "Barwed;": "\u2306", "barwedge;": "\u2305", "bbrk;": "\u23B5", "bbrktbrk;": "\u23B6", "bcong;": "\u224C", + "Bcy;": "\u0411", "bcy;": "\u0431", "bdquo;": "\u201E", "becaus;": "\u2235", "because;": "\u2235", + "Because;": "\u2235", "bemptyv;": "\u29B0", "bepsi;": "\u03F6", "bernou;": "\u212C", + "Bernoullis;": "\u212C", + "Beta;": "\u0392", "beta;": "\u03B2", "beth;": "\u2136", "between;": "\u226C", - "bfr;": "\u1D51F", + "Bfr;": "\uD835\uDD05", + "bfr;": "\uD835\uDD1F", "bigcap;": "\u22C2", "bigcirc;": "\u25EF", "bigcup;": "\u22C3", @@ -7467,138 +6975,177 @@ module.exports = { "block;": "\u2588", "bne;": "\u003D\u20E5", "bnequiv;": "\u2261\u20E5", + "bNot;": "\u2AED", "bnot;": "\u2310", - "bopf;": "\u1D553", + "Bopf;": "\uD835\uDD39", + "bopf;": "\uD835\uDD53", "bot;": "\u22A5", "bottom;": "\u22A5", "bowtie;": "\u22C8", - "boxDL;": "\u2557", - "boxDR;": "\u2554", - "boxDl;": "\u2556", - "boxDr;": "\u2553", - "boxH;": "\u2550", - "boxHD;": "\u2566", - "boxHU;": "\u2569", - "boxHd;": "\u2564", - "boxHu;": "\u2567", - "boxUL;": "\u255D", - "boxUR;": "\u255A", - "boxUl;": "\u255C", - "boxUr;": "\u2559", - "boxV;": "\u2551", - "boxVH;": "\u256C", - "boxVL;": "\u2563", - "boxVR;": "\u2560", - "boxVh;": "\u256B", - "boxVl;": "\u2562", - "boxVr;": "\u255F", "boxbox;": "\u29C9", - "boxdL;": "\u2555", - "boxdR;": "\u2552", "boxdl;": "\u2510", + "boxdL;": "\u2555", + "boxDl;": "\u2556", + "boxDL;": "\u2557", "boxdr;": "\u250C", + "boxdR;": "\u2552", + "boxDr;": "\u2553", + "boxDR;": "\u2554", "boxh;": "\u2500", - "boxhD;": "\u2565", - "boxhU;": "\u2568", + "boxH;": "\u2550", "boxhd;": "\u252C", + "boxHd;": "\u2564", + "boxhD;": "\u2565", + "boxHD;": "\u2566", "boxhu;": "\u2534", + "boxHu;": "\u2567", + "boxhU;": "\u2568", + "boxHU;": "\u2569", "boxminus;": "\u229F", "boxplus;": "\u229E", "boxtimes;": "\u22A0", - "boxuL;": "\u255B", - "boxuR;": "\u2558", "boxul;": "\u2518", + "boxuL;": "\u255B", + "boxUl;": "\u255C", + "boxUL;": "\u255D", "boxur;": "\u2514", + "boxuR;": "\u2558", + "boxUr;": "\u2559", + "boxUR;": "\u255A", "boxv;": "\u2502", - "boxvH;": "\u256A", - "boxvL;": "\u2561", - "boxvR;": "\u255E", + "boxV;": "\u2551", "boxvh;": "\u253C", + "boxvH;": "\u256A", + "boxVh;": "\u256B", + "boxVH;": "\u256C", "boxvl;": "\u2524", + "boxvL;": "\u2561", + "boxVl;": "\u2562", + "boxVL;": "\u2563", "boxvr;": "\u251C", + "boxvR;": "\u255E", + "boxVr;": "\u255F", + "boxVR;": "\u2560", "bprime;": "\u2035", "breve;": "\u02D8", - "brvbar": "\u00A6", + "Breve;": "\u02D8", "brvbar;": "\u00A6", - "bscr;": "\u1D4B7", + "brvbar": "\u00A6", + "bscr;": "\uD835\uDCB7", + "Bscr;": "\u212C", "bsemi;": "\u204F", "bsim;": "\u223D", "bsime;": "\u22CD", - "bsol;": "\u005C", "bsolb;": "\u29C5", + "bsol;": "\u005C", "bsolhsub;": "\u27C8", "bull;": "\u2022", "bullet;": "\u2022", "bump;": "\u224E", "bumpE;": "\u2AAE", "bumpe;": "\u224F", + "Bumpeq;": "\u224E", "bumpeq;": "\u224F", + "Cacute;": "\u0106", "cacute;": "\u0107", - "cap;": "\u2229", "capand;": "\u2A44", "capbrcup;": "\u2A49", "capcap;": "\u2A4B", + "cap;": "\u2229", + "Cap;": "\u22D2", "capcup;": "\u2A47", "capdot;": "\u2A40", + "CapitalDifferentialD;": "\u2145", "caps;": "\u2229\uFE00", "caret;": "\u2041", "caron;": "\u02C7", + "Cayleys;": "\u212D", "ccaps;": "\u2A4D", + "Ccaron;": "\u010C", "ccaron;": "\u010D", - "ccedil": "\u00E7", + "Ccedil;": "\u00C7", + "Ccedil": "\u00C7", "ccedil;": "\u00E7", + "ccedil": "\u00E7", + "Ccirc;": "\u0108", "ccirc;": "\u0109", + "Cconint;": "\u2230", "ccups;": "\u2A4C", "ccupssm;": "\u2A50", + "Cdot;": "\u010A", "cdot;": "\u010B", - "cedil": "\u00B8", "cedil;": "\u00B8", + "cedil": "\u00B8", + "Cedilla;": "\u00B8", "cemptyv;": "\u29B2", - "cent": "\u00A2", "cent;": "\u00A2", + "cent": "\u00A2", "centerdot;": "\u00B7", - "cfr;": "\u1D520", + "CenterDot;": "\u00B7", + "cfr;": "\uD835\uDD20", + "Cfr;": "\u212D", + "CHcy;": "\u0427", "chcy;": "\u0447", "check;": "\u2713", "checkmark;": "\u2713", + "Chi;": "\u03A7", "chi;": "\u03C7", - "cir;": "\u25CB", - "cirE;": "\u29C3", "circ;": "\u02C6", "circeq;": "\u2257", "circlearrowleft;": "\u21BA", "circlearrowright;": "\u21BB", - "circledR;": "\u00AE", - "circledS;": "\u24C8", "circledast;": "\u229B", "circledcirc;": "\u229A", "circleddash;": "\u229D", + "CircleDot;": "\u2299", + "circledR;": "\u00AE", + "circledS;": "\u24C8", + "CircleMinus;": "\u2296", + "CirclePlus;": "\u2295", + "CircleTimes;": "\u2297", + "cir;": "\u25CB", + "cirE;": "\u29C3", "cire;": "\u2257", "cirfnint;": "\u2A10", "cirmid;": "\u2AEF", "cirscir;": "\u29C2", + "ClockwiseContourIntegral;": "\u2232", + "CloseCurlyDoubleQuote;": "\u201D", + "CloseCurlyQuote;": "\u2019", "clubs;": "\u2663", "clubsuit;": "\u2663", - "colon;": ":", + "colon;": "\u003A", + "Colon;": "\u2237", + "Colone;": "\u2A74", "colone;": "\u2254", "coloneq;": "\u2254", - "comma;": ",", - "commat;": "@", + "comma;": "\u002C", + "commat;": "\u0040", "comp;": "\u2201", "compfn;": "\u2218", "complement;": "\u2201", "complexes;": "\u2102", "cong;": "\u2245", "congdot;": "\u2A6D", + "Congruent;": "\u2261", "conint;": "\u222E", - "copf;": "\u1D554", + "Conint;": "\u222F", + "ContourIntegral;": "\u222E", + "copf;": "\uD835\uDD54", + "Copf;": "\u2102", "coprod;": "\u2210", - "copy": "\u00A9", + "Coproduct;": "\u2210", "copy;": "\u00A9", + "copy": "\u00A9", + "COPY;": "\u00A9", + "COPY": "\u00A9", "copysr;": "\u2117", + "CounterClockwiseContourIntegral;": "\u2233", "crarr;": "\u21B5", "cross;": "\u2717", - "cscr;": "\u1D4B8", + "Cross;": "\u2A2F", + "Cscr;": "\uD835\uDC9E", + "cscr;": "\uD835\uDCB8", "csub;": "\u2ACF", "csube;": "\u2AD1", "csup;": "\u2AD0", @@ -7610,9 +7157,11 @@ module.exports = { "cuesc;": "\u22DF", "cularr;": "\u21B6", "cularrp;": "\u293D", - "cup;": "\u222A", "cupbrcap;": "\u2A48", "cupcap;": "\u2A46", + "CupCap;": "\u224D", + "cup;": "\u222A", + "Cup;": "\u22D3", "cupcup;": "\u2A4A", "cupdot;": "\u228D", "cupor;": "\u2A45", @@ -7623,8 +7172,8 @@ module.exports = { "curlyeqsucc;": "\u22DF", "curlyvee;": "\u22CE", "curlywedge;": "\u22CF", - "curren": "\u00A4", "curren;": "\u00A4", + "curren": "\u00A4", "curvearrowleft;": "\u21B6", "curvearrowright;": "\u21B7", "cuvee;": "\u22CE", @@ -7632,63 +7181,116 @@ module.exports = { "cwconint;": "\u2232", "cwint;": "\u2231", "cylcty;": "\u232D", - "dArr;": "\u21D3", - "dHar;": "\u2965", "dagger;": "\u2020", + "Dagger;": "\u2021", "daleth;": "\u2138", "darr;": "\u2193", + "Darr;": "\u21A1", + "dArr;": "\u21D3", "dash;": "\u2010", + "Dashv;": "\u2AE4", "dashv;": "\u22A3", "dbkarow;": "\u290F", "dblac;": "\u02DD", + "Dcaron;": "\u010E", "dcaron;": "\u010F", + "Dcy;": "\u0414", "dcy;": "\u0434", - "dd;": "\u2146", "ddagger;": "\u2021", "ddarr;": "\u21CA", + "DD;": "\u2145", + "dd;": "\u2146", + "DDotrahd;": "\u2911", "ddotseq;": "\u2A77", - "deg": "\u00B0", "deg;": "\u00B0", + "deg": "\u00B0", + "Del;": "\u2207", + "Delta;": "\u0394", "delta;": "\u03B4", "demptyv;": "\u29B1", "dfisht;": "\u297F", - "dfr;": "\u1D521", + "Dfr;": "\uD835\uDD07", + "dfr;": "\uD835\uDD21", + "dHar;": "\u2965", "dharl;": "\u21C3", "dharr;": "\u21C2", + "DiacriticalAcute;": "\u00B4", + "DiacriticalDot;": "\u02D9", + "DiacriticalDoubleAcute;": "\u02DD", + "DiacriticalGrave;": "\u0060", + "DiacriticalTilde;": "\u02DC", "diam;": "\u22C4", "diamond;": "\u22C4", + "Diamond;": "\u22C4", "diamondsuit;": "\u2666", "diams;": "\u2666", "die;": "\u00A8", + "DifferentialD;": "\u2146", "digamma;": "\u03DD", "disin;": "\u22F2", "div;": "\u00F7", - "divide": "\u00F7", "divide;": "\u00F7", + "divide": "\u00F7", "divideontimes;": "\u22C7", "divonx;": "\u22C7", + "DJcy;": "\u0402", "djcy;": "\u0452", "dlcorn;": "\u231E", "dlcrop;": "\u230D", - "dollar;": "$", - "dopf;": "\u1D555", + "dollar;": "\u0024", + "Dopf;": "\uD835\uDD3B", + "dopf;": "\uD835\uDD55", + "Dot;": "\u00A8", "dot;": "\u02D9", + "DotDot;": "\u20DC", "doteq;": "\u2250", "doteqdot;": "\u2251", + "DotEqual;": "\u2250", "dotminus;": "\u2238", "dotplus;": "\u2214", "dotsquare;": "\u22A1", "doublebarwedge;": "\u2306", + "DoubleContourIntegral;": "\u222F", + "DoubleDot;": "\u00A8", + "DoubleDownArrow;": "\u21D3", + "DoubleLeftArrow;": "\u21D0", + "DoubleLeftRightArrow;": "\u21D4", + "DoubleLeftTee;": "\u2AE4", + "DoubleLongLeftArrow;": "\u27F8", + "DoubleLongLeftRightArrow;": "\u27FA", + "DoubleLongRightArrow;": "\u27F9", + "DoubleRightArrow;": "\u21D2", + "DoubleRightTee;": "\u22A8", + "DoubleUpArrow;": "\u21D1", + "DoubleUpDownArrow;": "\u21D5", + "DoubleVerticalBar;": "\u2225", + "DownArrowBar;": "\u2913", "downarrow;": "\u2193", + "DownArrow;": "\u2193", + "Downarrow;": "\u21D3", + "DownArrowUpArrow;": "\u21F5", + "DownBreve;": "\u0311", "downdownarrows;": "\u21CA", "downharpoonleft;": "\u21C3", "downharpoonright;": "\u21C2", + "DownLeftRightVector;": "\u2950", + "DownLeftTeeVector;": "\u295E", + "DownLeftVectorBar;": "\u2956", + "DownLeftVector;": "\u21BD", + "DownRightTeeVector;": "\u295F", + "DownRightVectorBar;": "\u2957", + "DownRightVector;": "\u21C1", + "DownTeeArrow;": "\u21A7", + "DownTee;": "\u22A4", "drbkarow;": "\u2910", "drcorn;": "\u231F", "drcrop;": "\u230C", - "dscr;": "\u1D4B9", + "Dscr;": "\uD835\uDC9F", + "dscr;": "\uD835\uDCB9", + "DScy;": "\u0405", "dscy;": "\u0455", "dsol;": "\u29F6", + "Dstrok;": "\u0110", "dstrok;": "\u0111", "dtdot;": "\u22F1", "dtri;": "\u25BF", @@ -7696,48 +7298,67 @@ module.exports = { "duarr;": "\u21F5", "duhar;": "\u296F", "dwangle;": "\u29A6", + "DZcy;": "\u040F", "dzcy;": "\u045F", "dzigrarr;": "\u27FF", - "eDDot;": "\u2A77", - "eDot;": "\u2251", - "eacute": "\u00E9", + "Eacute;": "\u00C9", + "Eacute": "\u00C9", "eacute;": "\u00E9", + "eacute": "\u00E9", "easter;": "\u2A6E", + "Ecaron;": "\u011A", "ecaron;": "\u011B", - "ecir;": "\u2256", - "ecirc": "\u00EA", + "Ecirc;": "\u00CA", + "Ecirc": "\u00CA", "ecirc;": "\u00EA", + "ecirc": "\u00EA", + "ecir;": "\u2256", "ecolon;": "\u2255", + "Ecy;": "\u042D", "ecy;": "\u044D", + "eDDot;": "\u2A77", + "Edot;": "\u0116", "edot;": "\u0117", + "eDot;": "\u2251", "ee;": "\u2147", "efDot;": "\u2252", - "efr;": "\u1D522", + "Efr;": "\uD835\uDD08", + "efr;": "\uD835\uDD22", "eg;": "\u2A9A", - "egrave": "\u00E8", + "Egrave;": "\u00C8", + "Egrave": "\u00C8", "egrave;": "\u00E8", + "egrave": "\u00E8", "egs;": "\u2A96", "egsdot;": "\u2A98", "el;": "\u2A99", + "Element;": "\u2208", "elinters;": "\u23E7", "ell;": "\u2113", "els;": "\u2A95", "elsdot;": "\u2A97", + "Emacr;": "\u0112", "emacr;": "\u0113", "empty;": "\u2205", "emptyset;": "\u2205", + "EmptySmallSquare;": "\u25FB", "emptyv;": "\u2205", + "EmptyVerySmallSquare;": "\u25AB", "emsp13;": "\u2004", "emsp14;": "\u2005", "emsp;": "\u2003", + "ENG;": "\u014A", "eng;": "\u014B", "ensp;": "\u2002", + "Eogon;": "\u0118", "eogon;": "\u0119", - "eopf;": "\u1D556", + "Eopf;": "\uD835\uDD3C", + "eopf;": "\uD835\uDD56", "epar;": "\u22D5", "eparsl;": "\u29E3", "eplus;": "\u2A71", "epsi;": "\u03B5", + "Epsilon;": "\u0395", "epsilon;": "\u03B5", "epsiv;": "\u03F5", "eqcirc;": "\u2256", @@ -7745,56 +7366,75 @@ module.exports = { "eqsim;": "\u2242", "eqslantgtr;": "\u2A96", "eqslantless;": "\u2A95", - "equals;": "=", + "Equal;": "\u2A75", + "equals;": "\u003D", + "EqualTilde;": "\u2242", "equest;": "\u225F", + "Equilibrium;": "\u21CC", "equiv;": "\u2261", "equivDD;": "\u2A78", "eqvparsl;": "\u29E5", - "erDot;": "\u2253", "erarr;": "\u2971", + "erDot;": "\u2253", "escr;": "\u212F", + "Escr;": "\u2130", "esdot;": "\u2250", + "Esim;": "\u2A73", "esim;": "\u2242", + "Eta;": "\u0397", "eta;": "\u03B7", - "eth": "\u00F0", + "ETH;": "\u00D0", + "ETH": "\u00D0", "eth;": "\u00F0", - "euml": "\u00EB", + "eth": "\u00F0", + "Euml;": "\u00CB", + "Euml": "\u00CB", "euml;": "\u00EB", + "euml": "\u00EB", "euro;": "\u20AC", - "excl;": "!", + "excl;": "\u0021", "exist;": "\u2203", + "Exists;": "\u2203", "expectation;": "\u2130", "exponentiale;": "\u2147", + "ExponentialE;": "\u2147", "fallingdotseq;": "\u2252", + "Fcy;": "\u0424", "fcy;": "\u0444", "female;": "\u2640", "ffilig;": "\uFB03", "fflig;": "\uFB00", "ffllig;": "\uFB04", - "ffr;": "\u1D523", + "Ffr;": "\uD835\uDD09", + "ffr;": "\uD835\uDD23", "filig;": "\uFB01", - "fjlig;": "\u0066", + "FilledSmallSquare;": "\u25FC", + "FilledVerySmallSquare;": "\u25AA", + "fjlig;": "\u0066\u006A", "flat;": "\u266D", "fllig;": "\uFB02", "fltns;": "\u25B1", "fnof;": "\u0192", - "fopf;": "\u1D557", + "Fopf;": "\uD835\uDD3D", + "fopf;": "\uD835\uDD57", "forall;": "\u2200", + "ForAll;": "\u2200", "fork;": "\u22D4", "forkv;": "\u2AD9", + "Fouriertrf;": "\u2131", "fpartint;": "\u2A0D", - "frac12": "\u00BD", "frac12;": "\u00BD", + "frac12": "\u00BD", "frac13;": "\u2153", - "frac14": "\u00BC", "frac14;": "\u00BC", + "frac14": "\u00BC", "frac15;": "\u2155", "frac16;": "\u2159", "frac18;": "\u215B", "frac23;": "\u2154", "frac25;": "\u2156", - "frac34": "\u00BE", "frac34;": "\u00BE", + "frac34": "\u00BE", "frac35;": "\u2157", "frac38;": "\u215C", "frac45;": "\u2158", @@ -7803,55 +7443,78 @@ module.exports = { "frac78;": "\u215E", "frasl;": "\u2044", "frown;": "\u2322", - "fscr;": "\u1D4BB", - "gE;": "\u2267", - "gEl;": "\u2A8C", + "fscr;": "\uD835\uDCBB", + "Fscr;": "\u2131", "gacute;": "\u01F5", + "Gamma;": "\u0393", "gamma;": "\u03B3", + "Gammad;": "\u03DC", "gammad;": "\u03DD", "gap;": "\u2A86", + "Gbreve;": "\u011E", "gbreve;": "\u011F", + "Gcedil;": "\u0122", + "Gcirc;": "\u011C", "gcirc;": "\u011D", + "Gcy;": "\u0413", "gcy;": "\u0433", + "Gdot;": "\u0120", "gdot;": "\u0121", "ge;": "\u2265", + "gE;": "\u2267", + "gEl;": "\u2A8C", "gel;": "\u22DB", "geq;": "\u2265", "geqq;": "\u2267", "geqslant;": "\u2A7E", - "ges;": "\u2A7E", "gescc;": "\u2AA9", + "ges;": "\u2A7E", "gesdot;": "\u2A80", "gesdoto;": "\u2A82", "gesdotol;": "\u2A84", "gesl;": "\u22DB\uFE00", "gesles;": "\u2A94", - "gfr;": "\u1D524", + "Gfr;": "\uD835\uDD0A", + "gfr;": "\uD835\uDD24", "gg;": "\u226B", + "Gg;": "\u22D9", "ggg;": "\u22D9", "gimel;": "\u2137", + "GJcy;": "\u0403", "gjcy;": "\u0453", + "gla;": "\u2AA5", "gl;": "\u2277", "glE;": "\u2A92", - "gla;": "\u2AA5", "glj;": "\u2AA4", - "gnE;": "\u2269", "gnap;": "\u2A8A", "gnapprox;": "\u2A8A", "gne;": "\u2A88", + "gnE;": "\u2269", "gneq;": "\u2A88", "gneqq;": "\u2269", "gnsim;": "\u22E7", - "gopf;": "\u1D558", - "grave;": "`", + "Gopf;": "\uD835\uDD3E", + "gopf;": "\uD835\uDD58", + "grave;": "\u0060", + "GreaterEqual;": "\u2265", + "GreaterEqualLess;": "\u22DB", + "GreaterFullEqual;": "\u2267", + "GreaterGreater;": "\u2AA2", + "GreaterLess;": "\u2277", + "GreaterSlantEqual;": "\u2A7E", + "GreaterTilde;": "\u2273", + "Gscr;": "\uD835\uDCA2", "gscr;": "\u210A", "gsim;": "\u2273", "gsime;": "\u2A8E", "gsiml;": "\u2A90", - "gt": ">", - "gt;": ">", "gtcc;": "\u2AA7", "gtcir;": "\u2A7A", + "gt;": "\u003E", + "gt": "\u003E", + "GT;": "\u003E", + "GT": "\u003E", + "Gt;": "\u226B", "gtdot;": "\u22D7", "gtlPar;": "\u2995", "gtquest;": "\u2A7C", @@ -7864,149 +7527,210 @@ module.exports = { "gtrsim;": "\u2273", "gvertneqq;": "\u2269\uFE00", "gvnE;": "\u2269\uFE00", - "hArr;": "\u21D4", + "Hacek;": "\u02C7", "hairsp;": "\u200A", "half;": "\u00BD", "hamilt;": "\u210B", + "HARDcy;": "\u042A", "hardcy;": "\u044A", - "harr;": "\u2194", "harrcir;": "\u2948", + "harr;": "\u2194", + "hArr;": "\u21D4", "harrw;": "\u21AD", + "Hat;": "\u005E", "hbar;": "\u210F", + "Hcirc;": "\u0124", "hcirc;": "\u0125", "hearts;": "\u2665", "heartsuit;": "\u2665", "hellip;": "\u2026", "hercon;": "\u22B9", - "hfr;": "\u1D525", + "hfr;": "\uD835\uDD25", + "Hfr;": "\u210C", + "HilbertSpace;": "\u210B", "hksearow;": "\u2925", "hkswarow;": "\u2926", "hoarr;": "\u21FF", "homtht;": "\u223B", "hookleftarrow;": "\u21A9", "hookrightarrow;": "\u21AA", - "hopf;": "\u1D559", + "hopf;": "\uD835\uDD59", + "Hopf;": "\u210D", "horbar;": "\u2015", - "hscr;": "\u1D4BD", + "HorizontalLine;": "\u2500", + "hscr;": "\uD835\uDCBD", + "Hscr;": "\u210B", "hslash;": "\u210F", + "Hstrok;": "\u0126", "hstrok;": "\u0127", + "HumpDownHump;": "\u224E", + "HumpEqual;": "\u224F", "hybull;": "\u2043", "hyphen;": "\u2010", - "iacute": "\u00ED", + "Iacute;": "\u00CD", + "Iacute": "\u00CD", "iacute;": "\u00ED", + "iacute": "\u00ED", "ic;": "\u2063", - "icirc": "\u00EE", + "Icirc;": "\u00CE", + "Icirc": "\u00CE", "icirc;": "\u00EE", + "icirc": "\u00EE", + "Icy;": "\u0418", "icy;": "\u0438", + "Idot;": "\u0130", + "IEcy;": "\u0415", "iecy;": "\u0435", - "iexcl": "\u00A1", "iexcl;": "\u00A1", + "iexcl": "\u00A1", "iff;": "\u21D4", - "ifr;": "\u1D526", - "igrave": "\u00EC", + "ifr;": "\uD835\uDD26", + "Ifr;": "\u2111", + "Igrave;": "\u00CC", + "Igrave": "\u00CC", "igrave;": "\u00EC", + "igrave": "\u00EC", "ii;": "\u2148", "iiiint;": "\u2A0C", "iiint;": "\u222D", "iinfin;": "\u29DC", "iiota;": "\u2129", + "IJlig;": "\u0132", "ijlig;": "\u0133", + "Imacr;": "\u012A", "imacr;": "\u012B", "image;": "\u2111", + "ImaginaryI;": "\u2148", "imagline;": "\u2110", "imagpart;": "\u2111", "imath;": "\u0131", + "Im;": "\u2111", "imof;": "\u22B7", "imped;": "\u01B5", - "in;": "\u2208", + "Implies;": "\u21D2", "incare;": "\u2105", + "in;": "\u2208", "infin;": "\u221E", "infintie;": "\u29DD", "inodot;": "\u0131", - "int;": "\u222B", "intcal;": "\u22BA", + "int;": "\u222B", + "Int;": "\u222C", "integers;": "\u2124", + "Integral;": "\u222B", "intercal;": "\u22BA", + "Intersection;": "\u22C2", "intlarhk;": "\u2A17", "intprod;": "\u2A3C", + "InvisibleComma;": "\u2063", + "InvisibleTimes;": "\u2062", + "IOcy;": "\u0401", "iocy;": "\u0451", + "Iogon;": "\u012E", "iogon;": "\u012F", - "iopf;": "\u1D55A", + "Iopf;": "\uD835\uDD40", + "iopf;": "\uD835\uDD5A", + "Iota;": "\u0399", "iota;": "\u03B9", "iprod;": "\u2A3C", - "iquest": "\u00BF", "iquest;": "\u00BF", - "iscr;": "\u1D4BE", + "iquest": "\u00BF", + "iscr;": "\uD835\uDCBE", + "Iscr;": "\u2110", "isin;": "\u2208", - "isinE;": "\u22F9", "isindot;": "\u22F5", + "isinE;": "\u22F9", "isins;": "\u22F4", "isinsv;": "\u22F3", "isinv;": "\u2208", "it;": "\u2062", + "Itilde;": "\u0128", "itilde;": "\u0129", + "Iukcy;": "\u0406", "iukcy;": "\u0456", - "iuml": "\u00EF", + "Iuml;": "\u00CF", + "Iuml": "\u00CF", "iuml;": "\u00EF", + "iuml": "\u00EF", + "Jcirc;": "\u0134", "jcirc;": "\u0135", + "Jcy;": "\u0419", "jcy;": "\u0439", - "jfr;": "\u1D527", + "Jfr;": "\uD835\uDD0D", + "jfr;": "\uD835\uDD27", "jmath;": "\u0237", - "jopf;": "\u1D55B", - "jscr;": "\u1D4BF", + "Jopf;": "\uD835\uDD41", + "jopf;": "\uD835\uDD5B", + "Jscr;": "\uD835\uDCA5", + "jscr;": "\uD835\uDCBF", + "Jsercy;": "\u0408", "jsercy;": "\u0458", + "Jukcy;": "\u0404", "jukcy;": "\u0454", + "Kappa;": "\u039A", "kappa;": "\u03BA", "kappav;": "\u03F0", + "Kcedil;": "\u0136", "kcedil;": "\u0137", + "Kcy;": "\u041A", "kcy;": "\u043A", - "kfr;": "\u1D528", + "Kfr;": "\uD835\uDD0E", + "kfr;": "\uD835\uDD28", "kgreen;": "\u0138", + "KHcy;": "\u0425", "khcy;": "\u0445", + "KJcy;": "\u040C", "kjcy;": "\u045C", - "kopf;": "\u1D55C", - "kscr;": "\u1D4C0", + "Kopf;": "\uD835\uDD42", + "kopf;": "\uD835\uDD5C", + "Kscr;": "\uD835\uDCA6", + "kscr;": "\uD835\uDCC0", "lAarr;": "\u21DA", - "lArr;": "\u21D0", - "lAtail;": "\u291B", - "lBarr;": "\u290E", - "lE;": "\u2266", - "lEg;": "\u2A8B", - "lHar;": "\u2962", + "Lacute;": "\u0139", "lacute;": "\u013A", "laemptyv;": "\u29B4", "lagran;": "\u2112", + "Lambda;": "\u039B", "lambda;": "\u03BB", "lang;": "\u27E8", + "Lang;": "\u27EA", "langd;": "\u2991", "langle;": "\u27E8", "lap;": "\u2A85", - "laquo": "\u00AB", + "Laplacetrf;": "\u2112", "laquo;": "\u00AB", - "larr;": "\u2190", + "laquo": "\u00AB", "larrb;": "\u21E4", "larrbfs;": "\u291F", + "larr;": "\u2190", + "Larr;": "\u219E", + "lArr;": "\u21D0", "larrfs;": "\u291D", "larrhk;": "\u21A9", "larrlp;": "\u21AB", "larrpl;": "\u2939", "larrsim;": "\u2973", "larrtl;": "\u21A2", - "lat;": "\u2AAB", "latail;": "\u2919", + "lAtail;": "\u291B", + "lat;": "\u2AAB", "late;": "\u2AAD", "lates;": "\u2AAD\uFE00", "lbarr;": "\u290C", + "lBarr;": "\u290E", "lbbrk;": "\u2772", - "lbrace;": "{", - "lbrack;": "[", + "lbrace;": "\u007B", + "lbrack;": "\u005B", "lbrke;": "\u298B", "lbrksld;": "\u298F", "lbrkslu;": "\u298D", + "Lcaron;": "\u013D", "lcaron;": "\u013E", + "Lcedil;": "\u013B", "lcedil;": "\u013C", "lceil;": "\u2308", - "lcub;": "{", + "lcub;": "\u007B", + "Lcy;": "\u041B", "lcy;": "\u043B", "ldca;": "\u2936", "ldquo;": "\u201C", @@ -8015,22 +7739,50 @@ module.exports = { "ldrushar;": "\u294B", "ldsh;": "\u21B2", "le;": "\u2264", + "lE;": "\u2266", + "LeftAngleBracket;": "\u27E8", + "LeftArrowBar;": "\u21E4", "leftarrow;": "\u2190", + "LeftArrow;": "\u2190", + "Leftarrow;": "\u21D0", + "LeftArrowRightArrow;": "\u21C6", "leftarrowtail;": "\u21A2", + "LeftCeiling;": "\u2308", + "LeftDoubleBracket;": "\u27E6", + "LeftDownTeeVector;": "\u2961", + "LeftDownVectorBar;": "\u2959", + "LeftDownVector;": "\u21C3", + "LeftFloor;": "\u230A", "leftharpoondown;": "\u21BD", "leftharpoonup;": "\u21BC", "leftleftarrows;": "\u21C7", "leftrightarrow;": "\u2194", + "LeftRightArrow;": "\u2194", + "Leftrightarrow;": "\u21D4", "leftrightarrows;": "\u21C6", "leftrightharpoons;": "\u21CB", "leftrightsquigarrow;": "\u21AD", + "LeftRightVector;": "\u294E", + "LeftTeeArrow;": "\u21A4", + "LeftTee;": "\u22A3", + "LeftTeeVector;": "\u295A", "leftthreetimes;": "\u22CB", + "LeftTriangleBar;": "\u29CF", + "LeftTriangle;": "\u22B2", + "LeftTriangleEqual;": "\u22B4", + "LeftUpDownVector;": "\u2951", + "LeftUpTeeVector;": "\u2960", + "LeftUpVectorBar;": "\u2958", + "LeftUpVector;": "\u21BF", + "LeftVectorBar;": "\u2952", + "LeftVector;": "\u21BC", + "lEg;": "\u2A8B", "leg;": "\u22DA", "leq;": "\u2264", "leqq;": "\u2266", "leqslant;": "\u2A7D", - "les;": "\u2A7D", "lescc;": "\u2AA8", + "les;": "\u2A7D", "lesdot;": "\u2A7F", "lesdoto;": "\u2A81", "lesdotor;": "\u2A83", @@ -8040,30 +7792,42 @@ module.exports = { "lessdot;": "\u22D6", "lesseqgtr;": "\u22DA", "lesseqqgtr;": "\u2A8B", + "LessEqualGreater;": "\u22DA", + "LessFullEqual;": "\u2266", + "LessGreater;": "\u2276", "lessgtr;": "\u2276", + "LessLess;": "\u2AA1", "lesssim;": "\u2272", + "LessSlantEqual;": "\u2A7D", + "LessTilde;": "\u2272", "lfisht;": "\u297C", "lfloor;": "\u230A", - "lfr;": "\u1D529", + "Lfr;": "\uD835\uDD0F", + "lfr;": "\uD835\uDD29", "lg;": "\u2276", "lgE;": "\u2A91", + "lHar;": "\u2962", "lhard;": "\u21BD", "lharu;": "\u21BC", "lharul;": "\u296A", "lhblk;": "\u2584", + "LJcy;": "\u0409", "ljcy;": "\u0459", - "ll;": "\u226A", "llarr;": "\u21C7", + "ll;": "\u226A", + "Ll;": "\u22D8", "llcorner;": "\u231E", + "Lleftarrow;": "\u21DA", "llhard;": "\u296B", "lltri;": "\u25FA", + "Lmidot;": "\u013F", "lmidot;": "\u0140", - "lmoust;": "\u23B0", "lmoustache;": "\u23B0", - "lnE;": "\u2268", + "lmoust;": "\u23B0", "lnap;": "\u2A89", "lnapprox;": "\u2A89", "lne;": "\u2A87", + "lnE;": "\u2268", "lneq;": "\u2A87", "lneqq;": "\u2268", "lnsim;": "\u22E6", @@ -8071,21 +7835,30 @@ module.exports = { "loarr;": "\u21FD", "lobrk;": "\u27E6", "longleftarrow;": "\u27F5", + "LongLeftArrow;": "\u27F5", + "Longleftarrow;": "\u27F8", "longleftrightarrow;": "\u27F7", + "LongLeftRightArrow;": "\u27F7", + "Longleftrightarrow;": "\u27FA", "longmapsto;": "\u27FC", "longrightarrow;": "\u27F6", + "LongRightArrow;": "\u27F6", + "Longrightarrow;": "\u27F9", "looparrowleft;": "\u21AB", "looparrowright;": "\u21AC", "lopar;": "\u2985", - "lopf;": "\u1D55D", + "Lopf;": "\uD835\uDD43", + "lopf;": "\uD835\uDD5D", "loplus;": "\u2A2D", "lotimes;": "\u2A34", "lowast;": "\u2217", - "lowbar;": "_", + "lowbar;": "\u005F", + "LowerLeftArrow;": "\u2199", + "LowerRightArrow;": "\u2198", "loz;": "\u25CA", "lozenge;": "\u25CA", "lozf;": "\u29EB", - "lpar;": "(", + "lpar;": "\u0028", "lparlt;": "\u2993", "lrarr;": "\u21C6", "lrcorner;": "\u231F", @@ -8094,38 +7867,44 @@ module.exports = { "lrm;": "\u200E", "lrtri;": "\u22BF", "lsaquo;": "\u2039", - "lscr;": "\u1D4C1", + "lscr;": "\uD835\uDCC1", + "Lscr;": "\u2112", "lsh;": "\u21B0", + "Lsh;": "\u21B0", "lsim;": "\u2272", "lsime;": "\u2A8D", "lsimg;": "\u2A8F", - "lsqb;": "[", + "lsqb;": "\u005B", "lsquo;": "\u2018", "lsquor;": "\u201A", + "Lstrok;": "\u0141", "lstrok;": "\u0142", - "lt": "<", - "lt;": "<", "ltcc;": "\u2AA6", "ltcir;": "\u2A79", + "lt;": "\u003C", + "lt": "\u003C", + "LT;": "\u003C", + "LT": "\u003C", + "Lt;": "\u226A", "ltdot;": "\u22D6", "lthree;": "\u22CB", "ltimes;": "\u22C9", "ltlarr;": "\u2976", "ltquest;": "\u2A7B", - "ltrPar;": "\u2996", "ltri;": "\u25C3", "ltrie;": "\u22B4", "ltrif;": "\u25C2", + "ltrPar;": "\u2996", "lurdshar;": "\u294A", "luruhar;": "\u2966", "lvertneqq;": "\u2268\uFE00", "lvnE;": "\u2268\uFE00", - "mDDot;": "\u223A", - "macr": "\u00AF", "macr;": "\u00AF", + "macr": "\u00AF", "male;": "\u2642", "malt;": "\u2720", "maltese;": "\u2720", + "Map;": "\u2905", "map;": "\u21A6", "mapsto;": "\u21A6", "mapstodown;": "\u21A7", @@ -8133,45 +7912,44 @@ module.exports = { "mapstoup;": "\u21A5", "marker;": "\u25AE", "mcomma;": "\u2A29", + "Mcy;": "\u041C", "mcy;": "\u043C", "mdash;": "\u2014", + "mDDot;": "\u223A", "measuredangle;": "\u2221", - "mfr;": "\u1D52A", + "MediumSpace;": "\u205F", + "Mellintrf;": "\u2133", + "Mfr;": "\uD835\uDD10", + "mfr;": "\uD835\uDD2A", "mho;": "\u2127", - "micro": "\u00B5", "micro;": "\u00B5", - "mid;": "\u2223", - "midast;": "*", + "micro": "\u00B5", + "midast;": "\u002A", "midcir;": "\u2AF0", - "middot": "\u00B7", + "mid;": "\u2223", "middot;": "\u00B7", - "minus;": "\u2212", + "middot": "\u00B7", "minusb;": "\u229F", + "minus;": "\u2212", "minusd;": "\u2238", "minusdu;": "\u2A2A", + "MinusPlus;": "\u2213", "mlcp;": "\u2ADB", "mldr;": "\u2026", "mnplus;": "\u2213", "models;": "\u22A7", - "mopf;": "\u1D55E", + "Mopf;": "\uD835\uDD44", + "mopf;": "\uD835\uDD5E", "mp;": "\u2213", - "mscr;": "\u1D4C2", + "mscr;": "\uD835\uDCC2", + "Mscr;": "\u2133", "mstpos;": "\u223E", + "Mu;": "\u039C", "mu;": "\u03BC", "multimap;": "\u22B8", "mumap;": "\u22B8", - "nGg;": "\u22D9\u0338", - "nGt;": "\u226B\u20D2", - "nGtv;": "\u226B\u0338", - "nLeftarrow;": "\u21CD", - "nLeftrightarrow;": "\u21CE", - "nLl;": "\u22D8\u0338", - "nLt;": "\u226A\u20D2", - "nLtv;": "\u226A\u0338", - "nRightarrow;": "\u21CF", - "nVDash;": "\u22AF", - "nVdash;": "\u22AE", "nabla;": "\u2207", + "Nacute;": "\u0143", "nacute;": "\u0144", "nang;": "\u2220\u20D2", "nap;": "\u2249", @@ -8179,101 +7957,178 @@ module.exports = { "napid;": "\u224B\u0338", "napos;": "\u0149", "napprox;": "\u2249", - "natur;": "\u266E", "natural;": "\u266E", "naturals;": "\u2115", - "nbsp": "\u00A0", + "natur;": "\u266E", "nbsp;": "\u00A0", + "nbsp": "\u00A0", "nbump;": "\u224E\u0338", "nbumpe;": "\u224F\u0338", "ncap;": "\u2A43", + "Ncaron;": "\u0147", "ncaron;": "\u0148", + "Ncedil;": "\u0145", "ncedil;": "\u0146", - "ncong;": "\u2247\u0338", - "ncongdot;": "\u2A6D", + "ncong;": "\u2247", + "ncongdot;": "\u2A6D\u0338", "ncup;": "\u2A42", + "Ncy;": "\u041D", "ncy;": "\u043D", "ndash;": "\u2013", - "ne;": "\u2260", - "neArr;": "\u21D7", "nearhk;": "\u2924", "nearr;": "\u2197", + "neArr;": "\u21D7", "nearrow;": "\u2197", + "ne;": "\u2260", "nedot;": "\u2250\u0338", + "NegativeMediumSpace;": "\u200B", + "NegativeThickSpace;": "\u200B", + "NegativeThinSpace;": "\u200B", + "NegativeVeryThinSpace;": "\u200B", "nequiv;": "\u2262", "nesear;": "\u2928", "nesim;": "\u2242\u0338", + "NestedGreaterGreater;": "\u226B", + "NestedLessLess;": "\u226A", + "NewLine;": "\u000A", "nexist;": "\u2204", "nexists;": "\u2204", - "nfr;": "\u1D52B", + "Nfr;": "\uD835\uDD11", + "nfr;": "\uD835\uDD2B", "ngE;": "\u2267\u0338", "nge;": "\u2271", "ngeq;": "\u2271", "ngeqq;": "\u2267\u0338", "ngeqslant;": "\u2A7E\u0338", "nges;": "\u2A7E\u0338", + "nGg;": "\u22D9\u0338", "ngsim;": "\u2275", + "nGt;": "\u226B\u20D2", "ngt;": "\u226F", "ngtr;": "\u226F", - "nhArr;": "\u21CE", + "nGtv;": "\u226B\u0338", "nharr;": "\u21AE", + "nhArr;": "\u21CE", "nhpar;": "\u2AF2", "ni;": "\u220B", "nis;": "\u22FC", "nisd;": "\u22FA", "niv;": "\u220B", + "NJcy;": "\u040A", "njcy;": "\u045A", - "nlArr;": "\u21CD", - "nlE;": "\u2266\u0338", "nlarr;": "\u219A", + "nlArr;": "\u21CD", "nldr;": "\u2025", + "nlE;": "\u2266\u0338", "nle;": "\u2270", "nleftarrow;": "\u219A", + "nLeftarrow;": "\u21CD", "nleftrightarrow;": "\u21AE", + "nLeftrightarrow;": "\u21CE", "nleq;": "\u2270", "nleqq;": "\u2266\u0338", "nleqslant;": "\u2A7D\u0338", "nles;": "\u2A7D\u0338", "nless;": "\u226E", + "nLl;": "\u22D8\u0338", "nlsim;": "\u2274", + "nLt;": "\u226A\u20D2", "nlt;": "\u226E", "nltri;": "\u22EA", "nltrie;": "\u22EC", + "nLtv;": "\u226A\u0338", "nmid;": "\u2224", - "nopf;": "\u1D55F", - "not": "\u00AC", + "NoBreak;": "\u2060", + "NonBreakingSpace;": "\u00A0", + "nopf;": "\uD835\uDD5F", + "Nopf;": "\u2115", + "Not;": "\u2AEC", "not;": "\u00AC", + "not": "\u00AC", + "NotCongruent;": "\u2262", + "NotCupCap;": "\u226D", + "NotDoubleVerticalBar;": "\u2226", + "NotElement;": "\u2209", + "NotEqual;": "\u2260", + "NotEqualTilde;": "\u2242\u0338", + "NotExists;": "\u2204", + "NotGreater;": "\u226F", + "NotGreaterEqual;": "\u2271", + "NotGreaterFullEqual;": "\u2267\u0338", + "NotGreaterGreater;": "\u226B\u0338", + "NotGreaterLess;": "\u2279", + "NotGreaterSlantEqual;": "\u2A7E\u0338", + "NotGreaterTilde;": "\u2275", + "NotHumpDownHump;": "\u224E\u0338", + "NotHumpEqual;": "\u224F\u0338", "notin;": "\u2209", - "notinE;": "\u22F9\u0338", "notindot;": "\u22F5\u0338", + "notinE;": "\u22F9\u0338", "notinva;": "\u2209", "notinvb;": "\u22F7", "notinvc;": "\u22F6", + "NotLeftTriangleBar;": "\u29CF\u0338", + "NotLeftTriangle;": "\u22EA", + "NotLeftTriangleEqual;": "\u22EC", + "NotLess;": "\u226E", + "NotLessEqual;": "\u2270", + "NotLessGreater;": "\u2278", + "NotLessLess;": "\u226A\u0338", + "NotLessSlantEqual;": "\u2A7D\u0338", + "NotLessTilde;": "\u2274", + "NotNestedGreaterGreater;": "\u2AA2\u0338", + "NotNestedLessLess;": "\u2AA1\u0338", "notni;": "\u220C", "notniva;": "\u220C", "notnivb;": "\u22FE", "notnivc;": "\u22FD", - "npar;": "\u2226", + "NotPrecedes;": "\u2280", + "NotPrecedesEqual;": "\u2AAF\u0338", + "NotPrecedesSlantEqual;": "\u22E0", + "NotReverseElement;": "\u220C", + "NotRightTriangleBar;": "\u29D0\u0338", + "NotRightTriangle;": "\u22EB", + "NotRightTriangleEqual;": "\u22ED", + "NotSquareSubset;": "\u228F\u0338", + "NotSquareSubsetEqual;": "\u22E2", + "NotSquareSuperset;": "\u2290\u0338", + "NotSquareSupersetEqual;": "\u22E3", + "NotSubset;": "\u2282\u20D2", + "NotSubsetEqual;": "\u2288", + "NotSucceeds;": "\u2281", + "NotSucceedsEqual;": "\u2AB0\u0338", + "NotSucceedsSlantEqual;": "\u22E1", + "NotSucceedsTilde;": "\u227F\u0338", + "NotSuperset;": "\u2283\u20D2", + "NotSupersetEqual;": "\u2289", + "NotTilde;": "\u2241", + "NotTildeEqual;": "\u2244", + "NotTildeFullEqual;": "\u2247", + "NotTildeTilde;": "\u2249", + "NotVerticalBar;": "\u2224", "nparallel;": "\u2226", + "npar;": "\u2226", "nparsl;": "\u2AFD\u20E5", "npart;": "\u2202\u0338", "npolint;": "\u2A14", "npr;": "\u2280", "nprcue;": "\u22E0", - "npre;": "\u2AAF", "nprec;": "\u2280", - "npreceq;": "\u2AAF", - "nrArr;": "\u21CF", - "nrarr;": "\u219B", + "npreceq;": "\u2AAF\u0338", + "npre;": "\u2AAF\u0338", "nrarrc;": "\u2933\u0338", + "nrarr;": "\u219B", + "nrArr;": "\u21CF", "nrarrw;": "\u219D\u0338", "nrightarrow;": "\u219B", + "nRightarrow;": "\u21CF", "nrtri;": "\u22EB", "nrtrie;": "\u22ED", "nsc;": "\u2281", "nsccue;": "\u22E1", "nsce;": "\u2AB0\u0338", - "nscr;": "\u1D4C3", + "Nscr;": "\uD835\uDCA9", + "nscr;": "\uD835\uDCC3", "nshortmid;": "\u2224", "nshortparallel;": "\u2226", "nsim;": "\u2241", @@ -8286,35 +8141,40 @@ module.exports = { "nsub;": "\u2284", "nsubE;": "\u2AC5\u0338", "nsube;": "\u2288", - "nsubset;": "\u2282\u0338", + "nsubset;": "\u2282\u20D2", "nsubseteq;": "\u2288", "nsubseteqq;": "\u2AC5\u0338", "nsucc;": "\u2281", "nsucceq;": "\u2AB0\u0338", "nsup;": "\u2285", - "nsupE;": "\u2AC6", + "nsupE;": "\u2AC6\u0338", "nsupe;": "\u2289", - "nsupset;": "\u2283\u0338", + "nsupset;": "\u2283\u20D2", "nsupseteq;": "\u2289", "nsupseteqq;": "\u2AC6\u0338", "ntgl;": "\u2279", - "ntilde": "\u00F1", + "Ntilde;": "\u00D1", + "Ntilde": "\u00D1", "ntilde;": "\u00F1", + "ntilde": "\u00F1", "ntlg;": "\u2278", "ntriangleleft;": "\u22EA", "ntrianglelefteq;": "\u22EC", "ntriangleright;": "\u22EB", "ntrianglerighteq;": "\u22ED", + "Nu;": "\u039D", "nu;": "\u03BD", - "num;": "#", + "num;": "\u0023", "numero;": "\u2116", "numsp;": "\u2007", - "nvDash;": "\u22AD", - "nvHarr;": "\u2904", "nvap;": "\u224D\u20D2", "nvdash;": "\u22AC", + "nvDash;": "\u22AD", + "nVdash;": "\u22AE", + "nVDash;": "\u22AF", "nvge;": "\u2265\u20D2", "nvgt;": "\u003E\u20D2", + "nvHarr;": "\u2904", "nvinfin;": "\u29DE", "nvlArr;": "\u2902", "nvle;": "\u2264\u20D2", @@ -8323,30 +8183,39 @@ module.exports = { "nvrArr;": "\u2903", "nvrtrie;": "\u22B5\u20D2", "nvsim;": "\u223C\u20D2", - "nwArr;": "\u21D6", "nwarhk;": "\u2923", "nwarr;": "\u2196", + "nwArr;": "\u21D6", "nwarrow;": "\u2196", "nwnear;": "\u2927", - "oS;": "\u24C8", - "oacute": "\u00F3", + "Oacute;": "\u00D3", + "Oacute": "\u00D3", "oacute;": "\u00F3", + "oacute": "\u00F3", "oast;": "\u229B", - "ocir;": "\u229A", - "ocirc": "\u00F4", + "Ocirc;": "\u00D4", + "Ocirc": "\u00D4", "ocirc;": "\u00F4", + "ocirc": "\u00F4", + "ocir;": "\u229A", + "Ocy;": "\u041E", "ocy;": "\u043E", "odash;": "\u229D", + "Odblac;": "\u0150", "odblac;": "\u0151", "odiv;": "\u2A38", "odot;": "\u2299", "odsold;": "\u29BC", + "OElig;": "\u0152", "oelig;": "\u0153", "ofcir;": "\u29BF", - "ofr;": "\u1D52C", + "Ofr;": "\uD835\uDD12", + "ofr;": "\uD835\uDD2C", "ogon;": "\u02DB", - "ograve": "\u00F2", + "Ograve;": "\u00D2", + "Ograve": "\u00D2", "ograve;": "\u00F2", + "ograve": "\u00F2", "ogt;": "\u29C1", "ohbar;": "\u29B5", "ohm;": "\u03A9", @@ -8356,160 +8225,211 @@ module.exports = { "olcross;": "\u29BB", "oline;": "\u203E", "olt;": "\u29C0", + "Omacr;": "\u014C", "omacr;": "\u014D", + "Omega;": "\u03A9", "omega;": "\u03C9", + "Omicron;": "\u039F", "omicron;": "\u03BF", "omid;": "\u29B6", "ominus;": "\u2296", - "oopf;": "\u1D560", + "Oopf;": "\uD835\uDD46", + "oopf;": "\uD835\uDD60", "opar;": "\u29B7", + "OpenCurlyDoubleQuote;": "\u201C", + "OpenCurlyQuote;": "\u2018", "operp;": "\u29B9", "oplus;": "\u2295", - "or;": "\u2228", "orarr;": "\u21BB", + "Or;": "\u2A54", + "or;": "\u2228", "ord;": "\u2A5D", "order;": "\u2134", "orderof;": "\u2134", - "ordf": "\u00AA", "ordf;": "\u00AA", - "ordm": "\u00BA", + "ordf": "\u00AA", "ordm;": "\u00BA", + "ordm": "\u00BA", "origof;": "\u22B6", "oror;": "\u2A56", "orslope;": "\u2A57", "orv;": "\u2A5B", + "oS;": "\u24C8", + "Oscr;": "\uD835\uDCAA", "oscr;": "\u2134", - "oslash": "\u00F8", + "Oslash;": "\u00D8", + "Oslash": "\u00D8", "oslash;": "\u00F8", + "oslash": "\u00F8", "osol;": "\u2298", - "otilde": "\u00F5", + "Otilde;": "\u00D5", + "Otilde": "\u00D5", "otilde;": "\u00F5", - "otimes;": "\u2297", + "otilde": "\u00F5", "otimesas;": "\u2A36", - "ouml": "\u00F6", + "Otimes;": "\u2A37", + "otimes;": "\u2297", + "Ouml;": "\u00D6", + "Ouml": "\u00D6", "ouml;": "\u00F6", + "ouml": "\u00F6", "ovbar;": "\u233D", - "par;": "\u2225", - "para": "\u00B6", + "OverBar;": "\u203E", + "OverBrace;": "\u23DE", + "OverBracket;": "\u23B4", + "OverParenthesis;": "\u23DC", "para;": "\u00B6", + "para": "\u00B6", "parallel;": "\u2225", + "par;": "\u2225", "parsim;": "\u2AF3", "parsl;": "\u2AFD", "part;": "\u2202", + "PartialD;": "\u2202", + "Pcy;": "\u041F", "pcy;": "\u043F", - "percnt;": "%", - "period;": ".", + "percnt;": "\u0025", + "period;": "\u002E", "permil;": "\u2030", "perp;": "\u22A5", "pertenk;": "\u2031", - "pfr;": "\u1D52D", + "Pfr;": "\uD835\uDD13", + "pfr;": "\uD835\uDD2D", + "Phi;": "\u03A6", "phi;": "\u03C6", "phiv;": "\u03D5", "phmmat;": "\u2133", "phone;": "\u260E", + "Pi;": "\u03A0", "pi;": "\u03C0", "pitchfork;": "\u22D4", "piv;": "\u03D6", "planck;": "\u210F", "planckh;": "\u210E", "plankv;": "\u210F", - "plus;": "+", "plusacir;": "\u2A23", "plusb;": "\u229E", "pluscir;": "\u2A22", + "plus;": "\u002B", "plusdo;": "\u2214", "plusdu;": "\u2A25", "pluse;": "\u2A72", - "plusmn": "\u00B1", + "PlusMinus;": "\u00B1", "plusmn;": "\u00B1", + "plusmn": "\u00B1", "plussim;": "\u2A26", "plustwo;": "\u2A27", "pm;": "\u00B1", + "Poincareplane;": "\u210C", "pointint;": "\u2A15", - "popf;": "\u1D561", - "pound": "\u00A3", + "popf;": "\uD835\uDD61", + "Popf;": "\u2119", "pound;": "\u00A3", - "pr;": "\u227A", - "prE;": "\u2AB3", + "pound": "\u00A3", "prap;": "\u2AB7", + "Pr;": "\u2ABB", + "pr;": "\u227A", "prcue;": "\u227C", - "pre;": "\u2AAF", - "prec;": "\u227A", "precapprox;": "\u2AB7", + "prec;": "\u227A", "preccurlyeq;": "\u227C", + "Precedes;": "\u227A", + "PrecedesEqual;": "\u2AAF", + "PrecedesSlantEqual;": "\u227C", + "PrecedesTilde;": "\u227E", "preceq;": "\u2AAF", "precnapprox;": "\u2AB9", "precneqq;": "\u2AB5", "precnsim;": "\u22E8", + "pre;": "\u2AAF", + "prE;": "\u2AB3", "precsim;": "\u227E", "prime;": "\u2032", + "Prime;": "\u2033", "primes;": "\u2119", - "prnE;": "\u2AB5", "prnap;": "\u2AB9", + "prnE;": "\u2AB5", "prnsim;": "\u22E8", "prod;": "\u220F", + "Product;": "\u220F", "profalar;": "\u232E", "profline;": "\u2312", "profsurf;": "\u2313", "prop;": "\u221D", + "Proportional;": "\u221D", + "Proportion;": "\u2237", "propto;": "\u221D", "prsim;": "\u227E", "prurel;": "\u22B0", - "pscr;": "\u1D4C5", + "Pscr;": "\uD835\uDCAB", + "pscr;": "\uD835\uDCC5", + "Psi;": "\u03A8", "psi;": "\u03C8", "puncsp;": "\u2008", - "qfr;": "\u1D52E", + "Qfr;": "\uD835\uDD14", + "qfr;": "\uD835\uDD2E", "qint;": "\u2A0C", - "qopf;": "\u1D562", + "qopf;": "\uD835\uDD62", + "Qopf;": "\u211A", "qprime;": "\u2057", - "qscr;": "\u1D4C6", + "Qscr;": "\uD835\uDCAC", + "qscr;": "\uD835\uDCC6", "quaternions;": "\u210D", "quatint;": "\u2A16", - "quest;": "?", + "quest;": "\u003F", "questeq;": "\u225F", - "quot": "\u0022", "quot;": "\u0022", + "quot": "\u0022", + "QUOT;": "\u0022", + "QUOT": "\u0022", "rAarr;": "\u21DB", - "rArr;": "\u21D2", - "rAtail;": "\u291C", - "rBarr;": "\u290F", - "rHar;": "\u2964", "race;": "\u223D\u0331", + "Racute;": "\u0154", "racute;": "\u0155", "radic;": "\u221A", "raemptyv;": "\u29B3", "rang;": "\u27E9", + "Rang;": "\u27EB", "rangd;": "\u2992", "range;": "\u29A5", "rangle;": "\u27E9", - "raquo": "\u00BB", "raquo;": "\u00BB", - "rarr;": "\u2192", + "raquo": "\u00BB", "rarrap;": "\u2975", "rarrb;": "\u21E5", "rarrbfs;": "\u2920", "rarrc;": "\u2933", + "rarr;": "\u2192", + "Rarr;": "\u21A0", + "rArr;": "\u21D2", "rarrfs;": "\u291E", "rarrhk;": "\u21AA", "rarrlp;": "\u21AC", "rarrpl;": "\u2945", "rarrsim;": "\u2974", + "Rarrtl;": "\u2916", "rarrtl;": "\u21A3", "rarrw;": "\u219D", "ratail;": "\u291A", + "rAtail;": "\u291C", "ratio;": "\u2236", "rationals;": "\u211A", "rbarr;": "\u290D", + "rBarr;": "\u290F", + "RBarr;": "\u2910", "rbbrk;": "\u2773", - "rbrace;": "}", - "rbrack;": "]", + "rbrace;": "\u007D", + "rbrack;": "\u005D", "rbrke;": "\u298C", "rbrksld;": "\u298E", "rbrkslu;": "\u2990", + "Rcaron;": "\u0158", "rcaron;": "\u0159", + "Rcedil;": "\u0156", "rcedil;": "\u0157", "rceil;": "\u2309", - "rcub;": "}", + "rcub;": "\u007D", + "Rcy;": "\u0420", "rcy;": "\u0440", "rdca;": "\u2937", "rdldhar;": "\u2969", @@ -8520,49 +8440,86 @@ module.exports = { "realine;": "\u211B", "realpart;": "\u211C", "reals;": "\u211D", + "Re;": "\u211C", "rect;": "\u25AD", - "reg": "\u00AE", "reg;": "\u00AE", + "reg": "\u00AE", + "REG;": "\u00AE", + "REG": "\u00AE", + "ReverseElement;": "\u220B", + "ReverseEquilibrium;": "\u21CB", + "ReverseUpEquilibrium;": "\u296F", "rfisht;": "\u297D", "rfloor;": "\u230B", - "rfr;": "\u1D52F", + "rfr;": "\uD835\uDD2F", + "Rfr;": "\u211C", + "rHar;": "\u2964", "rhard;": "\u21C1", "rharu;": "\u21C0", "rharul;": "\u296C", + "Rho;": "\u03A1", "rho;": "\u03C1", "rhov;": "\u03F1", + "RightAngleBracket;": "\u27E9", + "RightArrowBar;": "\u21E5", "rightarrow;": "\u2192", + "RightArrow;": "\u2192", + "Rightarrow;": "\u21D2", + "RightArrowLeftArrow;": "\u21C4", "rightarrowtail;": "\u21A3", + "RightCeiling;": "\u2309", + "RightDoubleBracket;": "\u27E7", + "RightDownTeeVector;": "\u295D", + "RightDownVectorBar;": "\u2955", + "RightDownVector;": "\u21C2", + "RightFloor;": "\u230B", "rightharpoondown;": "\u21C1", "rightharpoonup;": "\u21C0", "rightleftarrows;": "\u21C4", "rightleftharpoons;": "\u21CC", "rightrightarrows;": "\u21C9", "rightsquigarrow;": "\u219D", + "RightTeeArrow;": "\u21A6", + "RightTee;": "\u22A2", + "RightTeeVector;": "\u295B", "rightthreetimes;": "\u22CC", + "RightTriangleBar;": "\u29D0", + "RightTriangle;": "\u22B3", + "RightTriangleEqual;": "\u22B5", + "RightUpDownVector;": "\u294F", + "RightUpTeeVector;": "\u295C", + "RightUpVectorBar;": "\u2954", + "RightUpVector;": "\u21BE", + "RightVectorBar;": "\u2953", + "RightVector;": "\u21C0", "ring;": "\u02DA", "risingdotseq;": "\u2253", "rlarr;": "\u21C4", "rlhar;": "\u21CC", "rlm;": "\u200F", - "rmoust;": "\u23B1", "rmoustache;": "\u23B1", + "rmoust;": "\u23B1", "rnmid;": "\u2AEE", "roang;": "\u27ED", "roarr;": "\u21FE", "robrk;": "\u27E7", "ropar;": "\u2986", - "ropf;": "\u1D563", + "ropf;": "\uD835\uDD63", + "Ropf;": "\u211D", "roplus;": "\u2A2E", "rotimes;": "\u2A35", - "rpar;": ")", + "RoundImplies;": "\u2970", + "rpar;": "\u0029", "rpargt;": "\u2994", "rppolint;": "\u2A12", "rrarr;": "\u21C9", + "Rrightarrow;": "\u21DB", "rsaquo;": "\u203A", - "rscr;": "\u1D4C7", + "rscr;": "\uD835\uDCC7", + "Rscr;": "\u211B", "rsh;": "\u21B1", - "rsqb;": "]", + "Rsh;": "\u21B1", + "rsqb;": "\u005D", "rsquo;": "\u2019", "rsquor;": "\u2019", "rthree;": "\u22CC", @@ -8571,47 +8528,62 @@ module.exports = { "rtrie;": "\u22B5", "rtrif;": "\u25B8", "rtriltri;": "\u29CE", + "RuleDelayed;": "\u29F4", "ruluhar;": "\u2968", "rx;": "\u211E", + "Sacute;": "\u015A", "sacute;": "\u015B", "sbquo;": "\u201A", - "sc;": "\u227B", - "scE;": "\u2AB4", "scap;": "\u2AB8", + "Scaron;": "\u0160", "scaron;": "\u0161", + "Sc;": "\u2ABC", + "sc;": "\u227B", "sccue;": "\u227D", "sce;": "\u2AB0", + "scE;": "\u2AB4", + "Scedil;": "\u015E", "scedil;": "\u015F", + "Scirc;": "\u015C", "scirc;": "\u015D", - "scnE;": "\u2AB6", "scnap;": "\u2ABA", + "scnE;": "\u2AB6", "scnsim;": "\u22E9", "scpolint;": "\u2A13", "scsim;": "\u227F", + "Scy;": "\u0421", "scy;": "\u0441", - "sdot;": "\u22C5", "sdotb;": "\u22A1", + "sdot;": "\u22C5", "sdote;": "\u2A66", - "seArr;": "\u21D8", "searhk;": "\u2925", "searr;": "\u2198", + "seArr;": "\u21D8", "searrow;": "\u2198", - "sect": "\u00A7", "sect;": "\u00A7", - "semi;": ";", + "sect": "\u00A7", + "semi;": "\u003B", "seswar;": "\u2929", "setminus;": "\u2216", "setmn;": "\u2216", "sext;": "\u2736", - "sfr;": "\u1D530", + "Sfr;": "\uD835\uDD16", + "sfr;": "\uD835\uDD30", "sfrown;": "\u2322", "sharp;": "\u266F", + "SHCHcy;": "\u0429", "shchcy;": "\u0449", + "SHcy;": "\u0428", "shcy;": "\u0448", + "ShortDownArrow;": "\u2193", + "ShortLeftArrow;": "\u2190", "shortmid;": "\u2223", "shortparallel;": "\u2225", - "shy": "\u00AD", + "ShortRightArrow;": "\u2192", + "ShortUpArrow;": "\u2191", "shy;": "\u00AD", + "shy": "\u00AD", + "Sigma;": "\u03A3", "sigma;": "\u03C3", "sigmaf;": "\u03C2", "sigmav;": "\u03C2", @@ -8627,6 +8599,7 @@ module.exports = { "simplus;": "\u2A24", "simrarr;": "\u2972", "slarr;": "\u2190", + "SmallCircle;": "\u2218", "smallsetminus;": "\u2216", "smashp;": "\u2A33", "smeparsl;": "\u29E4", @@ -8635,11 +8608,13 @@ module.exports = { "smt;": "\u2AAA", "smte;": "\u2AAC", "smtes;": "\u2AAC\uFE00", + "SOFTcy;": "\u042C", "softcy;": "\u044C", - "sol;": "/", - "solb;": "\u29C4", "solbar;": "\u233F", - "sopf;": "\u1D564", + "solb;": "\u29C4", + "sol;": "\u002F", + "Sopf;": "\uD835\uDD4A", + "sopf;": "\uD835\uDD64", "spades;": "\u2660", "spadesuit;": "\u2660", "spar;": "\u2225", @@ -8647,6 +8622,7 @@ module.exports = { "sqcaps;": "\u2293\uFE00", "sqcup;": "\u2294", "sqcups;": "\u2294\uFE00", + "Sqrt;": "\u221A", "sqsub;": "\u228F", "sqsube;": "\u2291", "sqsubset;": "\u228F", @@ -8655,23 +8631,33 @@ module.exports = { "sqsupe;": "\u2292", "sqsupset;": "\u2290", "sqsupseteq;": "\u2292", - "squ;": "\u25A1", "square;": "\u25A1", + "Square;": "\u25A1", + "SquareIntersection;": "\u2293", + "SquareSubset;": "\u228F", + "SquareSubsetEqual;": "\u2291", + "SquareSuperset;": "\u2290", + "SquareSupersetEqual;": "\u2292", + "SquareUnion;": "\u2294", "squarf;": "\u25AA", + "squ;": "\u25A1", "squf;": "\u25AA", "srarr;": "\u2192", - "sscr;": "\u1D4C8", + "Sscr;": "\uD835\uDCAE", + "sscr;": "\uD835\uDCC8", "ssetmn;": "\u2216", "ssmile;": "\u2323", "sstarf;": "\u22C6", + "Star;": "\u22C6", "star;": "\u2606", "starf;": "\u2605", "straightepsilon;": "\u03F5", "straightphi;": "\u03D5", "strns;": "\u00AF", "sub;": "\u2282", - "subE;": "\u2AC5", + "Sub;": "\u22D0", "subdot;": "\u2ABD", + "subE;": "\u2AC5", "sube;": "\u2286", "subedot;": "\u2AC3", "submult;": "\u2AC1", @@ -8680,35 +8666,46 @@ module.exports = { "subplus;": "\u2ABF", "subrarr;": "\u2979", "subset;": "\u2282", + "Subset;": "\u22D0", "subseteq;": "\u2286", "subseteqq;": "\u2AC5", + "SubsetEqual;": "\u2286", "subsetneq;": "\u228A", "subsetneqq;": "\u2ACB", "subsim;": "\u2AC7", "subsub;": "\u2AD5", "subsup;": "\u2AD3", - "succ;": "\u227B", "succapprox;": "\u2AB8", + "succ;": "\u227B", "succcurlyeq;": "\u227D", + "Succeeds;": "\u227B", + "SucceedsEqual;": "\u2AB0", + "SucceedsSlantEqual;": "\u227D", + "SucceedsTilde;": "\u227F", "succeq;": "\u2AB0", "succnapprox;": "\u2ABA", "succneqq;": "\u2AB6", "succnsim;": "\u22E9", "succsim;": "\u227F", + "SuchThat;": "\u220B", "sum;": "\u2211", + "Sum;": "\u2211", "sung;": "\u266A", - "sup1": "\u00B9", "sup1;": "\u00B9", - "sup2": "\u00B2", + "sup1": "\u00B9", "sup2;": "\u00B2", - "sup3": "\u00B3", + "sup2": "\u00B2", "sup3;": "\u00B3", + "sup3": "\u00B3", "sup;": "\u2283", - "supE;": "\u2AC6", + "Sup;": "\u22D1", "supdot;": "\u2ABE", "supdsub;": "\u2AD8", + "supE;": "\u2AC6", "supe;": "\u2287", "supedot;": "\u2AC4", + "Superset;": "\u2283", + "SupersetEqual;": "\u2287", "suphsol;": "\u27C9", "suphsub;": "\u2AD7", "suplarr;": "\u297B", @@ -8717,6 +8714,7 @@ module.exports = { "supne;": "\u228B", "supplus;": "\u2AC0", "supset;": "\u2283", + "Supset;": "\u22D1", "supseteq;": "\u2287", "supseteqq;": "\u2AC6", "supsetneq;": "\u228B", @@ -8724,50 +8722,68 @@ module.exports = { "supsim;": "\u2AC8", "supsub;": "\u2AD4", "supsup;": "\u2AD6", - "swArr;": "\u21D9", "swarhk;": "\u2926", "swarr;": "\u2199", + "swArr;": "\u21D9", "swarrow;": "\u2199", "swnwar;": "\u292A", - "szlig": "\u00DF", "szlig;": "\u00DF", + "szlig": "\u00DF", + "Tab;": "\u0009", "target;": "\u2316", + "Tau;": "\u03A4", "tau;": "\u03C4", "tbrk;": "\u23B4", + "Tcaron;": "\u0164", "tcaron;": "\u0165", + "Tcedil;": "\u0162", "tcedil;": "\u0163", + "Tcy;": "\u0422", "tcy;": "\u0442", "tdot;": "\u20DB", "telrec;": "\u2315", - "tfr;": "\u1D531", + "Tfr;": "\uD835\uDD17", + "tfr;": "\uD835\uDD31", "there4;": "\u2234", "therefore;": "\u2234", + "Therefore;": "\u2234", + "Theta;": "\u0398", "theta;": "\u03B8", "thetasym;": "\u03D1", "thetav;": "\u03D1", "thickapprox;": "\u2248", "thicksim;": "\u223C", + "ThickSpace;": "\u205F\u200A", + "ThinSpace;": "\u2009", "thinsp;": "\u2009", "thkap;": "\u2248", "thksim;": "\u223C", - "thorn": "\u00FE", + "THORN;": "\u00DE", + "THORN": "\u00DE", "thorn;": "\u00FE", + "thorn": "\u00FE", "tilde;": "\u02DC", - "times": "\u00D7", - "times;": "\u00D7", - "timesb;": "\u22A0", + "Tilde;": "\u223C", + "TildeEqual;": "\u2243", + "TildeFullEqual;": "\u2245", + "TildeTilde;": "\u2248", "timesbar;": "\u2A31", + "timesb;": "\u22A0", + "times;": "\u00D7", + "times": "\u00D7", "timesd;": "\u2A30", "tint;": "\u222D", "toea;": "\u2928", - "top;": "\u22A4", "topbot;": "\u2336", "topcir;": "\u2AF1", - "topf;": "\u1D565", + "top;": "\u22A4", + "Topf;": "\uD835\uDD4B", + "topf;": "\uD835\uDD65", "topfork;": "\u2ADA", "tosa;": "\u2929", "tprime;": "\u2034", "trade;": "\u2122", + "TRADE;": "\u2122", "triangle;": "\u25B5", "triangledown;": "\u25BF", "triangleleft;": "\u25C3", @@ -8778,34 +8794,52 @@ module.exports = { "tridot;": "\u25EC", "trie;": "\u225C", "triminus;": "\u2A3A", + "TripleDot;": "\u20DB", "triplus;": "\u2A39", "trisb;": "\u29CD", "tritime;": "\u2A3B", "trpezium;": "\u23E2", - "tscr;": "\u1D4C9", + "Tscr;": "\uD835\uDCAF", + "tscr;": "\uD835\uDCC9", + "TScy;": "\u0426", "tscy;": "\u0446", + "TSHcy;": "\u040B", "tshcy;": "\u045B", + "Tstrok;": "\u0166", "tstrok;": "\u0167", "twixt;": "\u226C", "twoheadleftarrow;": "\u219E", "twoheadrightarrow;": "\u21A0", - "uArr;": "\u21D1", - "uHar;": "\u2963", - "uacute": "\u00FA", + "Uacute;": "\u00DA", + "Uacute": "\u00DA", "uacute;": "\u00FA", + "uacute": "\u00FA", "uarr;": "\u2191", + "Uarr;": "\u219F", + "uArr;": "\u21D1", + "Uarrocir;": "\u2949", + "Ubrcy;": "\u040E", "ubrcy;": "\u045E", + "Ubreve;": "\u016C", "ubreve;": "\u016D", - "ucirc": "\u00FB", + "Ucirc;": "\u00DB", + "Ucirc": "\u00DB", "ucirc;": "\u00FB", + "ucirc": "\u00FB", + "Ucy;": "\u0423", "ucy;": "\u0443", "udarr;": "\u21C5", + "Udblac;": "\u0170", "udblac;": "\u0171", "udhar;": "\u296E", "ufisht;": "\u297E", - "ufr;": "\u1D532", - "ugrave": "\u00F9", + "Ufr;": "\uD835\uDD18", + "ufr;": "\uD835\uDD32", + "Ugrave;": "\u00D9", + "Ugrave": "\u00D9", "ugrave;": "\u00F9", + "ugrave": "\u00F9", + "uHar;": "\u2963", "uharl;": "\u21BF", "uharr;": "\u21BE", "uhblk;": "\u2580", @@ -8813,38 +8847,61 @@ module.exports = { "ulcorner;": "\u231C", "ulcrop;": "\u230F", "ultri;": "\u25F8", + "Umacr;": "\u016A", "umacr;": "\u016B", - "uml": "\u00A8", "uml;": "\u00A8", + "uml": "\u00A8", + "UnderBar;": "\u005F", + "UnderBrace;": "\u23DF", + "UnderBracket;": "\u23B5", + "UnderParenthesis;": "\u23DD", + "Union;": "\u22C3", + "UnionPlus;": "\u228E", + "Uogon;": "\u0172", "uogon;": "\u0173", - "uopf;": "\u1D566", + "Uopf;": "\uD835\uDD4C", + "uopf;": "\uD835\uDD66", + "UpArrowBar;": "\u2912", "uparrow;": "\u2191", + "UpArrow;": "\u2191", + "Uparrow;": "\u21D1", + "UpArrowDownArrow;": "\u21C5", "updownarrow;": "\u2195", + "UpDownArrow;": "\u2195", + "Updownarrow;": "\u21D5", + "UpEquilibrium;": "\u296E", "upharpoonleft;": "\u21BF", "upharpoonright;": "\u21BE", "uplus;": "\u228E", + "UpperLeftArrow;": "\u2196", + "UpperRightArrow;": "\u2197", "upsi;": "\u03C5", + "Upsi;": "\u03D2", "upsih;": "\u03D2", + "Upsilon;": "\u03A5", "upsilon;": "\u03C5", + "UpTeeArrow;": "\u21A5", + "UpTee;": "\u22A5", "upuparrows;": "\u21C8", "urcorn;": "\u231D", "urcorner;": "\u231D", "urcrop;": "\u230E", + "Uring;": "\u016E", "uring;": "\u016F", "urtri;": "\u25F9", - "uscr;": "\u1D4CA", + "Uscr;": "\uD835\uDCB0", + "uscr;": "\uD835\uDCCA", "utdot;": "\u22F0", + "Utilde;": "\u0168", "utilde;": "\u0169", "utri;": "\u25B5", "utrif;": "\u25B4", "uuarr;": "\u21C8", - "uuml": "\u00FC", + "Uuml;": "\u00DC", + "Uuml": "\u00DC", "uuml;": "\u00FC", + "uuml": "\u00FC", "uwangle;": "\u29A7", - "vArr;": "\u21D5", - "vBar;": "\u2AE8", - "vBarv;": "\u2AE9", - "vDash;": "\u22A8", "vangrt;": "\u299C", "varepsilon;": "\u03F5", "varkappa;": "\u03F0", @@ -8853,6 +8910,7 @@ module.exports = { "varpi;": "\u03D6", "varpropto;": "\u221D", "varr;": "\u2195", + "vArr;": "\u21D5", "varrho;": "\u03F1", "varsigma;": "\u03C2", "varsubsetneq;": "\u228A\uFE00", @@ -8862,107 +8920,175 @@ module.exports = { "vartheta;": "\u03D1", "vartriangleleft;": "\u22B2", "vartriangleright;": "\u22B3", + "vBar;": "\u2AE8", + "Vbar;": "\u2AEB", + "vBarv;": "\u2AE9", + "Vcy;": "\u0412", "vcy;": "\u0432", "vdash;": "\u22A2", - "vee;": "\u2228", + "vDash;": "\u22A8", + "Vdash;": "\u22A9", + "VDash;": "\u22AB", + "Vdashl;": "\u2AE6", "veebar;": "\u22BB", + "vee;": "\u2228", + "Vee;": "\u22C1", "veeeq;": "\u225A", "vellip;": "\u22EE", - "verbar;": "|", - "vert;": "|", - "vfr;": "\u1D533", + "verbar;": "\u007C", + "Verbar;": "\u2016", + "vert;": "\u007C", + "Vert;": "\u2016", + "VerticalBar;": "\u2223", + "VerticalLine;": "\u007C", + "VerticalSeparator;": "\u2758", + "VerticalTilde;": "\u2240", + "VeryThinSpace;": "\u200A", + "Vfr;": "\uD835\uDD19", + "vfr;": "\uD835\uDD33", "vltri;": "\u22B2", "vnsub;": "\u2282\u20D2", "vnsup;": "\u2283\u20D2", - "vopf;": "\u1D567", + "Vopf;": "\uD835\uDD4D", + "vopf;": "\uD835\uDD67", "vprop;": "\u221D", "vrtri;": "\u22B3", - "vscr;": "\u1D4CB", + "Vscr;": "\uD835\uDCB1", + "vscr;": "\uD835\uDCCB", "vsubnE;": "\u2ACB\uFE00", "vsubne;": "\u228A\uFE00", "vsupnE;": "\u2ACC\uFE00", "vsupne;": "\u228B\uFE00", + "Vvdash;": "\u22AA", "vzigzag;": "\u299A", + "Wcirc;": "\u0174", "wcirc;": "\u0175", "wedbar;": "\u2A5F", "wedge;": "\u2227", + "Wedge;": "\u22C0", "wedgeq;": "\u2259", "weierp;": "\u2118", - "wfr;": "\u1D534", - "wopf;": "\u1D568", + "Wfr;": "\uD835\uDD1A", + "wfr;": "\uD835\uDD34", + "Wopf;": "\uD835\uDD4E", + "wopf;": "\uD835\uDD68", "wp;": "\u2118", "wr;": "\u2240", "wreath;": "\u2240", - "wscr;": "\u1D4CC", + "Wscr;": "\uD835\uDCB2", + "wscr;": "\uD835\uDCCC", "xcap;": "\u22C2", "xcirc;": "\u25EF", "xcup;": "\u22C3", "xdtri;": "\u25BD", - "xfr;": "\u1D535", - "xhArr;": "\u27FA", + "Xfr;": "\uD835\uDD1B", + "xfr;": "\uD835\uDD35", "xharr;": "\u27F7", + "xhArr;": "\u27FA", + "Xi;": "\u039E", "xi;": "\u03BE", - "xlArr;": "\u27F8", "xlarr;": "\u27F5", + "xlArr;": "\u27F8", "xmap;": "\u27FC", "xnis;": "\u22FB", "xodot;": "\u2A00", - "xopf;": "\u1D569", + "Xopf;": "\uD835\uDD4F", + "xopf;": "\uD835\uDD69", "xoplus;": "\u2A01", "xotime;": "\u2A02", - "xrArr;": "\u27F9", "xrarr;": "\u27F6", - "xscr;": "\u1D4CD", + "xrArr;": "\u27F9", + "Xscr;": "\uD835\uDCB3", + "xscr;": "\uD835\uDCCD", "xsqcup;": "\u2A06", "xuplus;": "\u2A04", "xutri;": "\u25B3", "xvee;": "\u22C1", "xwedge;": "\u22C0", - "yacute": "\u00FD", + "Yacute;": "\u00DD", + "Yacute": "\u00DD", "yacute;": "\u00FD", + "yacute": "\u00FD", + "YAcy;": "\u042F", "yacy;": "\u044F", + "Ycirc;": "\u0176", "ycirc;": "\u0177", + "Ycy;": "\u042B", "ycy;": "\u044B", - "yen": "\u00A5", "yen;": "\u00A5", - "yfr;": "\u1D536", + "yen": "\u00A5", + "Yfr;": "\uD835\uDD1C", + "yfr;": "\uD835\uDD36", + "YIcy;": "\u0407", "yicy;": "\u0457", - "yopf;": "\u1D56A", - "yscr;": "\u1D4CE", + "Yopf;": "\uD835\uDD50", + "yopf;": "\uD835\uDD6A", + "Yscr;": "\uD835\uDCB4", + "yscr;": "\uD835\uDCCE", + "YUcy;": "\u042E", "yucy;": "\u044E", - "yuml": "\u00FF", "yuml;": "\u00FF", + "yuml": "\u00FF", + "Yuml;": "\u0178", + "Zacute;": "\u0179", "zacute;": "\u017A", + "Zcaron;": "\u017D", "zcaron;": "\u017E", + "Zcy;": "\u0417", "zcy;": "\u0437", + "Zdot;": "\u017B", "zdot;": "\u017C", "zeetrf;": "\u2128", + "ZeroWidthSpace;": "\u200B", + "Zeta;": "\u0396", "zeta;": "\u03B6", - "zfr;": "\u1D537", + "zfr;": "\uD835\uDD37", + "Zfr;": "\u2128", + "ZHcy;": "\u0416", "zhcy;": "\u0436", "zigrarr;": "\u21DD", - "zopf;": "\u1D56B", - "zscr;": "\u1D4CF", + "zopf;": "\uD835\uDD6B", + "Zopf;": "\u2124", + "Zscr;": "\uD835\uDCB5", + "zscr;": "\uD835\uDCCF", "zwj;": "\u200D", "zwnj;": "\u200C" }; -},{}],13:[function(req,module,exports){ -(function(){// UTILITY -var util = req('util'); -var Buffer = req("buffer").Buffer; -var pSlice = Array.prototype.slice; +}, +{}], +13:[function(_dereq_,module,exports){ +// http://wiki.commonjs.org/wiki/Unit_Testing/1.0 +// +// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8! +// +// Originally from narwhal.js (http://narwhaljs.org) +// Copyright (c) 2009 Thomas Robinson <280north.com> +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the 'Software'), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -function objectKeys(object) { - if (Object.keys) return Object.keys(object); - var result = []; - for (var name in object) { - if (Object.prototype.hasOwnProperty.call(object, name)) { - result.push(name); - } - } - return result; -} +// when used in node, this will actually load the util module we depend on +// versus loading the builtin util module as happens otherwise +// this is a bug in node module loading as far as I am concerned +var util = _dereq_('util/'); + +var pSlice = Array.prototype.slice; +var hasOwn = Object.prototype.hasOwnProperty; // 1. The assert module provides functions that throw // AssertionError's when particular conditions are not met. The @@ -8977,53 +9103,71 @@ var assert = module.exports = ok; assert.AssertionError = function AssertionError(options) { this.name = 'AssertionError'; - this.message = options.message; this.actual = options.actual; this.expected = options.expected; this.operator = options.operator; + if (options.message) { + this.message = options.message; + this.generatedMessage = false; + } else { + this.message = getMessage(this); + this.generatedMessage = true; + } var stackStartFunction = options.stackStartFunction || fail; if (Error.captureStackTrace) { Error.captureStackTrace(this, stackStartFunction); } + else { + // non v8 browsers so we can have a stacktrace + var err = new Error(); + if (err.stack) { + var out = err.stack; + + // try to strip useless frames + var fn_name = stackStartFunction.name; + var idx = out.indexOf('\n' + fn_name); + if (idx >= 0) { + // once we have located the function frame + // we need to strip out everything before it (and its line) + var next_line = out.indexOf('\n', idx + 1); + out = out.substring(next_line + 1); + } + + this.stack = out; + } + } }; // assert.AssertionError instanceof Error util.inherits(assert.AssertionError, Error); function replacer(key, value) { - if (value === undefined) { + if (util.isUndefined(value)) { return '' + value; } - if (typeof value === 'number' && (isNaN(value) || !isFinite(value))) { + if (util.isNumber(value) && (isNaN(value) || !isFinite(value))) { return value.toString(); } - if (typeof value === 'function' || value instanceof RegExp) { + if (util.isFunction(value) || util.isRegExp(value)) { return value.toString(); } return value; } function truncate(s, n) { - if (typeof s == 'string') { + if (util.isString(s)) { return s.length < n ? s : s.slice(0, n); } else { return s; } } -assert.AssertionError.prototype.toString = function() { - if (this.message) { - return [this.name + ':', this.message].join(' '); - } else { - return [ - this.name + ':', - truncate(JSON.stringify(this.actual, replacer), 128), - this.operator, - truncate(JSON.stringify(this.expected, replacer), 128) - ].join(' '); - } -}; +function getMessage(self) { + return truncate(JSON.stringify(self.actual, replacer), 128) + ' ' + + self.operator + ' ' + + truncate(JSON.stringify(self.expected, replacer), 128); +} // At present only the three keys mentioned above are used and // understood by the spec. Implementations or sub modules can pass @@ -9052,12 +9196,12 @@ assert.fail = fail; // 4. Pure assertion tests whether a value is truthy, as determined // by !!guard. // assert.ok(guard, message_opt); -// This statement is equivalent to assert.equal(true, guard, +// This statement is equivalent to assert.equal(true, !!guard, // message_opt);. To test strictly for the value true, use // assert.strictEqual(true, guard, message_opt);. function ok(value, message) { - if (!!!value) fail(value, true, message, '==', assert.ok); + if (!value) fail(value, true, message, '==', assert.ok); } assert.ok = ok; @@ -9092,7 +9236,7 @@ function _deepEqual(actual, expected) { if (actual === expected) { return true; - } else if (Buffer.isBuffer(actual) && Buffer.isBuffer(expected)) { + } else if (util.isBuffer(actual) && util.isBuffer(expected)) { if (actual.length != expected.length) return false; for (var i = 0; i < actual.length; i++) { @@ -9103,15 +9247,25 @@ function _deepEqual(actual, expected) { // 7.2. If the expected value is a Date object, the actual value is // equivalent if it is also a Date object that refers to the same time. - } else if (actual instanceof Date && expected instanceof Date) { + } else if (util.isDate(actual) && util.isDate(expected)) { return actual.getTime() === expected.getTime(); - // 7.3. Other pairs that do not both pass typeof value == 'object', + // 7.3 If the expected value is a RegExp object, the actual value is + // equivalent if it is also a RegExp object with the same source and + // properties (`global`, `multiline`, `lastIndex`, `ignoreCase`). + } else if (util.isRegExp(actual) && util.isRegExp(expected)) { + return actual.source === expected.source && + actual.global === expected.global && + actual.multiline === expected.multiline && + actual.lastIndex === expected.lastIndex && + actual.ignoreCase === expected.ignoreCase; + + // 7.4. Other pairs that do not both pass typeof value == 'object', // equivalence is determined by ==. - } else if (typeof actual != 'object' && typeof expected != 'object') { + } else if (!util.isObject(actual) && !util.isObject(expected)) { return actual == expected; - // 7.4. For all other Object pairs, including Array objects, equivalence is + // 7.5 For all other Object pairs, including Array objects, equivalence is // determined by having the same number of owned properties (as verified // with Object.prototype.hasOwnProperty.call), the same set of keys // (although not necessarily the same order), equivalent values for every @@ -9122,16 +9276,12 @@ function _deepEqual(actual, expected) { } } -function isUndefinedOrNull(value) { - return value === null || value === undefined; -} - function isArguments(object) { return Object.prototype.toString.call(object) == '[object Arguments]'; } function objEquiv(a, b) { - if (isUndefinedOrNull(a) || isUndefinedOrNull(b)) + if (util.isNullOrUndefined(a) || util.isNullOrUndefined(b)) return false; // an identical 'prototype' property. if (a.prototype !== b.prototype) return false; @@ -9205,7 +9355,7 @@ function expectedException(actual, expected) { return false; } - if (expected instanceof RegExp) { + if (Object.prototype.toString.call(expected) == '[object RegExp]') { return expected.test(actual); } else if (actual instanceof expected) { return true; @@ -9219,7 +9369,7 @@ function expectedException(actual, expected) { function _throws(shouldThrow, block, expected, message) { var actual; - if (typeof expected === 'string') { + if (util.isString(expected)) { message = expected; expected = null; } @@ -9234,11 +9384,11 @@ function _throws(shouldThrow, block, expected, message) { (message ? ' ' + message : '.'); if (shouldThrow && !actual) { - fail('Missing expected exception' + message); + fail(actual, expected, 'Missing expected exception' + message); } if (!shouldThrow && expectedException(actual, expected)) { - fail('Got unwanted exception' + message); + fail(actual, expected, 'Got unwanted exception' + message); } if ((shouldThrow && actual && expected && @@ -9255,518 +9405,60 @@ assert.throws = function(block, /*optional*/error, /*optional*/message) { }; // EXTENSION! This is annoying to write outside this module. -assert.doesNotThrow = function(block, /*optional*/error, /*optional*/message) { +assert.doesNotThrow = function(block, /*optional*/message) { _throws.apply(this, [false].concat(pSlice.call(arguments))); }; assert.ifError = function(err) { if (err) {throw err;}}; -})() -},{"buffer":17,"util":15}],14:[function(req,module,exports){ -(function(process){if (!process.EventEmitter) process.EventEmitter = function () {}; +var objectKeys = Object.keys || function (obj) { + var keys = []; + for (var key in obj) { + if (hasOwn.call(obj, key)) keys.push(key); + } + return keys; +}; -var EventEmitter = exports.EventEmitter = process.EventEmitter; -var isArray = typeof Array.isArray === 'function' - ? Array.isArray - : function (xs) { - return Object.prototype.toString.call(xs) === '[object Array]' - } -; -function indexOf (xs, x) { - if (xs.indexOf) return xs.indexOf(x); - for (var i = 0; i < xs.length; i++) { - if (x === xs[i]) return i; - } - return -1; +}, +{"util/":15}], +14:[function(_dereq_,module,exports){ +module.exports = function isBuffer(arg) { + return arg && typeof arg === 'object' + && typeof arg.copy === 'function' + && typeof arg.fill === 'function' + && typeof arg.readUInt8 === 'function'; } - -// By default EventEmitters will print a warning if more than -// 10 listeners are added to it. This is a useful default which -// helps finding memory leaks. +}, +{}], +15:[function(_dereq_,module,exports){ +(function (process,global){ +// Copyright Joyent, Inc. and other Node contributors. // -// Obviously not all Emitters should be limited to 10. This function allows -// that to be increased. Set to zero for unlimited. -var defaultMaxListeners = 10; -EventEmitter.prototype.setMaxListeners = function(n) { - if (!this._events) this._events = {}; - this._events.maxListeners = n; -}; - - -EventEmitter.prototype.emit = function(type) { - // If there is no 'error' event listener then throw. - if (type === 'error') { - if (!this._events || !this._events.error || - (isArray(this._events.error) && !this._events.error.length)) - { - if (arguments[1] instanceof Error) { - throw arguments[1]; // Unhandled 'error' event - } else { - throw new Error("Uncaught, unspecified 'error' event."); - } - return false; - } - } - - if (!this._events) return false; - var handler = this._events[type]; - if (!handler) return false; - - if (typeof handler == 'function') { - switch (arguments.length) { - // fast cases - case 1: - handler.call(this); - break; - case 2: - handler.call(this, arguments[1]); - break; - case 3: - handler.call(this, arguments[1], arguments[2]); - break; - // slower - default: - var args = Array.prototype.slice.call(arguments, 1); - handler.apply(this, args); - } - return true; - - } else if (isArray(handler)) { - var args = Array.prototype.slice.call(arguments, 1); - - var listeners = handler.slice(); - for (var i = 0, l = listeners.length; i < l; i++) { - listeners[i].apply(this, args); - } - return true; - - } else { - return false; - } -}; - -// EventEmitter is defined in src/node_events.cc -// EventEmitter.prototype.emit() is also defined there. -EventEmitter.prototype.addListener = function(type, listener) { - if ('function' !== typeof listener) { - throw new Error('addListener only takes instances of Function'); - } - - if (!this._events) this._events = {}; - - // To avoid recursion in the case that type == "newListeners"! Before - // adding it to the listeners, first emit "newListeners". - this.emit('newListener', type, listener); - - if (!this._events[type]) { - // Optimize the case of one listener. Don't need the extra array object. - this._events[type] = listener; - } else if (isArray(this._events[type])) { - - // Check for listener leak - if (!this._events[type].warned) { - var m; - if (this._events.maxListeners !== undefined) { - m = this._events.maxListeners; - } else { - m = defaultMaxListeners; - } - - if (m && m > 0 && this._events[type].length > m) { - this._events[type].warned = true; - console.error('(node) warning: possible EventEmitter memory ' + - 'leak detected. %d listeners added. ' + - 'Use emitter.setMaxListeners() to increase limit.', - this._events[type].length); - console.trace(); - } - } - - // If we've already got an array, just append. - this._events[type].push(listener); - } else { - // Adding the second element, need to change to array. - this._events[type] = [this._events[type], listener]; - } - - return this; -}; - -EventEmitter.prototype.on = EventEmitter.prototype.addListener; - -EventEmitter.prototype.once = function(type, listener) { - var self = this; - self.on(type, function g() { - self.removeListener(type, g); - listener.apply(this, arguments); - }); - - return this; -}; - -EventEmitter.prototype.removeListener = function(type, listener) { - if ('function' !== typeof listener) { - throw new Error('removeListener only takes instances of Function'); - } - - // does not use listeners(), so no side effect of creating _events[type] - if (!this._events || !this._events[type]) return this; - - var list = this._events[type]; - - if (isArray(list)) { - var i = indexOf(list, listener); - if (i < 0) return this; - list.splice(i, 1); - if (list.length == 0) - delete this._events[type]; - } else if (this._events[type] === listener) { - delete this._events[type]; - } - - return this; -}; - -EventEmitter.prototype.removeAllListeners = function(type) { - if (arguments.length === 0) { - this._events = {}; - return this; - } - - // does not use listeners(), so no side effect of creating _events[type] - if (type && this._events && this._events[type]) this._events[type] = null; - return this; -}; - -EventEmitter.prototype.listeners = function(type) { - if (!this._events) this._events = {}; - if (!this._events[type]) this._events[type] = []; - if (!isArray(this._events[type])) { - this._events[type] = [this._events[type]]; - } - return this._events[type]; -}; - -})(req("__browserify_process")) -},{"__browserify_process":20}],15:[function(req,module,exports){ -var events = req('events'); - -exports.isArray = isArray; -exports.isDate = function(obj){return Object.prototype.toString.call(obj) === '[object Date]'}; -exports.isRegExp = function(obj){return Object.prototype.toString.call(obj) === '[object RegExp]'}; - - -exports.print = function () {}; -exports.puts = function () {}; -exports.debug = function() {}; - -exports.inspect = function(obj, showHidden, depth, colors) { - var seen = []; - - var stylize = function(str, styleType) { - // http://en.wikipedia.org/wiki/ANSI_escape_code#graphics - var styles = - { 'bold' : [1, 22], - 'italic' : [3, 23], - 'underline' : [4, 24], - 'inverse' : [7, 27], - 'white' : [37, 39], - 'grey' : [90, 39], - 'black' : [30, 39], - 'blue' : [34, 39], - 'cyan' : [36, 39], - 'green' : [32, 39], - 'magenta' : [35, 39], - 'red' : [31, 39], - 'yellow' : [33, 39] }; - - var style = - { 'special': 'cyan', - 'number': 'blue', - 'boolean': 'yellow', - 'undefined': 'grey', - 'null': 'bold', - 'string': 'green', - 'date': 'magenta', - // "name": intentionally not styling - 'regexp': 'red' }[styleType]; - - if (style) { - return '\u001b[' + styles[style][0] + 'm' + str + - '\u001b[' + styles[style][1] + 'm'; - } else { - return str; - } - }; - if (! colors) { - stylize = function(str, styleType) { return str; }; - } - - function format(value, recurseTimes) { - // Provide a hook for user-specified inspect functions. - // Check that value is an object with an inspect function on it - if (value && typeof value.inspect === 'function' && - // Filter out the util module, it's inspect function is special - value !== exports && - // Also filter out any prototype objects using the circular check. - !(value.constructor && value.constructor.prototype === value)) { - return value.inspect(recurseTimes); - } - - // Primitive types cannot have properties - switch (typeof value) { - case 'undefined': - return stylize('undefined', 'undefined'); - - case 'string': - var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') - .replace(/'/g, "\\'") - .replace(/\\"/g, '"') + '\''; - return stylize(simple, 'string'); - - case 'number': - return stylize('' + value, 'number'); - - case 'boolean': - return stylize('' + value, 'boolean'); - } - // For some reason typeof null is "object", so special case here. - if (value === null) { - return stylize('null', 'null'); - } - - // Look up the keys of the object. - var visible_keys = Object_keys(value); - var keys = showHidden ? Object_getOwnPropertyNames(value) : visible_keys; - - // Functions without properties can be shortcutted. - if (typeof value === 'function' && keys.length === 0) { - if (isRegExp(value)) { - return stylize('' + value, 'regexp'); - } else { - var name = value.name ? ': ' + value.name : ''; - return stylize('[Function' + name + ']', 'special'); - } - } - - // Dates without properties can be shortcutted - if (isDate(value) && keys.length === 0) { - return stylize(value.toUTCString(), 'date'); - } - - var base, type, braces; - // Determine the object type - if (isArray(value)) { - type = 'Array'; - braces = ['[', ']']; - } else { - type = 'Object'; - braces = ['{', '}']; - } - - // Make functions say that they are functions - if (typeof value === 'function') { - var n = value.name ? ': ' + value.name : ''; - base = (isRegExp(value)) ? ' ' + value : ' [Function' + n + ']'; - } else { - base = ''; - } - - // Make dates with properties first say the date - if (isDate(value)) { - base = ' ' + value.toUTCString(); - } - - if (keys.length === 0) { - return braces[0] + base + braces[1]; - } - - if (recurseTimes < 0) { - if (isRegExp(value)) { - return stylize('' + value, 'regexp'); - } else { - return stylize('[Object]', 'special'); - } - } - - seen.push(value); - - var output = keys.map(function(key) { - var name, str; - if (value.__lookupGetter__) { - if (value.__lookupGetter__(key)) { - if (value.__lookupSetter__(key)) { - str = stylize('[Getter/Setter]', 'special'); - } else { - str = stylize('[Getter]', 'special'); - } - } else { - if (value.__lookupSetter__(key)) { - str = stylize('[Setter]', 'special'); - } - } - } - if (visible_keys.indexOf(key) < 0) { - name = '[' + key + ']'; - } - if (!str) { - if (seen.indexOf(value[key]) < 0) { - if (recurseTimes === null) { - str = format(value[key]); - } else { - str = format(value[key], recurseTimes - 1); - } - if (str.indexOf('\n') > -1) { - if (isArray(value)) { - str = str.split('\n').map(function(line) { - return ' ' + line; - }).join('\n').substr(2); - } else { - str = '\n' + str.split('\n').map(function(line) { - return ' ' + line; - }).join('\n'); - } - } - } else { - str = stylize('[Circular]', 'special'); - } - } - if (typeof name === 'undefined') { - if (type === 'Array' && key.match(/^\d+$/)) { - return str; - } - name = JSON.stringify('' + key); - if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { - name = name.substr(1, name.length - 2); - name = stylize(name, 'name'); - } else { - name = name.replace(/'/g, "\\'") - .replace(/\\"/g, '"') - .replace(/(^"|"$)/g, "'"); - name = stylize(name, 'string'); - } - } - - return name + ': ' + str; - }); - - seen.pop(); - - var numLinesEst = 0; - var length = output.reduce(function(prev, cur) { - numLinesEst++; - if (cur.indexOf('\n') >= 0) numLinesEst++; - return prev + cur.length + 1; - }, 0); - - if (length > 50) { - output = braces[0] + - (base === '' ? '' : base + '\n ') + - ' ' + - output.join(',\n ') + - ' ' + - braces[1]; - - } else { - output = braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; - } - - return output; - } - return format(obj, (typeof depth === 'undefined' ? 2 : depth)); -}; - - -function isArray(ar) { - return Array.isArray(ar) || - (typeof ar === 'object' && Object.prototype.toString.call(ar) === '[object Array]'); -} - - -function isRegExp(re) { - typeof re === 'object' && Object.prototype.toString.call(re) === '[object RegExp]'; -} - - -function isDate(d) { - return typeof d === 'object' && Object.prototype.toString.call(d) === '[object Date]'; -} - -function pad(n) { - return n < 10 ? '0' + n.toString(10) : n.toString(10); -} - -var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', - 'Oct', 'Nov', 'Dec']; - -// 26 Feb 16:19:34 -function timestamp() { - var d = new Date(); - var time = [pad(d.getHours()), - pad(d.getMinutes()), - pad(d.getSeconds())].join(':'); - return [d.getDate(), months[d.getMonth()], time].join(' '); -} - -exports.log = function (msg) {}; - -exports.pump = null; - -var Object_keys = Object.keys || function (obj) { - var res = []; - for (var key in obj) res.push(key); - return res; -}; - -var Object_getOwnPropertyNames = Object.getOwnPropertyNames || function (obj) { - var res = []; - for (var key in obj) { - if (Object.hasOwnProperty.call(obj, key)) res.push(key); - } - return res; -}; - -var Object_create = Object.create || function (prototype, properties) { - // from es5-shim - var object; - if (prototype === null) { - object = { '__proto__' : null }; - } - else { - if (typeof prototype !== 'object') { - throw new TypeError( - 'typeof prototype[' + (typeof prototype) + '] != \'object\'' - ); - } - var Type = function () {}; - Type.prototype = prototype; - object = new Type(); - object.__proto__ = prototype; - } - if (typeof properties !== 'undefined' && Object.defineProperties) { - Object.defineProperties(object, properties); - } - return object; -}; - -exports.inherits = function(ctor, superCtor) { - ctor.super_ = superCtor; - ctor.prototype = Object_create(superCtor.prototype, { - constructor: { - value: ctor, - enumerable: false, - writable: true, - configurable: true - } - }); -}; +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. var formatRegExp = /%[sdj%]/g; exports.format = function(f) { - if (typeof f !== 'string') { + if (!isString(f)) { var objects = []; for (var i = 0; i < arguments.length; i++) { - objects.push(exports.inspect(arguments[i])); + objects.push(inspect(arguments[i])); } return objects.join(' '); } @@ -9780,1280 +9472,888 @@ exports.format = function(f) { switch (x) { case '%s': return String(args[i++]); case '%d': return Number(args[i++]); - case '%j': return JSON.stringify(args[i++]); + case '%j': + try { + return JSON.stringify(args[i++]); + } catch (_) { + return '[Circular]'; + } default: return x; } }); - for(var x = args[i]; i < len; x = args[++i]){ - if (x === null || typeof x !== 'object') { + for (var x = args[i]; i < len; x = args[++i]) { + if (isNull(x) || !isObject(x)) { str += ' ' + x; } else { - str += ' ' + exports.inspect(x); + str += ' ' + inspect(x); } } return str; }; -},{"events":14}],16:[function(req,module,exports){ -exports.readIEEE754 = function(buffer, offset, isBE, mLen, nBytes) { - var e, m, - eLen = nBytes * 8 - mLen - 1, - eMax = (1 << eLen) - 1, - eBias = eMax >> 1, - nBits = -7, - i = isBE ? 0 : (nBytes - 1), - d = isBE ? 1 : -1, - s = buffer[offset + i]; - i += d; - - e = s & ((1 << (-nBits)) - 1); - s >>= (-nBits); - nBits += eLen; - for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8); - - m = e & ((1 << (-nBits)) - 1); - e >>= (-nBits); - nBits += mLen; - for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8); - - if (e === 0) { - e = 1 - eBias; - } else if (e === eMax) { - return m ? NaN : ((s ? -1 : 1) * Infinity); - } else { - m = m + Math.pow(2, mLen); - e = e - eBias; +// Mark that a method should not be used. +// Returns a modified function which warns once by default. +// If --no-deprecation is set, then it is a no-op. +exports.deprecate = function(fn, msg) { + // Allow for deprecating things in the process of starting up. + if (isUndefined(global.process)) { + return function() { + return exports.deprecate(fn, msg).apply(this, arguments); + }; } - return (s ? -1 : 1) * m * Math.pow(2, e - mLen); + + if (process.noDeprecation === true) { + return fn; + } + + var warned = false; + function deprecated() { + if (!warned) { + if (process.throwDeprecation) { + throw new Error(msg); + } else if (process.traceDeprecation) { + console.trace(msg); + } else { + console.error(msg); + } + warned = true; + } + return fn.apply(this, arguments); + } + + return deprecated; }; -exports.writeIEEE754 = function(buffer, value, offset, isBE, mLen, nBytes) { - var e, m, c, - eLen = nBytes * 8 - mLen - 1, - eMax = (1 << eLen) - 1, - eBias = eMax >> 1, - rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0), - i = isBE ? (nBytes - 1) : 0, - d = isBE ? -1 : 1, - s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0; - value = Math.abs(value); - - if (isNaN(value) || value === Infinity) { - m = isNaN(value) ? 1 : 0; - e = eMax; - } else { - e = Math.floor(Math.log(value) / Math.LN2); - if (value * (c = Math.pow(2, -e)) < 1) { - e--; - c *= 2; - } - if (e + eBias >= 1) { - value += rt / c; +var debugs = {}; +var debugEnviron; +exports.debuglog = function(set) { + if (isUndefined(debugEnviron)) + debugEnviron = process.env.NODE_DEBUG || ''; + set = set.toUpperCase(); + if (!debugs[set]) { + if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) { + var pid = process.pid; + debugs[set] = function() { + var msg = exports.format.apply(exports, arguments); + console.error('%s %d: %s', set, pid, msg); + }; } else { - value += rt * Math.pow(2, 1 - eBias); - } - if (value * c >= 2) { - e++; - c /= 2; - } - - if (e + eBias >= eMax) { - m = 0; - e = eMax; - } else if (e + eBias >= 1) { - m = (value * c - 1) * Math.pow(2, mLen); - e = e + eBias; - } else { - m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen); - e = 0; + debugs[set] = function() {}; } } - - for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8); - - e = (e << mLen) | m; - eLen += mLen; - for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8); - - buffer[offset + i - d] |= s * 128; + return debugs[set]; }; -},{}],17:[function(req,module,exports){ -(function(){var assert = req('assert'); -exports.Buffer = Buffer; -exports.SlowBuffer = Buffer; -Buffer.poolSize = 8192; -exports.INSPECT_MAX_BYTES = 50; -function Buffer(subject, encoding, offset) { - if (!(this instanceof Buffer)) { - return new Buffer(subject, encoding, offset); +/** + * Echos the value of a value. Trys to print the value out + * in the best way possible given the different types. + * + * @param {Object} obj The object to print out. + * @param {Object} opts Optional options object that alters the output. + */ +/* legacy: obj, showHidden, depth, colors*/ +function inspect(obj, opts) { + // default options + var ctx = { + seen: [], + stylize: stylizeNoColor + }; + // legacy... + if (arguments.length >= 3) ctx.depth = arguments[2]; + if (arguments.length >= 4) ctx.colors = arguments[3]; + if (isBoolean(opts)) { + // legacy... + ctx.showHidden = opts; + } else if (opts) { + // got an "options" object + exports._extend(ctx, opts); } - this.parent = this; - this.offset = 0; + // set default options + if (isUndefined(ctx.showHidden)) ctx.showHidden = false; + if (isUndefined(ctx.depth)) ctx.depth = 2; + if (isUndefined(ctx.colors)) ctx.colors = false; + if (isUndefined(ctx.customInspect)) ctx.customInspect = true; + if (ctx.colors) ctx.stylize = stylizeWithColor; + return formatValue(ctx, obj, ctx.depth); +} +exports.inspect = inspect; - var type; - // Are we slicing? - if (typeof offset === 'number') { - this.length = coerce(encoding); - this.offset = offset; +// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics +inspect.colors = { + 'bold' : [1, 22], + 'italic' : [3, 23], + 'underline' : [4, 24], + 'inverse' : [7, 27], + 'white' : [37, 39], + 'grey' : [90, 39], + 'black' : [30, 39], + 'blue' : [34, 39], + 'cyan' : [36, 39], + 'green' : [32, 39], + 'magenta' : [35, 39], + 'red' : [31, 39], + 'yellow' : [33, 39] +}; + +// Don't use 'blue' not visible on cmd.exe +inspect.styles = { + 'special': 'cyan', + 'number': 'yellow', + 'boolean': 'yellow', + 'undefined': 'grey', + 'null': 'bold', + 'string': 'green', + 'date': 'magenta', + // "name": intentionally not styling + 'regexp': 'red' +}; + + +function stylizeWithColor(str, styleType) { + var style = inspect.styles[styleType]; + + if (style) { + return '\u001b[' + inspect.colors[style][0] + 'm' + str + + '\u001b[' + inspect.colors[style][1] + 'm'; } else { - // Find the length - switch (type = typeof subject) { - case 'number': - this.length = coerce(subject); - break; + return str; + } +} - case 'string': - this.length = Buffer.byteLength(subject, encoding); - break; - case 'object': // Assume object is an array - this.length = coerce(subject.length); - break; +function stylizeNoColor(str, styleType) { + return str; +} + +function arrayToHash(array) { + var hash = {}; + + array.forEach(function(val, idx) { + hash[val] = true; + }); + + return hash; +} + + +function formatValue(ctx, value, recurseTimes) { + // Provide a hook for user-specified inspect functions. + // Check that value is an object with an inspect function on it + if (ctx.customInspect && + value && + isFunction(value.inspect) && + // Filter out the util module, it's inspect function is special + value.inspect !== exports.inspect && + // Also filter out any prototype objects using the circular check. + !(value.constructor && value.constructor.prototype === value)) { + var ret = value.inspect(recurseTimes, ctx); + if (!isString(ret)) { + ret = formatValue(ctx, ret, recurseTimes); + } + return ret; + } + + // Primitive types cannot have properties + var primitive = formatPrimitive(ctx, value); + if (primitive) { + return primitive; + } + + // Look up the keys of the object. + var keys = Object.keys(value); + var visibleKeys = arrayToHash(keys); + + if (ctx.showHidden) { + keys = Object.getOwnPropertyNames(value); + } + + // IE doesn't make error fields non-enumerable + // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx + if (isError(value) + && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) { + return formatError(value); + } + + // Some type of object without properties can be shortcutted. + if (keys.length === 0) { + if (isFunction(value)) { + var name = value.name ? ': ' + value.name : ''; + return ctx.stylize('[Function' + name + ']', 'special'); + } + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } + if (isDate(value)) { + return ctx.stylize(Date.prototype.toString.call(value), 'date'); + } + if (isError(value)) { + return formatError(value); + } + } + + var base = '', array = false, braces = ['{', '}']; + + // Make Array say that they are Array + if (isArray(value)) { + array = true; + braces = ['[', ']']; + } + + // Make functions say that they are functions + if (isFunction(value)) { + var n = value.name ? ': ' + value.name : ''; + base = ' [Function' + n + ']'; + } + + // Make RegExps say that they are RegExps + if (isRegExp(value)) { + base = ' ' + RegExp.prototype.toString.call(value); + } + + // Make dates with properties first say the date + if (isDate(value)) { + base = ' ' + Date.prototype.toUTCString.call(value); + } + + // Make error with message first say the error + if (isError(value)) { + base = ' ' + formatError(value); + } + + if (keys.length === 0 && (!array || value.length == 0)) { + return braces[0] + base + braces[1]; + } + + if (recurseTimes < 0) { + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } else { + return ctx.stylize('[Object]', 'special'); + } + } + + ctx.seen.push(value); + + var output; + if (array) { + output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); + } else { + output = keys.map(function(key) { + return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); + }); + } + + ctx.seen.pop(); + + return reduceToSingleString(output, base, braces); +} + + +function formatPrimitive(ctx, value) { + if (isUndefined(value)) + return ctx.stylize('undefined', 'undefined'); + if (isString(value)) { + var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') + .replace(/'/g, "\\'") + .replace(/\\"/g, '"') + '\''; + return ctx.stylize(simple, 'string'); + } + if (isNumber(value)) + return ctx.stylize('' + value, 'number'); + if (isBoolean(value)) + return ctx.stylize('' + value, 'boolean'); + // For some reason typeof null is "object", so special case here. + if (isNull(value)) + return ctx.stylize('null', 'null'); +} + + +function formatError(value) { + return '[' + Error.prototype.toString.call(value) + ']'; +} + + +function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { + var output = []; + for (var i = 0, l = value.length; i < l; ++i) { + if (hasOwnProperty(value, String(i))) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + String(i), true)); + } else { + output.push(''); + } + } + keys.forEach(function(key) { + if (!key.match(/^\d+$/)) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + key, true)); + } + }); + return output; +} + + +function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { + var name, str, desc; + desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; + if (desc.get) { + if (desc.set) { + str = ctx.stylize('[Getter/Setter]', 'special'); + } else { + str = ctx.stylize('[Getter]', 'special'); + } + } else { + if (desc.set) { + str = ctx.stylize('[Setter]', 'special'); + } + } + if (!hasOwnProperty(visibleKeys, key)) { + name = '[' + key + ']'; + } + if (!str) { + if (ctx.seen.indexOf(desc.value) < 0) { + if (isNull(recurseTimes)) { + str = formatValue(ctx, desc.value, null); + } else { + str = formatValue(ctx, desc.value, recurseTimes - 1); + } + if (str.indexOf('\n') > -1) { + if (array) { + str = str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n').substr(2); + } else { + str = '\n' + str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n'); + } + } + } else { + str = ctx.stylize('[Circular]', 'special'); + } + } + if (isUndefined(name)) { + if (array && key.match(/^\d+$/)) { + return str; + } + name = JSON.stringify('' + key); + if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { + name = name.substr(1, name.length - 2); + name = ctx.stylize(name, 'name'); + } else { + name = name.replace(/'/g, "\\'") + .replace(/\\"/g, '"') + .replace(/(^"|"$)/g, "'"); + name = ctx.stylize(name, 'string'); + } + } + + return name + ': ' + str; +} + + +function reduceToSingleString(output, base, braces) { + var numLinesEst = 0; + var length = output.reduce(function(prev, cur) { + numLinesEst++; + if (cur.indexOf('\n') >= 0) numLinesEst++; + return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; + }, 0); + + if (length > 60) { + return braces[0] + + (base === '' ? '' : base + '\n ') + + ' ' + + output.join(',\n ') + + ' ' + + braces[1]; + } + + return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; +} + + +// NOTE: These type checking functions intentionally don't use `instanceof` +// because it is fragile and can be easily faked with `Object.create()`. +function isArray(ar) { + return Array.isArray(ar); +} +exports.isArray = isArray; + +function isBoolean(arg) { + return typeof arg === 'boolean'; +} +exports.isBoolean = isBoolean; + +function isNull(arg) { + return arg === null; +} +exports.isNull = isNull; + +function isNullOrUndefined(arg) { + return arg == null; +} +exports.isNullOrUndefined = isNullOrUndefined; + +function isNumber(arg) { + return typeof arg === 'number'; +} +exports.isNumber = isNumber; + +function isString(arg) { + return typeof arg === 'string'; +} +exports.isString = isString; + +function isSymbol(arg) { + return typeof arg === 'symbol'; +} +exports.isSymbol = isSymbol; + +function isUndefined(arg) { + return arg === void 0; +} +exports.isUndefined = isUndefined; + +function isRegExp(re) { + return isObject(re) && objectToString(re) === '[object RegExp]'; +} +exports.isRegExp = isRegExp; + +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} +exports.isObject = isObject; + +function isDate(d) { + return isObject(d) && objectToString(d) === '[object Date]'; +} +exports.isDate = isDate; + +function isError(e) { + return isObject(e) && + (objectToString(e) === '[object Error]' || e instanceof Error); +} +exports.isError = isError; + +function isFunction(arg) { + return typeof arg === 'function'; +} +exports.isFunction = isFunction; + +function isPrimitive(arg) { + return arg === null || + typeof arg === 'boolean' || + typeof arg === 'number' || + typeof arg === 'string' || + typeof arg === 'symbol' || // ES6 symbol + typeof arg === 'undefined'; +} +exports.isPrimitive = isPrimitive; + +exports.isBuffer = _dereq_('./support/isBuffer'); + +function objectToString(o) { + return Object.prototype.toString.call(o); +} + + +function pad(n) { + return n < 10 ? '0' + n.toString(10) : n.toString(10); +} + + +var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', + 'Oct', 'Nov', 'Dec']; + +// 26 Feb 16:19:34 +function timestamp() { + var d = new Date(); + var time = [pad(d.getHours()), + pad(d.getMinutes()), + pad(d.getSeconds())].join(':'); + return [d.getDate(), months[d.getMonth()], time].join(' '); +} + + +// log is just a thin wrapper to console.log that prepends a timestamp +exports.log = function() { + console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); +}; + + +/** + * Inherit the prototype methods from one constructor into another. + * + * The Function.prototype.inherits from lang.js rewritten as a standalone + * function (not on Function.prototype). NOTE: If this file is to be loaded + * during bootstrapping this function needs to be rewritten using some native + * functions as prototype setup using normal JavaScript does not work as + * expected during bootstrapping (see mirror.js in r114903). + * + * @param {function} ctor Constructor function which needs to inherit the + * prototype. + * @param {function} superCtor Constructor function to inherit prototype from. + */ +exports.inherits = _dereq_('inherits'); + +exports._extend = function(origin, add) { + // Don't do anything if add isn't an object + if (!add || !isObject(add)) return origin; + + var keys = Object.keys(add); + var i = keys.length; + while (i--) { + origin[keys[i]] = add[keys[i]]; + } + return origin; +}; + +function hasOwnProperty(obj, prop) { + return Object.prototype.hasOwnProperty.call(obj, prop); +} + +}).call(this,_dereq_("H:\\node\\npm\\node_modules\\browserify\\node_modules\\insert-module-globals\\node_modules\\process\\browser.js"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +}, +{"./support/isBuffer":14,"H:\\node\\npm\\node_modules\\browserify\\node_modules\\insert-module-globals\\node_modules\\process\\browser.js":18,"inherits":17}], +16:[function(_dereq_,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +function EventEmitter() { + this._events = this._events || {}; + this._maxListeners = this._maxListeners || undefined; +} +module.exports = EventEmitter; + +// Backwards-compat with node 0.10.x +EventEmitter.EventEmitter = EventEmitter; + +EventEmitter.prototype._events = undefined; +EventEmitter.prototype._maxListeners = undefined; + +// By default EventEmitters will print a warning if more than 10 listeners are +// added to it. This is a useful default which helps finding memory leaks. +EventEmitter.defaultMaxListeners = 10; + +// Obviously not all Emitters should be limited to 10. This function allows +// that to be increased. Set to zero for unlimited. +EventEmitter.prototype.setMaxListeners = function(n) { + if (!isNumber(n) || n < 0 || isNaN(n)) + throw TypeError('n must be a positive number'); + this._maxListeners = n; + return this; +}; + +EventEmitter.prototype.emit = function(type) { + var er, handler, len, args, i, listeners; + + if (!this._events) + this._events = {}; + + // If there is no 'error' event listener then throw. + if (type === 'error') { + if (!this._events.error || + (isObject(this._events.error) && !this._events.error.length)) { + er = arguments[1]; + if (er instanceof Error) { + throw er; // Unhandled 'error' event + } else { + throw TypeError('Uncaught, unspecified "error" event.'); + } + return false; + } + } + + handler = this._events[type]; + + if (isUndefined(handler)) + return false; + + if (isFunction(handler)) { + switch (arguments.length) { + // fast cases + case 1: + handler.call(this); + break; + case 2: + handler.call(this, arguments[1]); + break; + case 3: + handler.call(this, arguments[1], arguments[2]); + break; + // slower default: - throw new Error('First argument needs to be a number, ' + - 'array or string.'); + len = arguments.length; + args = new Array(len - 1); + for (i = 1; i < len; i++) + args[i - 1] = arguments[i]; + handler.apply(this, args); + } + } else if (isObject(handler)) { + len = arguments.length; + args = new Array(len - 1); + for (i = 1; i < len; i++) + args[i - 1] = arguments[i]; + + listeners = handler.slice(); + len = listeners.length; + for (i = 0; i < len; i++) + listeners[i].apply(this, args); + } + + return true; +}; + +EventEmitter.prototype.addListener = function(type, listener) { + var m; + + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + if (!this._events) + this._events = {}; + + // To avoid recursion in the case that type === "newListener"! Before + // adding it to the listeners, first emit "newListener". + if (this._events.newListener) + this.emit('newListener', type, + isFunction(listener.listener) ? + listener.listener : listener); + + if (!this._events[type]) + // Optimize the case of one listener. Don't need the extra array object. + this._events[type] = listener; + else if (isObject(this._events[type])) + // If we've already got an array, just append. + this._events[type].push(listener); + else + // Adding the second element, need to change to array. + this._events[type] = [this._events[type], listener]; + + // Check for listener leak + if (isObject(this._events[type]) && !this._events[type].warned) { + var m; + if (!isUndefined(this._maxListeners)) { + m = this._maxListeners; + } else { + m = EventEmitter.defaultMaxListeners; } - // Treat array-ish objects as a byte array. - if (isArrayIsh(subject)) { - for (var i = 0; i < this.length; i++) { - if (subject instanceof Buffer) { - this[i] = subject.readUInt8(i); - } - else { - this[i] = subject[i]; - } - } - } else if (type == 'string') { - // We are a string - this.length = this.write(subject, 0, encoding); - } else if (type === 'number') { - for (var i = 0; i < this.length; i++) { - this[i] = 0; - } + if (m && m > 0 && this._events[type].length > m) { + this._events[type].warned = true; + console.error('(node) warning: possible EventEmitter memory ' + + 'leak detected. %d listeners added. ' + + 'Use emitter.setMaxListeners() to increase limit.', + this._events[type].length); + console.trace(); } } -} -Buffer.prototype.get = function get(i) { - if (i < 0 || i >= this.length) throw new Error('oob'); - return this[i]; + return this; }; -Buffer.prototype.set = function set(i, v) { - if (i < 0 || i >= this.length) throw new Error('oob'); - return this[i] = v; -}; +EventEmitter.prototype.on = EventEmitter.prototype.addListener; -Buffer.byteLength = function (str, encoding) { - switch (encoding || "utf8") { - case 'hex': - return str.length / 2; +EventEmitter.prototype.once = function(type, listener) { + if (!isFunction(listener)) + throw TypeError('listener must be a function'); - case 'utf8': - case 'utf-8': - return utf8ToBytes(str).length; + var fired = false; - case 'ascii': - case 'binary': - return str.length; + function g() { + this.removeListener(type, g); - case 'base64': - return base64ToBytes(str).length; - - default: - throw new Error('Unknown encoding'); - } -}; - -Buffer.prototype.utf8Write = function (string, offset, length) { - var bytes, pos; - return Buffer._charsWritten = blitBuffer(utf8ToBytes(string), this, offset, length); -}; - -Buffer.prototype.asciiWrite = function (string, offset, length) { - var bytes, pos; - return Buffer._charsWritten = blitBuffer(asciiToBytes(string), this, offset, length); -}; - -Buffer.prototype.binaryWrite = Buffer.prototype.asciiWrite; - -Buffer.prototype.base64Write = function (string, offset, length) { - var bytes, pos; - return Buffer._charsWritten = blitBuffer(base64ToBytes(string), this, offset, length); -}; - -Buffer.prototype.base64Slice = function (start, end) { - var bytes = Array.prototype.slice.apply(this, arguments) - return req("base64-js").fromByteArray(bytes); -}; - -Buffer.prototype.utf8Slice = function () { - var bytes = Array.prototype.slice.apply(this, arguments); - var res = ""; - var tmp = ""; - var i = 0; - while (i < bytes.length) { - if (bytes[i] <= 0x7F) { - res += decodeUtf8Char(tmp) + String.fromCharCode(bytes[i]); - tmp = ""; - } else - tmp += "%" + bytes[i].toString(16); - - i++; + if (!fired) { + fired = true; + listener.apply(this, arguments); + } } - return res + decodeUtf8Char(tmp); -} + g.listener = listener; + this.on(type, g); -Buffer.prototype.asciiSlice = function () { - var bytes = Array.prototype.slice.apply(this, arguments); - var ret = ""; - for (var i = 0; i < bytes.length; i++) - ret += String.fromCharCode(bytes[i]); + return this; +}; + +// emits a 'removeListener' event iff the listener was removed +EventEmitter.prototype.removeListener = function(type, listener) { + var list, position, length, i; + + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + if (!this._events || !this._events[type]) + return this; + + list = this._events[type]; + length = list.length; + position = -1; + + if (list === listener || + (isFunction(list.listener) && list.listener === listener)) { + delete this._events[type]; + if (this._events.removeListener) + this.emit('removeListener', type, listener); + + } else if (isObject(list)) { + for (i = length; i-- > 0;) { + if (list[i] === listener || + (list[i].listener && list[i].listener === listener)) { + position = i; + break; + } + } + + if (position < 0) + return this; + + if (list.length === 1) { + list.length = 0; + delete this._events[type]; + } else { + list.splice(position, 1); + } + + if (this._events.removeListener) + this.emit('removeListener', type, listener); + } + + return this; +}; + +EventEmitter.prototype.removeAllListeners = function(type) { + var key, listeners; + + if (!this._events) + return this; + + // not listening for removeListener, no need to emit + if (!this._events.removeListener) { + if (arguments.length === 0) + this._events = {}; + else if (this._events[type]) + delete this._events[type]; + return this; + } + + // emit removeListener for all listeners on all events + if (arguments.length === 0) { + for (key in this._events) { + if (key === 'removeListener') continue; + this.removeAllListeners(key); + } + this.removeAllListeners('removeListener'); + this._events = {}; + return this; + } + + listeners = this._events[type]; + + if (isFunction(listeners)) { + this.removeListener(type, listeners); + } else { + // LIFO order + while (listeners.length) + this.removeListener(type, listeners[listeners.length - 1]); + } + delete this._events[type]; + + return this; +}; + +EventEmitter.prototype.listeners = function(type) { + var ret; + if (!this._events || !this._events[type]) + ret = []; + else if (isFunction(this._events[type])) + ret = [this._events[type]]; + else + ret = this._events[type].slice(); return ret; +}; + +EventEmitter.listenerCount = function(emitter, type) { + var ret; + if (!emitter._events || !emitter._events[type]) + ret = 0; + else if (isFunction(emitter._events[type])) + ret = 1; + else + ret = emitter._events[type].length; + return ret; +}; + +function isFunction(arg) { + return typeof arg === 'function'; } -Buffer.prototype.binarySlice = Buffer.prototype.asciiSlice; +function isNumber(arg) { + return typeof arg === 'number'; +} -Buffer.prototype.inspect = function() { - var out = [], - len = this.length; - for (var i = 0; i < len; i++) { - out[i] = toHex(this[i]); - if (i == exports.INSPECT_MAX_BYTES) { - out[i + 1] = '...'; - break; - } - } - return ''; -}; +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} +function isUndefined(arg) { + return arg === void 0; +} -Buffer.prototype.hexSlice = function(start, end) { - var len = this.length; - - if (!start || start < 0) start = 0; - if (!end || end < 0 || end > len) end = len; - - var out = ''; - for (var i = start; i < end; i++) { - out += toHex(this[i]); - } - return out; -}; - - -Buffer.prototype.toString = function(encoding, start, end) { - encoding = String(encoding || 'utf8').toLowerCase(); - start = +start || 0; - if (typeof end == 'undefined') end = this.length; - - // Fastpath empty strings - if (+end == start) { - return ''; - } - - switch (encoding) { - case 'hex': - return this.hexSlice(start, end); - - case 'utf8': - case 'utf-8': - return this.utf8Slice(start, end); - - case 'ascii': - return this.asciiSlice(start, end); - - case 'binary': - return this.binarySlice(start, end); - - case 'base64': - return this.base64Slice(start, end); - - case 'ucs2': - case 'ucs-2': - return this.ucs2Slice(start, end); - - default: - throw new Error('Unknown encoding'); - } -}; - - -Buffer.prototype.hexWrite = function(string, offset, length) { - offset = +offset || 0; - var remaining = this.length - offset; - if (!length) { - length = remaining; - } else { - length = +length; - if (length > remaining) { - length = remaining; - } - } - - // must be an even number of digits - var strLen = string.length; - if (strLen % 2) { - throw new Error('Invalid hex string'); - } - if (length > strLen / 2) { - length = strLen / 2; - } - for (var i = 0; i < length; i++) { - var byte = parseInt(string.substr(i * 2, 2), 16); - if (isNaN(byte)) throw new Error('Invalid hex string'); - this[offset + i] = byte; - } - Buffer._charsWritten = i * 2; - return i; -}; - - -Buffer.prototype.write = function(string, offset, length, encoding) { - // Support both (string, offset, length, encoding) - // and the legacy (string, encoding, offset, length) - if (isFinite(offset)) { - if (!isFinite(length)) { - encoding = length; - length = undefined; - } - } else { // legacy - var swap = encoding; - encoding = offset; - offset = length; - length = swap; - } - - offset = +offset || 0; - var remaining = this.length - offset; - if (!length) { - length = remaining; - } else { - length = +length; - if (length > remaining) { - length = remaining; - } - } - encoding = String(encoding || 'utf8').toLowerCase(); - - switch (encoding) { - case 'hex': - return this.hexWrite(string, offset, length); - - case 'utf8': - case 'utf-8': - return this.utf8Write(string, offset, length); - - case 'ascii': - return this.asciiWrite(string, offset, length); - - case 'binary': - return this.binaryWrite(string, offset, length); - - case 'base64': - return this.base64Write(string, offset, length); - - case 'ucs2': - case 'ucs-2': - return this.ucs2Write(string, offset, length); - - default: - throw new Error('Unknown encoding'); - } -}; - - -// slice(start, end) -Buffer.prototype.slice = function(start, end) { - if (end === undefined) end = this.length; - - if (end > this.length) { - throw new Error('oob'); - } - if (start > end) { - throw new Error('oob'); - } - - return new Buffer(this, end - start, +start); -}; - -// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) -Buffer.prototype.copy = function(target, target_start, start, end) { - var source = this; - start || (start = 0); - if (end === undefined || isNaN(end)) { - end = this.length; - } - target_start || (target_start = 0); - - if (end < start) throw new Error('sourceEnd < sourceStart'); - - // Copy 0 bytes; we're done - if (end === start) return 0; - if (target.length == 0 || source.length == 0) return 0; - - if (target_start < 0 || target_start >= target.length) { - throw new Error('targetStart out of bounds'); - } - - if (start < 0 || start >= source.length) { - throw new Error('sourceStart out of bounds'); - } - - if (end < 0 || end > source.length) { - throw new Error('sourceEnd out of bounds'); - } - - // Are we oob? - if (end > this.length) { - end = this.length; - } - - if (target.length - target_start < end - start) { - end = target.length - target_start + start; - } - - var temp = []; - for (var i=start; i= this.length) { - throw new Error('start out of bounds'); - } - - if (end < 0 || end > this.length) { - throw new Error('end out of bounds'); - } - - for (var i = start; i < end; i++) { - this[i] = value; +}, +{}], +17:[function(_dereq_,module,exports){ +if (typeof Object.create === 'function') { + // implementation from standard node.js 'util' module + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + ctor.prototype = Object.create(superCtor.prototype, { + constructor: { + value: ctor, + enumerable: false, + writable: true, + configurable: true + } + }); + }; +} else { + // old school shim for old browsers + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + var TempCtor = function () {} + TempCtor.prototype = superCtor.prototype + ctor.prototype = new TempCtor() + ctor.prototype.constructor = ctor } } -// Static methods -Buffer.isBuffer = function isBuffer(b) { - return b instanceof Buffer || b instanceof Buffer; -}; - -Buffer.concat = function (list, totalLength) { - if (!isArray(list)) { - throw new Error("Usage: Buffer.concat(list, [totalLength])\n \ - list should be an Array."); - } - - if (list.length === 0) { - return new Buffer(0); - } else if (list.length === 1) { - return list[0]; - } - - if (typeof totalLength !== 'number') { - totalLength = 0; - for (var i = 0; i < list.length; i++) { - var buf = list[i]; - totalLength += buf.length; - } - } - - var buffer = new Buffer(totalLength); - var pos = 0; - for (var i = 0; i < list.length; i++) { - var buf = list[i]; - buf.copy(buffer, pos); - pos += buf.length; - } - return buffer; -}; - -// helpers - -function coerce(length) { - // Coerce length to a number (possibly NaN), round up - // in case it's fractional (e.g. 123.456) then do a - // double negate to coerce a NaN to 0. Easy, right? - length = ~~Math.ceil(+length); - return length < 0 ? 0 : length; -} - -function isArray(subject) { - return (Array.isArray || - function(subject){ - return {}.toString.apply(subject) == '[object Array]' - }) - (subject) -} - -function isArrayIsh(subject) { - return isArray(subject) || Buffer.isBuffer(subject) || - subject && typeof subject === 'object' && - typeof subject.length === 'number'; -} - -function toHex(n) { - if (n < 16) return '0' + n.toString(16); - return n.toString(16); -} - -function utf8ToBytes(str) { - var byteArray = []; - for (var i = 0; i < str.length; i++) - if (str.charCodeAt(i) <= 0x7F) - byteArray.push(str.charCodeAt(i)); - else { - var h = encodeURIComponent(str.charAt(i)).substr(1).split('%'); - for (var j = 0; j < h.length; j++) - byteArray.push(parseInt(h[j], 16)); - } - - return byteArray; -} - -function asciiToBytes(str) { - var byteArray = [] - for (var i = 0; i < str.length; i++ ) - // Node's code seems to be doing this and not & 0x7F.. - byteArray.push( str.charCodeAt(i) & 0xFF ); - - return byteArray; -} - -function base64ToBytes(str) { - return req("base64-js").toByteArray(str); -} - -function blitBuffer(src, dst, offset, length) { - var pos, i = 0; - while (i < length) { - if ((i+offset >= dst.length) || (i >= src.length)) - break; - - dst[i + offset] = src[i]; - i++; - } - return i; -} - -function decodeUtf8Char(str) { - try { - return decodeURIComponent(str); - } catch (err) { - return String.fromCharCode(0xFFFD); // UTF 8 invalid char - } -} - -// read/write bit-twiddling - -Buffer.prototype.readUInt8 = function(offset, noAssert) { - var buffer = this; - - if (!noAssert) { - assert.ok(offset !== undefined && offset !== null, - 'missing offset'); - - assert.ok(offset < buffer.length, - 'Trying to read beyond buffer length'); - } - - if (offset >= buffer.length) return; - - return buffer[offset]; -}; - -function readUInt16(buffer, offset, isBigEndian, noAssert) { - var val = 0; - - - if (!noAssert) { - assert.ok(typeof (isBigEndian) === 'boolean', - 'missing or invalid endian'); - - assert.ok(offset !== undefined && offset !== null, - 'missing offset'); - - assert.ok(offset + 1 < buffer.length, - 'Trying to read beyond buffer length'); - } - - if (offset >= buffer.length) return 0; - - if (isBigEndian) { - val = buffer[offset] << 8; - if (offset + 1 < buffer.length) { - val |= buffer[offset + 1]; - } - } else { - val = buffer[offset]; - if (offset + 1 < buffer.length) { - val |= buffer[offset + 1] << 8; - } - } - - return val; -} - -Buffer.prototype.readUInt16LE = function(offset, noAssert) { - return readUInt16(this, offset, false, noAssert); -}; - -Buffer.prototype.readUInt16BE = function(offset, noAssert) { - return readUInt16(this, offset, true, noAssert); -}; - -function readUInt32(buffer, offset, isBigEndian, noAssert) { - var val = 0; - - if (!noAssert) { - assert.ok(typeof (isBigEndian) === 'boolean', - 'missing or invalid endian'); - - assert.ok(offset !== undefined && offset !== null, - 'missing offset'); - - assert.ok(offset + 3 < buffer.length, - 'Trying to read beyond buffer length'); - } - - if (offset >= buffer.length) return 0; - - if (isBigEndian) { - if (offset + 1 < buffer.length) - val = buffer[offset + 1] << 16; - if (offset + 2 < buffer.length) - val |= buffer[offset + 2] << 8; - if (offset + 3 < buffer.length) - val |= buffer[offset + 3]; - val = val + (buffer[offset] << 24 >>> 0); - } else { - if (offset + 2 < buffer.length) - val = buffer[offset + 2] << 16; - if (offset + 1 < buffer.length) - val |= buffer[offset + 1] << 8; - val |= buffer[offset]; - if (offset + 3 < buffer.length) - val = val + (buffer[offset + 3] << 24 >>> 0); - } - - return val; -} - -Buffer.prototype.readUInt32LE = function(offset, noAssert) { - return readUInt32(this, offset, false, noAssert); -}; - -Buffer.prototype.readUInt32BE = function(offset, noAssert) { - return readUInt32(this, offset, true, noAssert); -}; - - -/* - * Signed integer types, yay team! A reminder on how two's complement actually - * works. The first bit is the signed bit, i.e. tells us whether or not the - * number should be positive or negative. If the two's complement value is - * positive, then we're done, as it's equivalent to the unsigned representation. - * - * Now if the number is positive, you're pretty much done, you can just leverage - * the unsigned translations and return those. Unfortunately, negative numbers - * aren't quite that straightforward. - * - * At first glance, one might be inclined to use the traditional formula to - * translate binary numbers between the positive and negative values in two's - * complement. (Though it doesn't quite work for the most negative value) - * Mainly: - * - invert all the bits - * - add one to the result - * - * Of course, this doesn't quite work in Javascript. Take for example the value - * of -128. This could be represented in 16 bits (big-endian) as 0xff80. But of - * course, Javascript will do the following: - * - * > ~0xff80 - * -65409 - * - * Whoh there, Javascript, that's not quite right. But wait, according to - * Javascript that's perfectly correct. When Javascript ends up seeing the - * constant 0xff80, it has no notion that it is actually a signed number. It - * assumes that we've input the unsigned value 0xff80. Thus, when it does the - * binary negation, it casts it into a signed value, (positive 0xff80). Then - * when you perform binary negation on that, it turns it into a negative number. - * - * Instead, we're going to have to use the following general formula, that works - * in a rather Javascript friendly way. I'm glad we don't support this kind of - * weird numbering scheme in the kernel. - * - * (BIT-MAX - (unsigned)val + 1) * -1 - * - * The astute observer, may think that this doesn't make sense for 8-bit numbers - * (really it isn't necessary for them). However, when you get 16-bit numbers, - * you do. Let's go back to our prior example and see how this will look: - * - * (0xffff - 0xff80 + 1) * -1 - * (0x007f + 1) * -1 - * (0x0080) * -1 - */ -Buffer.prototype.readInt8 = function(offset, noAssert) { - var buffer = this; - var neg; - - if (!noAssert) { - assert.ok(offset !== undefined && offset !== null, - 'missing offset'); - - assert.ok(offset < buffer.length, - 'Trying to read beyond buffer length'); - } - - if (offset >= buffer.length) return; - - neg = buffer[offset] & 0x80; - if (!neg) { - return (buffer[offset]); - } - - return ((0xff - buffer[offset] + 1) * -1); -}; - -function readInt16(buffer, offset, isBigEndian, noAssert) { - var neg, val; - - if (!noAssert) { - assert.ok(typeof (isBigEndian) === 'boolean', - 'missing or invalid endian'); - - assert.ok(offset !== undefined && offset !== null, - 'missing offset'); - - assert.ok(offset + 1 < buffer.length, - 'Trying to read beyond buffer length'); - } - - val = readUInt16(buffer, offset, isBigEndian, noAssert); - neg = val & 0x8000; - if (!neg) { - return val; - } - - return (0xffff - val + 1) * -1; -} - -Buffer.prototype.readInt16LE = function(offset, noAssert) { - return readInt16(this, offset, false, noAssert); -}; - -Buffer.prototype.readInt16BE = function(offset, noAssert) { - return readInt16(this, offset, true, noAssert); -}; - -function readInt32(buffer, offset, isBigEndian, noAssert) { - var neg, val; - - if (!noAssert) { - assert.ok(typeof (isBigEndian) === 'boolean', - 'missing or invalid endian'); - - assert.ok(offset !== undefined && offset !== null, - 'missing offset'); - - assert.ok(offset + 3 < buffer.length, - 'Trying to read beyond buffer length'); - } - - val = readUInt32(buffer, offset, isBigEndian, noAssert); - neg = val & 0x80000000; - if (!neg) { - return (val); - } - - return (0xffffffff - val + 1) * -1; -} - -Buffer.prototype.readInt32LE = function(offset, noAssert) { - return readInt32(this, offset, false, noAssert); -}; - -Buffer.prototype.readInt32BE = function(offset, noAssert) { - return readInt32(this, offset, true, noAssert); -}; - -function readFloat(buffer, offset, isBigEndian, noAssert) { - if (!noAssert) { - assert.ok(typeof (isBigEndian) === 'boolean', - 'missing or invalid endian'); - - assert.ok(offset + 3 < buffer.length, - 'Trying to read beyond buffer length'); - } - - return req('./buffer_ieee754').readIEEE754(buffer, offset, isBigEndian, - 23, 4); -} - -Buffer.prototype.readFloatLE = function(offset, noAssert) { - return readFloat(this, offset, false, noAssert); -}; - -Buffer.prototype.readFloatBE = function(offset, noAssert) { - return readFloat(this, offset, true, noAssert); -}; - -function readDouble(buffer, offset, isBigEndian, noAssert) { - if (!noAssert) { - assert.ok(typeof (isBigEndian) === 'boolean', - 'missing or invalid endian'); - - assert.ok(offset + 7 < buffer.length, - 'Trying to read beyond buffer length'); - } - - return req('./buffer_ieee754').readIEEE754(buffer, offset, isBigEndian, - 52, 8); -} - -Buffer.prototype.readDoubleLE = function(offset, noAssert) { - return readDouble(this, offset, false, noAssert); -}; - -Buffer.prototype.readDoubleBE = function(offset, noAssert) { - return readDouble(this, offset, true, noAssert); -}; - - -/* - * We have to make sure that the value is a valid integer. This means that it is - * non-negative. It has no fractional component and that it does not exceed the - * maximum allowed value. - * - * value The number to check for validity - * - * max The maximum value - */ -function verifuint(value, max) { - assert.ok(typeof (value) == 'number', - 'cannot write a non-number as a number'); - - assert.ok(value >= 0, - 'specified a negative value for writing an unsigned value'); - - assert.ok(value <= max, 'value is larger than maximum value for type'); - - assert.ok(Math.floor(value) === value, 'value has a fractional component'); -} - -Buffer.prototype.writeUInt8 = function(value, offset, noAssert) { - var buffer = this; - - if (!noAssert) { - assert.ok(value !== undefined && value !== null, - 'missing value'); - - assert.ok(offset !== undefined && offset !== null, - 'missing offset'); - - assert.ok(offset < buffer.length, - 'trying to write beyond buffer length'); - - verifuint(value, 0xff); - } - - if (offset < buffer.length) { - buffer[offset] = value; - } -}; - -function writeUInt16(buffer, value, offset, isBigEndian, noAssert) { - if (!noAssert) { - assert.ok(value !== undefined && value !== null, - 'missing value'); - - assert.ok(typeof (isBigEndian) === 'boolean', - 'missing or invalid endian'); - - assert.ok(offset !== undefined && offset !== null, - 'missing offset'); - - assert.ok(offset + 1 < buffer.length, - 'trying to write beyond buffer length'); - - verifuint(value, 0xffff); - } - - for (var i = 0; i < Math.min(buffer.length - offset, 2); i++) { - buffer[offset + i] = - (value & (0xff << (8 * (isBigEndian ? 1 - i : i)))) >>> - (isBigEndian ? 1 - i : i) * 8; - } - -} - -Buffer.prototype.writeUInt16LE = function(value, offset, noAssert) { - writeUInt16(this, value, offset, false, noAssert); -}; - -Buffer.prototype.writeUInt16BE = function(value, offset, noAssert) { - writeUInt16(this, value, offset, true, noAssert); -}; - -function writeUInt32(buffer, value, offset, isBigEndian, noAssert) { - if (!noAssert) { - assert.ok(value !== undefined && value !== null, - 'missing value'); - - assert.ok(typeof (isBigEndian) === 'boolean', - 'missing or invalid endian'); - - assert.ok(offset !== undefined && offset !== null, - 'missing offset'); - - assert.ok(offset + 3 < buffer.length, - 'trying to write beyond buffer length'); - - verifuint(value, 0xffffffff); - } - - for (var i = 0; i < Math.min(buffer.length - offset, 4); i++) { - buffer[offset + i] = - (value >>> (isBigEndian ? 3 - i : i) * 8) & 0xff; - } -} - -Buffer.prototype.writeUInt32LE = function(value, offset, noAssert) { - writeUInt32(this, value, offset, false, noAssert); -}; - -Buffer.prototype.writeUInt32BE = function(value, offset, noAssert) { - writeUInt32(this, value, offset, true, noAssert); -}; - - -/* - * We now move onto our friends in the signed number category. Unlike unsigned - * numbers, we're going to have to worry a bit more about how we put values into - * arrays. Since we are only worrying about signed 32-bit values, we're in - * slightly better shape. Unfortunately, we really can't do our favorite binary - * & in this system. It really seems to do the wrong thing. For example: - * - * > -32 & 0xff - * 224 - * - * What's happening above is really: 0xe0 & 0xff = 0xe0. However, the results of - * this aren't treated as a signed number. Ultimately a bad thing. - * - * What we're going to want to do is basically create the unsigned equivalent of - * our representation and pass that off to the wuint* functions. To do that - * we're going to do the following: - * - * - if the value is positive - * we can pass it directly off to the equivalent wuint - * - if the value is negative - * we do the following computation: - * mb + val + 1, where - * mb is the maximum unsigned value in that byte size - * val is the Javascript negative integer - * - * - * As a concrete value, take -128. In signed 16 bits this would be 0xff80. If - * you do out the computations: - * - * 0xffff - 128 + 1 - * 0xffff - 127 - * 0xff80 - * - * You can then encode this value as the signed version. This is really rather - * hacky, but it should work and get the job done which is our goal here. - */ - -/* - * A series of checks to make sure we actually have a signed 32-bit number - */ -function verifsint(value, max, min) { - assert.ok(typeof (value) == 'number', - 'cannot write a non-number as a number'); - - assert.ok(value <= max, 'value larger than maximum allowed value'); - - assert.ok(value >= min, 'value smaller than minimum allowed value'); - - assert.ok(Math.floor(value) === value, 'value has a fractional component'); -} - -function verifIEEE754(value, max, min) { - assert.ok(typeof (value) == 'number', - 'cannot write a non-number as a number'); - - assert.ok(value <= max, 'value larger than maximum allowed value'); - - assert.ok(value >= min, 'value smaller than minimum allowed value'); -} - -Buffer.prototype.writeInt8 = function(value, offset, noAssert) { - var buffer = this; - - if (!noAssert) { - assert.ok(value !== undefined && value !== null, - 'missing value'); - - assert.ok(offset !== undefined && offset !== null, - 'missing offset'); - - assert.ok(offset < buffer.length, - 'Trying to write beyond buffer length'); - - verifsint(value, 0x7f, -0x80); - } - - if (value >= 0) { - buffer.writeUInt8(value, offset, noAssert); - } else { - buffer.writeUInt8(0xff + value + 1, offset, noAssert); - } -}; - -function writeInt16(buffer, value, offset, isBigEndian, noAssert) { - if (!noAssert) { - assert.ok(value !== undefined && value !== null, - 'missing value'); - - assert.ok(typeof (isBigEndian) === 'boolean', - 'missing or invalid endian'); - - assert.ok(offset !== undefined && offset !== null, - 'missing offset'); - - assert.ok(offset + 1 < buffer.length, - 'Trying to write beyond buffer length'); - - verifsint(value, 0x7fff, -0x8000); - } - - if (value >= 0) { - writeUInt16(buffer, value, offset, isBigEndian, noAssert); - } else { - writeUInt16(buffer, 0xffff + value + 1, offset, isBigEndian, noAssert); - } -} - -Buffer.prototype.writeInt16LE = function(value, offset, noAssert) { - writeInt16(this, value, offset, false, noAssert); -}; - -Buffer.prototype.writeInt16BE = function(value, offset, noAssert) { - writeInt16(this, value, offset, true, noAssert); -}; - -function writeInt32(buffer, value, offset, isBigEndian, noAssert) { - if (!noAssert) { - assert.ok(value !== undefined && value !== null, - 'missing value'); - - assert.ok(typeof (isBigEndian) === 'boolean', - 'missing or invalid endian'); - - assert.ok(offset !== undefined && offset !== null, - 'missing offset'); - - assert.ok(offset + 3 < buffer.length, - 'Trying to write beyond buffer length'); - - verifsint(value, 0x7fffffff, -0x80000000); - } - - if (value >= 0) { - writeUInt32(buffer, value, offset, isBigEndian, noAssert); - } else { - writeUInt32(buffer, 0xffffffff + value + 1, offset, isBigEndian, noAssert); - } -} - -Buffer.prototype.writeInt32LE = function(value, offset, noAssert) { - writeInt32(this, value, offset, false, noAssert); -}; - -Buffer.prototype.writeInt32BE = function(value, offset, noAssert) { - writeInt32(this, value, offset, true, noAssert); -}; - -function writeFloat(buffer, value, offset, isBigEndian, noAssert) { - if (!noAssert) { - assert.ok(value !== undefined && value !== null, - 'missing value'); - - assert.ok(typeof (isBigEndian) === 'boolean', - 'missing or invalid endian'); - - assert.ok(offset !== undefined && offset !== null, - 'missing offset'); - - assert.ok(offset + 3 < buffer.length, - 'Trying to write beyond buffer length'); - - verifIEEE754(value, 3.4028234663852886e+38, -3.4028234663852886e+38); - } - - req('./buffer_ieee754').writeIEEE754(buffer, value, offset, isBigEndian, - 23, 4); -} - -Buffer.prototype.writeFloatLE = function(value, offset, noAssert) { - writeFloat(this, value, offset, false, noAssert); -}; - -Buffer.prototype.writeFloatBE = function(value, offset, noAssert) { - writeFloat(this, value, offset, true, noAssert); -}; - -function writeDouble(buffer, value, offset, isBigEndian, noAssert) { - if (!noAssert) { - assert.ok(value !== undefined && value !== null, - 'missing value'); - - assert.ok(typeof (isBigEndian) === 'boolean', - 'missing or invalid endian'); - - assert.ok(offset !== undefined && offset !== null, - 'missing offset'); - - assert.ok(offset + 7 < buffer.length, - 'Trying to write beyond buffer length'); - - verifIEEE754(value, 1.7976931348623157E+308, -1.7976931348623157E+308); - } - - req('./buffer_ieee754').writeIEEE754(buffer, value, offset, isBigEndian, - 52, 8); -} - -Buffer.prototype.writeDoubleLE = function(value, offset, noAssert) { - writeDouble(this, value, offset, false, noAssert); -}; - -Buffer.prototype.writeDoubleBE = function(value, offset, noAssert) { - writeDouble(this, value, offset, true, noAssert); -}; - -})() -},{"./buffer_ieee754":16,"assert":13,"base64-js":18}],18:[function(req,module,exports){ -(function (exports) { - 'use strict'; - - var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; - - function b64ToByteArray(b64) { - var i, j, l, tmp, placeHolders, arr; - - if (b64.length % 4 > 0) { - throw 'Invalid string. Length must be a multiple of 4'; - } - - // the number of equal signs (place holders) - // if there are two placeholders, than the two characters before it - // represent one byte - // if there is only one, then the three characters before it represent 2 bytes - // this is just a cheap hack to not do indexOf twice - placeHolders = b64.indexOf('='); - placeHolders = placeHolders > 0 ? b64.length - placeHolders : 0; - - // base64 is 4/3 + up to two characters of the original data - arr = [];//new Uint8Array(b64.length * 3 / 4 - placeHolders); - - // if there are placeholders, only get up to the last complete 4 chars - l = placeHolders > 0 ? b64.length - 4 : b64.length; - - for (i = 0, j = 0; i < l; i += 4, j += 3) { - tmp = (lookup.indexOf(b64[i]) << 18) | (lookup.indexOf(b64[i + 1]) << 12) | (lookup.indexOf(b64[i + 2]) << 6) | lookup.indexOf(b64[i + 3]); - arr.push((tmp & 0xFF0000) >> 16); - arr.push((tmp & 0xFF00) >> 8); - arr.push(tmp & 0xFF); - } - - if (placeHolders === 2) { - tmp = (lookup.indexOf(b64[i]) << 2) | (lookup.indexOf(b64[i + 1]) >> 4); - arr.push(tmp & 0xFF); - } else if (placeHolders === 1) { - tmp = (lookup.indexOf(b64[i]) << 10) | (lookup.indexOf(b64[i + 1]) << 4) | (lookup.indexOf(b64[i + 2]) >> 2); - arr.push((tmp >> 8) & 0xFF); - arr.push(tmp & 0xFF); - } - - return arr; - } - - function uint8ToBase64(uint8) { - var i, - extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes - output = "", - temp, length; - - function tripletToBase64 (num) { - return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F]; - }; - - // go through the array every three bytes, we'll deal with trailing stuff later - for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) { - temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]); - output += tripletToBase64(temp); - } - - // pad the end with zeros, but make sure to not forget the extra bytes - switch (extraBytes) { - case 1: - temp = uint8[uint8.length - 1]; - output += lookup[temp >> 2]; - output += lookup[(temp << 4) & 0x3F]; - output += '=='; - break; - case 2: - temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1]); - output += lookup[temp >> 10]; - output += lookup[(temp >> 4) & 0x3F]; - output += lookup[(temp << 2) & 0x3F]; - output += '='; - break; - } - - return output; - } - - module.exports.toByteArray = b64ToByteArray; - module.exports.fromByteArray = uint8ToBase64; -}()); - -},{}],"./lib/sax/SAXParser.js":[function(req,module,exports){ -module.exports=req('DaboPu'); -},{}],20:[function(req,module,exports){ +}, +{}], +18:[function(_dereq_,module,exports){ // shim for using process in browser var process = module.exports = {}; @@ -11072,7 +10372,8 @@ process.nextTick = (function () { if (canPost) { var queue = []; window.addEventListener('message', function (ev) { - if (ev.source === window && ev.data === 'process-tick') { + var source = ev.source; + if ((source === window || source === null) && ev.data === 'process-tick') { ev.stopPropagation(); if (queue.length > 0) { var fn = queue.shift(); @@ -11097,6 +10398,13 @@ process.browser = true; process.env = {}; process.argv = []; +function noop() {} + +process.on = noop; +process.once = noop; +process.off = noop; +process.emit = noop; + process.binding = function (name) { throw new Error('process.binding is not supported'); } @@ -11107,7 +10415,16 @@ process.chdir = function (dir) { throw new Error('process.chdir is not supported'); }; -},{}]},{},["DaboPu"]) -; -exports.SAXParser = req('./lib/sax/SAXParser.js').SAXParser; -}); +}, +{}], +19:[function(_dereq_,module,exports){ +module.exports=_dereq_(14) +}, +{}], +20:[function(_dereq_,module,exports){ +module.exports=_dereq_(15) +}, +{"./support/isBuffer":19,"H:\\node\\npm\\node_modules\\browserify\\node_modules\\insert-module-globals\\node_modules\\process\\browser.js":18,"inherits":17}]},{},[9]) +(9) + +}); \ No newline at end of file diff --git a/lib/ace/mode/javascript/jshint.js b/lib/ace/mode/javascript/jshint.js index 84254ffa..fb2039b6 100644 --- a/lib/ace/mode/javascript/jshint.js +++ b/lib/ace/mode/javascript/jshint.js @@ -1,14 +1,32 @@ define(function(require, exports, module) { -// 2.1.9 -require = null; -require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o= 65 && i <= 90 || // A-Z + i === 95 || // _ + i >= 97 && i <= 122; // a-z +} + +var identifierPartTable = []; + +for (var i = 0; i < 128; i++) { + identifierPartTable[i] = + identifierStartTable[i] || // $, _, A-Z, a-z + i >= 48 && i <= 57; // 0-9 +} + +module.exports = { + asciiIdentifierStartTable: identifierStartTable, + asciiIdentifierPartTable: identifierPartTable +}; + +}, +{}], +2:[function(_dereq_,module,exports){ // Underscore.js 1.4.4 // http://underscorejs.org // (c) 2009-2013 Jeremy Ashkenas, DocumentCloud Inc. @@ -1238,844 +1256,34 @@ require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof requ }, {}], -2:[function(req,module,exports){ -"use strict"; - -var _ = req("underscore"); - -var errors = { - // JSHint options - E001: "Bad option: '{a}'.", - E002: "Bad option value.", - - // JSHint input - E003: "Expected a JSON value.", - E004: "Input is neither a string nor an array of strings.", - E005: "Input is empty.", - E006: "Unexpected early end of program.", - - // Strict mode - E007: "Missing \"use strict\" statement.", - E008: "Strict violation.", - E009: "Option 'validthis' can't be used in a global scope.", - E010: "'with' is not allowed in strict mode.", - - // Constants - E011: "const '{a}' has already been declared.", - E012: "const '{a}' is initialized to 'undefined'.", - E013: "Attempting to override '{a}' which is a constant.", - - // Regular expressions - E014: "A regular expression literal can be confused with '/='.", - E015: "Unclosed regular expression.", - E016: "Invalid regular expression.", - - // Tokens - E017: "Unclosed comment.", - E018: "Unbegun comment.", - E019: "Unmatched '{a}'.", - E020: "Expected '{a}' to match '{b}' from line {c} and instead saw '{d}'.", - E021: "Expected '{a}' and instead saw '{b}'.", - E022: "Line breaking error '{a}'.", - E023: "Missing '{a}'.", - E024: "Unexpected '{a}'.", - E025: "Missing ':' on a case clause.", - E026: "Missing '}' to match '{' from line {a}.", - E027: "Missing ']' to match '[' form line {a}.", - E028: "Illegal comma.", - E029: "Unclosed string.", - - // Everything else - E030: "Expected an identifier and instead saw '{a}'.", - E031: "Bad assignment.", // FIXME: Rephrase - E032: "Expected a small integer or 'false' and instead saw '{a}'.", - E033: "Expected an operator and instead saw '{a}'.", - E034: "get/set are ES5 features.", - E035: "Missing property name.", - E036: "Expected to see a statement and instead saw a block.", - E037: null, // Vacant - E038: null, // Vacant - E039: "Function declarations are not invocable. Wrap the whole function invocation in parens.", - E040: "Each value should have its own case label.", - E041: "Unrecoverable syntax error.", - E042: "Stopping.", - E043: "Too many errors.", - E044: "'{a}' is already defined and can't be redefined.", - E045: "Invalid for each loop.", - E046: "A yield statement shall be within a generator function (with syntax: `function*`)", - E047: "A generator function shall contain a yield statement.", - E048: "Let declaration not directly within block.", - E049: "A {a} cannot be named '{b}'.", - E050: "Mozilla requires the yield expression to be parenthesized here.", - E051: "Regular parameters cannot come after default parameters." -}; - -var warnings = { - W001: "'hasOwnProperty' is a really bad name.", - W002: "Value of '{a}' may be overwritten in IE 8 and earlier.", - W003: "'{a}' was used before it was defined.", - W004: "'{a}' is already defined.", - W005: "A dot following a number can be confused with a decimal point.", - W006: "Confusing minuses.", - W007: "Confusing pluses.", - W008: "A leading decimal point can be confused with a dot: '{a}'.", - W009: "The array literal notation [] is preferrable.", - W010: "The object literal notation {} is preferrable.", - W011: "Unexpected space after '{a}'.", - W012: "Unexpected space before '{a}'.", - W013: "Missing space after '{a}'.", - W014: "Bad line breaking before '{a}'.", - W015: "Expected '{a}' to have an indentation at {b} instead at {c}.", - W016: "Unexpected use of '{a}'.", - W017: "Bad operand.", - W018: "Confusing use of '{a}'.", - W019: "Use the isNaN function to compare with NaN.", - W020: "Read only.", - W021: "'{a}' is a function.", - W022: "Do not assign to the exception parameter.", - W023: "Expected an identifier in an assignment and instead saw a function invocation.", - W024: "Expected an identifier and instead saw '{a}' (a reserved word).", - W025: "Missing name in function declaration.", - W026: "Inner functions should be listed at the top of the outer function.", - W027: "Unreachable '{a}' after '{b}'.", - W028: "Label '{a}' on {b} statement.", - W030: "Expected an assignment or function call and instead saw an expression.", - W031: "Do not use 'new' for side effects.", - W032: "Unnecessary semicolon.", - W033: "Missing semicolon.", - W034: "Unnecessary directive \"{a}\".", - W035: "Empty block.", - W036: "Unexpected /*member '{a}'.", - W037: "'{a}' is a statement label.", - W038: "'{a}' used out of scope.", - W039: "'{a}' is not allowed.", - W040: "Possible strict violation.", - W041: "Use '{a}' to compare with '{b}'.", - W042: "Avoid EOL escaping.", - W043: "Bad escaping of EOL. Use option multistr if needed.", - W044: "Bad or unnecessary escaping.", - W045: "Bad number '{a}'.", - W046: "Don't use extra leading zeros '{a}'.", - W047: "A trailing decimal point can be confused with a dot: '{a}'.", - W048: "Unexpected control character in regular expression.", - W049: "Unexpected escaped character '{a}' in regular expression.", - W050: "JavaScript URL.", - W051: "Variables should not be deleted.", - W052: "Unexpected '{a}'.", - W053: "Do not use {a} as a constructor.", - W054: "The Function constructor is a form of eval.", - W055: "A constructor name should start with an uppercase letter.", - W056: "Bad constructor.", - W057: "Weird construction. Is 'new' unnecessary?", - W058: "Missing '()' invoking a constructor.", - W059: "Avoid arguments.{a}.", - W060: "document.write can be a form of eval.", - W061: "eval can be harmful.", - W062: "Wrap an immediate function invocation in parens " + - "to assist the reader in understanding that the expression " + - "is the result of a function, and not the function itself.", - W063: "Math is not a function.", - W064: "Missing 'new' prefix when invoking a constructor.", - W065: "Missing radix parameter.", - W066: "Implied eval. Consider passing a function instead of a string.", - W067: "Bad invocation.", - W068: "Wrapping non-IIFE function literals in parens is unnecessary.", - W069: "['{a}'] is better written in dot notation.", - W070: "Extra comma. (it breaks older versions of IE)", - W071: "This function has too many statements. ({a})", - W072: "This function has too many parameters. ({a})", - W073: "Blocks are nested too deeply. ({a})", - W074: "This function's cyclomatic complexity is too high. ({a})", - W075: "Duplicate key '{a}'.", - W076: "Unexpected parameter '{a}' in get {b} function.", - W077: "Expected a single parameter in set {a} function.", - W078: "Setter is defined without getter.", - W079: "Redefinition of '{a}'.", - W080: "It's not necessary to initialize '{a}' to 'undefined'.", - W081: "Too many var statements.", - W082: "Function declarations should not be placed in blocks. " + - "Use a function expression or move the statement to the top of " + - "the outer function.", - W083: "Don't make functions within a loop.", - W084: "Assignment in conditional expression", - W085: "Don't use 'with'.", - W086: "Expected a 'break' statement before '{a}'.", - W087: "Forgotten 'debugger' statement?", - W088: "Creating global 'for' variable. Should be 'for (var {a} ...'.", - W089: "The body of a for in should be wrapped in an if statement to filter " + - "unwanted properties from the prototype.", - W090: "'{a}' is not a statement label.", - W091: "'{a}' is out of scope.", - W092: "Wrap the /regexp/ literal in parens to disambiguate the slash operator.", - W093: "Did you mean to return a conditional instead of an assignment?", - W094: "Unexpected comma.", - W095: "Expected a string and instead saw {a}.", - W096: "The '{a}' key may produce unexpected results.", - W097: "Use the function form of \"use strict\".", - W098: "'{a}' is defined but never used.", - W099: "Mixed spaces and tabs.", - W100: "This character may get silently deleted by one or more browsers.", - W101: "Line is too long.", - W102: "Trailing whitespace.", - W103: "The '{a}' property is deprecated.", - W104: "'{a}' is only available in JavaScript 1.7.", - W105: "Unexpected {a} in '{b}'.", - W106: "Identifier '{a}' is not in camel case.", - W107: "Script URL.", - W108: "Strings must use doublequote.", - W109: "Strings must use singlequote.", - W110: "Mixed double and single quotes.", - W112: "Unclosed string.", - W113: "Control character in string: {a}.", - W114: "Avoid {a}.", - W115: "Octal literals are not allowed in strict mode.", - W116: "Expected '{a}' and instead saw '{b}'.", - W117: "'{a}' is not defined.", - W118: "'{a}' is only available in Mozilla JavaScript extensions (use moz option).", - W119: "'{a}' is only available in ES6 (use esnext option).", - W120: "You might be leaking a variable ({a}) here." -}; - -var info = { - I001: "Comma warnings can be turned off with 'laxcomma'.", - I002: "Reserved words as properties can be used under the 'es5' option.", - I003: "ES5 option is now set per default" -}; - -exports.errors = {}; -exports.warnings = {}; -exports.info = {}; - -_.each(errors, function (desc, code) { - exports.errors[code] = { code: code, desc: desc }; -}); - -_.each(warnings, function (desc, code) { - exports.warnings[code] = { code: code, desc: desc }; -}); - -_.each(info, function (desc, code) { - exports.info[code] = { code: code, desc: desc }; -}); - -}, -{"underscore":1}], -3:[function(req,module,exports){ -// jshint -W001 - -"use strict"; - -// Identifiers provided by the ECMAScript standard. - -exports.reservedVars = { - arguments : false, - NaN : false -}; - -exports.ecmaIdentifiers = { - Array : false, - Boolean : false, - Date : false, - decodeURI : false, - decodeURIComponent : false, - encodeURI : false, - encodeURIComponent : false, - Error : false, - "eval" : false, - EvalError : false, - Function : false, - hasOwnProperty : false, - isFinite : false, - isNaN : false, - JSON : false, - Math : false, - Map : false, - Number : false, - Object : false, - parseInt : false, - parseFloat : false, - RangeError : false, - ReferenceError : false, - RegExp : false, - Set : false, - String : false, - SyntaxError : false, - TypeError : false, - URIError : false, - WeakMap : false -}; - -// Global variables commonly provided by a web browser environment. - -exports.browser = { - ArrayBuffer : false, - ArrayBufferView : false, - Audio : false, - Blob : false, - addEventListener : false, - applicationCache : false, - atob : false, - blur : false, - btoa : false, - clearInterval : false, - clearTimeout : false, - close : false, - closed : false, - CustomEvent : false, - DataView : false, - DOMParser : false, - defaultStatus : false, - document : false, - Element : false, - ElementTimeControl : false, - event : false, - FileReader : false, - Float32Array : false, - Float64Array : false, - FormData : false, - focus : false, - frames : false, - getComputedStyle : false, - HTMLElement : false, - HTMLAnchorElement : false, - HTMLBaseElement : false, - HTMLBlockquoteElement: false, - HTMLBodyElement : false, - HTMLBRElement : false, - HTMLButtonElement : false, - HTMLCanvasElement : false, - HTMLDirectoryElement : false, - HTMLDivElement : false, - HTMLDListElement : false, - HTMLFieldSetElement : false, - HTMLFontElement : false, - HTMLFormElement : false, - HTMLFrameElement : false, - HTMLFrameSetElement : false, - HTMLHeadElement : false, - HTMLHeadingElement : false, - HTMLHRElement : false, - HTMLHtmlElement : false, - HTMLIFrameElement : false, - HTMLImageElement : false, - HTMLInputElement : false, - HTMLIsIndexElement : false, - HTMLLabelElement : false, - HTMLLayerElement : false, - HTMLLegendElement : false, - HTMLLIElement : false, - HTMLLinkElement : false, - HTMLMapElement : false, - HTMLMenuElement : false, - HTMLMetaElement : false, - HTMLModElement : false, - HTMLObjectElement : false, - HTMLOListElement : false, - HTMLOptGroupElement : false, - HTMLOptionElement : false, - HTMLParagraphElement : false, - HTMLParamElement : false, - HTMLPreElement : false, - HTMLQuoteElement : false, - HTMLScriptElement : false, - HTMLSelectElement : false, - HTMLStyleElement : false, - HTMLTableCaptionElement: false, - HTMLTableCellElement : false, - HTMLTableColElement : false, - HTMLTableElement : false, - HTMLTableRowElement : false, - HTMLTableSectionElement: false, - HTMLTextAreaElement : false, - HTMLTitleElement : false, - HTMLUListElement : false, - HTMLVideoElement : false, - history : false, - Int16Array : false, - Int32Array : false, - Int8Array : false, - Image : false, - length : false, - localStorage : false, - location : false, - MessageChannel : false, - MessageEvent : false, - MessagePort : false, - MouseEvent : false, - moveBy : false, - moveTo : false, - MutationObserver : false, - name : false, - Node : false, - NodeFilter : false, - navigator : false, - onbeforeunload : true, - onblur : true, - onerror : true, - onfocus : true, - onload : true, - onresize : true, - onunload : true, - open : false, - openDatabase : false, - opener : false, - Option : false, - parent : false, - print : false, - removeEventListener : false, - resizeBy : false, - resizeTo : false, - screen : false, - scroll : false, - scrollBy : false, - scrollTo : false, - sessionStorage : false, - setInterval : false, - setTimeout : false, - SharedWorker : false, - status : false, - SVGAElement : false, - SVGAltGlyphDefElement: false, - SVGAltGlyphElement : false, - SVGAltGlyphItemElement: false, - SVGAngle : false, - SVGAnimateColorElement: false, - SVGAnimateElement : false, - SVGAnimateMotionElement: false, - SVGAnimateTransformElement: false, - SVGAnimatedAngle : false, - SVGAnimatedBoolean : false, - SVGAnimatedEnumeration: false, - SVGAnimatedInteger : false, - SVGAnimatedLength : false, - SVGAnimatedLengthList: false, - SVGAnimatedNumber : false, - SVGAnimatedNumberList: false, - SVGAnimatedPathData : false, - SVGAnimatedPoints : false, - SVGAnimatedPreserveAspectRatio: false, - SVGAnimatedRect : false, - SVGAnimatedString : false, - SVGAnimatedTransformList: false, - SVGAnimationElement : false, - SVGCSSRule : false, - SVGCircleElement : false, - SVGClipPathElement : false, - SVGColor : false, - SVGColorProfileElement: false, - SVGColorProfileRule : false, - SVGComponentTransferFunctionElement: false, - SVGCursorElement : false, - SVGDefsElement : false, - SVGDescElement : false, - SVGDocument : false, - SVGElement : false, - SVGElementInstance : false, - SVGElementInstanceList: false, - SVGEllipseElement : false, - SVGExternalResourcesRequired: false, - SVGFEBlendElement : false, - SVGFEColorMatrixElement: false, - SVGFEComponentTransferElement: false, - SVGFECompositeElement: false, - SVGFEConvolveMatrixElement: false, - SVGFEDiffuseLightingElement: false, - SVGFEDisplacementMapElement: false, - SVGFEDistantLightElement: false, - SVGFEFloodElement : false, - SVGFEFuncAElement : false, - SVGFEFuncBElement : false, - SVGFEFuncGElement : false, - SVGFEFuncRElement : false, - SVGFEGaussianBlurElement: false, - SVGFEImageElement : false, - SVGFEMergeElement : false, - SVGFEMergeNodeElement: false, - SVGFEMorphologyElement: false, - SVGFEOffsetElement : false, - SVGFEPointLightElement: false, - SVGFESpecularLightingElement: false, - SVGFESpotLightElement: false, - SVGFETileElement : false, - SVGFETurbulenceElement: false, - SVGFilterElement : false, - SVGFilterPrimitiveStandardAttributes: false, - SVGFitToViewBox : false, - SVGFontElement : false, - SVGFontFaceElement : false, - SVGFontFaceFormatElement: false, - SVGFontFaceNameElement: false, - SVGFontFaceSrcElement: false, - SVGFontFaceUriElement: false, - SVGForeignObjectElement: false, - SVGGElement : false, - SVGGlyphElement : false, - SVGGlyphRefElement : false, - SVGGradientElement : false, - SVGHKernElement : false, - SVGICCColor : false, - SVGImageElement : false, - SVGLangSpace : false, - SVGLength : false, - SVGLengthList : false, - SVGLineElement : false, - SVGLinearGradientElement: false, - SVGLocatable : false, - SVGMPathElement : false, - SVGMarkerElement : false, - SVGMaskElement : false, - SVGMatrix : false, - SVGMetadataElement : false, - SVGMissingGlyphElement: false, - SVGNumber : false, - SVGNumberList : false, - SVGPaint : false, - SVGPathElement : false, - SVGPathSeg : false, - SVGPathSegArcAbs : false, - SVGPathSegArcRel : false, - SVGPathSegClosePath : false, - SVGPathSegCurvetoCubicAbs: false, - SVGPathSegCurvetoCubicRel: false, - SVGPathSegCurvetoCubicSmoothAbs: false, - SVGPathSegCurvetoCubicSmoothRel: false, - SVGPathSegCurvetoQuadraticAbs: false, - SVGPathSegCurvetoQuadraticRel: false, - SVGPathSegCurvetoQuadraticSmoothAbs: false, - SVGPathSegCurvetoQuadraticSmoothRel: false, - SVGPathSegLinetoAbs : false, - SVGPathSegLinetoHorizontalAbs: false, - SVGPathSegLinetoHorizontalRel: false, - SVGPathSegLinetoRel : false, - SVGPathSegLinetoVerticalAbs: false, - SVGPathSegLinetoVerticalRel: false, - SVGPathSegList : false, - SVGPathSegMovetoAbs : false, - SVGPathSegMovetoRel : false, - SVGPatternElement : false, - SVGPoint : false, - SVGPointList : false, - SVGPolygonElement : false, - SVGPolylineElement : false, - SVGPreserveAspectRatio: false, - SVGRadialGradientElement: false, - SVGRect : false, - SVGRectElement : false, - SVGRenderingIntent : false, - SVGSVGElement : false, - SVGScriptElement : false, - SVGSetElement : false, - SVGStopElement : false, - SVGStringList : false, - SVGStylable : false, - SVGStyleElement : false, - SVGSwitchElement : false, - SVGSymbolElement : false, - SVGTRefElement : false, - SVGTSpanElement : false, - SVGTests : false, - SVGTextContentElement: false, - SVGTextElement : false, - SVGTextPathElement : false, - SVGTextPositioningElement: false, - SVGTitleElement : false, - SVGTransform : false, - SVGTransformList : false, - SVGTransformable : false, - SVGURIReference : false, - SVGUnitTypes : false, - SVGUseElement : false, - SVGVKernElement : false, - SVGViewElement : false, - SVGViewSpec : false, - SVGZoomAndPan : false, - TimeEvent : false, - top : false, - Uint16Array : false, - Uint32Array : false, - Uint8Array : false, - Uint8ClampedArray : false, - WebSocket : false, - window : false, - Worker : false, - XMLHttpRequest : false, - XMLSerializer : false, - XPathEvaluator : false, - XPathException : false, - XPathExpression : false, - XPathNamespace : false, - XPathNSResolver : false, - XPathResult : false -}; - -exports.devel = { - alert : false, - confirm: false, - console: false, - Debug : false, - opera : false, - prompt : false -}; - -exports.worker = { - importScripts: true, - postMessage : true, - self : true -}; - -// Widely adopted global names that are not part of ECMAScript standard -exports.nonstandard = { - escape : false, - unescape: false -}; - -// Globals provided by popular JavaScript environments. - -exports.couch = { - "require" : false, - respond : false, - getRow : false, - emit : false, - send : false, - start : false, - sum : false, - log : false, - exports : false, - module : false, - provides : false -}; - -exports.node = { - __filename : false, - __dirname : false, - Buffer : false, - DataView : false, - console : false, - exports : true, // In Node it is ok to exports = module.exports = foo(); - GLOBAL : false, - global : false, - module : false, - process : false, - require : false, - setTimeout : false, - clearTimeout : false, - setInterval : false, - clearInterval : false, - setImmediate : false, // v0.9.1+ - clearImmediate: false // v0.9.1+ -}; - -exports.phantom = { - phantom : true, - require : true, - WebPage : true -}; - -exports.rhino = { - defineClass : false, - deserialize : false, - gc : false, - help : false, - importPackage: false, - "java" : false, - load : false, - loadClass : false, - print : false, - quit : false, - readFile : false, - readUrl : false, - runCommand : false, - seal : false, - serialize : false, - spawn : false, - sync : false, - toint32 : false, - version : false -}; - -exports.shelljs = { - target : false, - echo : false, - exit : false, - cd : false, - pwd : false, - ls : false, - find : false, - cp : false, - rm : false, - mv : false, - mkdir : false, - test : false, - cat : false, - sed : false, - grep : false, - which : false, - dirs : false, - pushd : false, - popd : false, - env : false, - exec : false, - chmod : false, - config : false, - error : false, - tempdir : false -}; - -exports.wsh = { - ActiveXObject : true, - Enumerator : true, - GetObject : true, - ScriptEngine : true, - ScriptEngineBuildVersion : true, - ScriptEngineMajorVersion : true, - ScriptEngineMinorVersion : true, - VBArray : true, - WSH : true, - WScript : true, - XDomainRequest : true -}; - -// Globals provided by popular JavaScript libraries. - -exports.dojo = { - dojo : false, - dijit : false, - dojox : false, - define : false, - "require": false -}; - -exports.jquery = { - "$" : false, - jQuery : false -}; - -exports.mootools = { - "$" : false, - "$$" : false, - Asset : false, - Browser : false, - Chain : false, - Class : false, - Color : false, - Cookie : false, - Core : false, - Document : false, - DomReady : false, - DOMEvent : false, - DOMReady : false, - Drag : false, - Element : false, - Elements : false, - Event : false, - Events : false, - Fx : false, - Group : false, - Hash : false, - HtmlTable : false, - Iframe : false, - IframeShim : false, - InputValidator: false, - instanceOf : false, - Keyboard : false, - Locale : false, - Mask : false, - MooTools : false, - Native : false, - Options : false, - OverText : false, - Request : false, - Scroller : false, - Slick : false, - Slider : false, - Sortables : false, - Spinner : false, - Swiff : false, - Tips : false, - Type : false, - typeOf : false, - URI : false, - Window : false -}; - -exports.prototypejs = { - "$" : false, - "$$" : false, - "$A" : false, - "$F" : false, - "$H" : false, - "$R" : false, - "$break" : false, - "$continue" : false, - "$w" : false, - Abstract : false, - Ajax : false, - Class : false, - Enumerable : false, - Element : false, - Event : false, - Field : false, - Form : false, - Hash : false, - Insertion : false, - ObjectRange : false, - PeriodicalExecuter: false, - Position : false, - Prototype : false, - Selector : false, - Template : false, - Toggle : false, - Try : false, - Autocompleter : false, - Builder : false, - Control : false, - Draggable : false, - Draggables : false, - Droppables : false, - Effect : false, - Sortable : false, - SortableObserver : false, - Sound : false, - Scriptaculous : false -}; - -exports.yui = { - YUI : false, - Y : false, - YUI_config: false -}; - - -}, -{}], -"n4bKNg":[function(req,module,exports){ +3:[function(_dereq_,module,exports){ /*! * JSHint, by JSHint Community. * * This file (and this file only) is licensed under the same slightly modified * MIT license that JSLint is. It stops evil-doers everywhere: * - * Copyright (c) 2002 Douglas Crockford (www.JSLint.com) + * Copyright (c) 2002 Douglas Crockford (www.JSLint.com) * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. * - * The Software shall be used for Good, not Evil. + * The Software shall be used for Good, not Evil. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. * */ @@ -2083,4964 +1291,5004 @@ exports.yui = { /*global console:true */ /*exported console */ -var _ = req("underscore"); -var events = req("events"); -var vars = req("../shared/vars.js"); -var messages = req("../shared/messages.js"); -var Lexer = req("./lex.js").Lexer; -var reg = req("./reg.js"); -var state = req("./state.js").state; -var style = req("./style.js"); - -// We need this module here because environments such as IE and Rhino -// don't necessarilly expose the 'console' API and browserify uses -// it to log things. It's a sad state of affair, really. -var console = req("console-browserify"); +var _ = _dereq_("underscore"); +var events = _dereq_("events"); +var vars = _dereq_("./vars.js"); +var messages = _dereq_("./messages.js"); +var Lexer = _dereq_("./lex.js").Lexer; +var reg = _dereq_("./reg.js"); +var state = _dereq_("./state.js").state; +var style = _dereq_("./style.js"); // We build the application inside a function so that we produce only a singleton // variable. That function will be invoked immediately, and its return value is // the JSHINT function itself. var JSHINT = (function () { - "use strict"; - - var anonname, // The guessed name for anonymous functions. - api, // Extension API - - // These are operators that should not be used with the ! operator. - bang = { - "<" : true, - "<=" : true, - "==" : true, - "===": true, - "!==": true, - "!=" : true, - ">" : true, - ">=" : true, - "+" : true, - "-" : true, - "*" : true, - "/" : true, - "%" : true - }, - - // These are the JSHint boolean options. - boolOptions = { - asi : true, // if automatic semicolon insertion should be tolerated - bitwise : true, // if bitwise operators should not be allowed - boss : true, // if advanced usage of assignments should be allowed - browser : true, // if the standard browser globals should be predefined - camelcase : true, // if identifiers should be required in camel case - couch : true, // if CouchDB globals should be predefined - curly : true, // if curly braces around all blocks should be required - debug : true, // if debugger statements should be allowed - devel : true, // if logging globals should be predefined (console, alert, etc.) - dojo : true, // if Dojo Toolkit globals should be predefined - eqeqeq : true, // if === should be required - eqnull : true, // if == null comparisons should be tolerated - es3 : true, // if ES3 syntax should be allowed - es5 : true, // if ES5 syntax should be allowed (is now set per default) - esnext : true, // if es.next specific syntax should be allowed - moz : true, // if mozilla specific syntax should be allowed - evil : true, // if eval should be allowed - expr : true, // if ExpressionStatement should be allowed as Programs - forin : true, // if for in statements must filter - funcscope : true, // if only function scope should be used for scope tests - gcl : true, // if JSHint should be compatible with Google Closure Linter - globalstrict: true, // if global "use strict"; should be allowed (also enables 'strict') - immed : true, // if immediate invocations must be wrapped in parens - iterator : true, // if the `__iterator__` property should be allowed - jquery : true, // if jQuery globals should be predefined - lastsemic : true, // if semicolons may be ommitted for the trailing - // statements inside of a one-line blocks. - laxbreak : true, // if line breaks should not be checked - laxcomma : true, // if line breaks should not be checked around commas - loopfunc : true, // if functions should be allowed to be defined within - // loops - mootools : true, // if MooTools globals should be predefined - multistr : true, // allow multiline strings - newcap : true, // if constructor names must be capitalized - noarg : true, // if arguments.caller and arguments.callee should be - // disallowed - node : true, // if the Node.js environment globals should be - // predefined - noempty : true, // if empty blocks should be disallowed - nonew : true, // if using `new` for side-effects should be disallowed - nonstandard : true, // if non-standard (but widely adopted) globals should - // be predefined - nomen : true, // if names should be checked - onevar : true, // if only one var statement per function should be - // allowed - passfail : true, // if the scan should stop on first error - phantom : true, // if PhantomJS symbols should be allowed - plusplus : true, // if increment/decrement should not be allowed - proto : true, // if the `__proto__` property should be allowed - prototypejs : true, // if Prototype and Scriptaculous globals should be - // predefined - rhino : true, // if the Rhino environment globals should be predefined - shelljs : true, // if ShellJS globals should be predefined - undef : true, // if variables should be declared before used - scripturl : true, // if script-targeted URLs should be tolerated - shadow : true, // if variable shadowing should be tolerated - smarttabs : true, // if smarttabs should be tolerated - // (http://www.emacswiki.org/emacs/SmartTabs) - strict : true, // require the "use strict"; pragma - sub : true, // if all forms of subscript notation are tolerated - supernew : true, // if `new function () { ... };` and `new Object;` - // should be tolerated - trailing : true, // if trailing whitespace rules apply - validthis : true, // if 'this' inside a non-constructor function is valid. - // This is a function scoped option only. - withstmt : true, // if with statements should be allowed - white : true, // if strict whitespace rules apply - worker : true, // if Web Worker script symbols should be allowed - wsh : true, // if the Windows Scripting Host environment globals - // should be predefined - yui : true, // YUI variables should be predefined - - // Obsolete options - onecase : true, // if one case switch statements should be allowed - regexp : true, // if the . should not be allowed in regexp literals - regexdash : true // if unescaped first/last dash (-) inside brackets - // should be tolerated - }, - - // These are the JSHint options that can take any value - // (we use this object to detect invalid options) - valOptions = { - maxlen : false, - indent : false, - maxerr : false, - predef : false, - quotmark : false, //'single'|'double'|true - scope : false, - maxstatements: false, // {int} max statements per function - maxdepth : false, // {int} max nested block depth per function - maxparams : false, // {int} max params per function - maxcomplexity: false, // {int} max cyclomatic complexity per function - unused : true, // warn if variables are unused. Available options: - // false - don't check for unused variables - // true - "vars" + check last function param - // "vars" - skip checking unused function params - // "strict" - "vars" + check all function params - latedef : false // warn if the variable is used before its definition - // false - don't emit any warnings - // true - warn if any variable is used before its definition - // "nofunc" - warn for any variable but function declarations - }, - - // These are JSHint boolean options which are shared with JSLint - // where the definition in JSHint is opposite JSLint - invertedOptions = { - bitwise : true, - forin : true, - newcap : true, - nomen : true, - plusplus: true, - regexp : true, - undef : true, - white : true, - - // Inverted and renamed, use JSHint name here - eqeqeq : true, - onevar : true, - strict : true - }, - - // These are JSHint boolean options which are shared with JSLint - // where the name has been changed but the effect is unchanged - renamedOptions = { - eqeq : "eqeqeq", - vars : "onevar", - windows: "wsh", - sloppy : "strict" - }, - - declared, // Globals that were declared using /*global ... */ syntax. - exported, // Variables that are used outside of the current file. - - functionicity = [ - "closure", "exception", "global", "label", - "outer", "unused", "var" - ], - - funct, // The current function - functions, // All of the functions - - global, // The global scope - implied, // Implied globals - inblock, - indent, - lookahead, - lex, - member, - membersOnly, - noreach, - predefined, // Global variables defined by option - - scope, // The current scope - stack, - unuseds, - urls, - warnings, - - extraModules = [], - emitter = new events.EventEmitter(); - - function checkOption(name, t) { - name = name.trim(); - - if (/^[+-]W\d{3}$/g.test(name)) { - return true; - } - - if (valOptions[name] === undefined && boolOptions[name] === undefined) { - if (t.type !== "jslint") { - error("E001", t, name); - return false; - } - } - - return true; - } - - function isString(obj) { - return Object.prototype.toString.call(obj) === "[object String]"; - } - - function isIdentifier(tkn, value) { - if (!tkn) - return false; - - if (!tkn.identifier || tkn.value !== value) - return false; - - return true; - } - - function isReserved(token) { - if (!token.reserved) { - return false; - } - var meta = token.meta; - - if (meta && meta.isFutureReservedWord && state.option.inES5()) { - // ES3 FutureReservedWord in an ES5 environment. - if (!meta.es5) { - return false; - } - - // Some ES5 FutureReservedWord identifiers are active only - // within a strict mode environment. - if (meta.strictOnly) { - if (!state.option.strict && !state.directive["use strict"]) { - return false; - } - } - - if (token.isProperty) { - return false; - } - } - - return true; - } - - function supplant(str, data) { - return str.replace(/\{([^{}]*)\}/g, function (a, b) { - var r = data[b]; - return typeof r === "string" || typeof r === "number" ? r : a; - }); - } - - function combine(t, o) { - var n; - for (n in o) { - if (_.has(o, n) && !_.has(JSHINT.blacklist, n)) { - t[n] = o[n]; - } - } - } - - function updatePredefined() { - Object.keys(JSHINT.blacklist).forEach(function (key) { - delete predefined[key]; - }); - } - - function assume() { - if (state.option.couch) { - combine(predefined, vars.couch); - } - - if (state.option.rhino) { - combine(predefined, vars.rhino); - } - - if (state.option.shelljs) { - combine(predefined, vars.shelljs); - combine(predefined, vars.node); - } - - if (state.option.phantom) { - combine(predefined, vars.phantom); - } - - if (state.option.prototypejs) { - combine(predefined, vars.prototypejs); - } - - if (state.option.node) { - combine(predefined, vars.node); - } - - if (state.option.devel) { - combine(predefined, vars.devel); - } - - if (state.option.dojo) { - combine(predefined, vars.dojo); - } - - if (state.option.browser) { - combine(predefined, vars.browser); - } - - if (state.option.nonstandard) { - combine(predefined, vars.nonstandard); - } - - if (state.option.jquery) { - combine(predefined, vars.jquery); - } - - if (state.option.mootools) { - combine(predefined, vars.mootools); - } - - if (state.option.worker) { - combine(predefined, vars.worker); - } - - if (state.option.wsh) { - combine(predefined, vars.wsh); - } - - if (state.option.globalstrict && state.option.strict !== false) { - state.option.strict = true; - } - - if (state.option.yui) { - combine(predefined, vars.yui); - } - - // Let's assume that chronologically ES3 < ES5 < ES6/ESNext < Moz - - state.option.inMoz = function (strict) { - return state.option.moz; - }; - - state.option.inESNext = function (strict) { - return state.option.moz || state.option.esnext; - }; - - state.option.inES5 = function (/* strict */) { - return !state.option.es3; - }; - - state.option.inES3 = function (strict) { - if (strict) { - return !state.option.moz && !state.option.esnext && state.option.es3; - } - return state.option.es3; - }; - } - - // Produce an error warning. - function quit(code, line, chr) { - var percentage = Math.floor((line / state.lines.length) * 100); - var message = messages.errors[code].desc; - - throw { - name: "JSHintError", - line: line, - character: chr, - message: message + " (" + percentage + "% scanned).", - raw: message, - code: code - }; - } - - function isundef(scope, code, token, a) { - return JSHINT.undefs.push([scope, code, token, a]); - } - - function warning(code, t, a, b, c, d) { - var ch, l, w, msg; - - if (/^W\d{3}$/.test(code)) { - if (state.ignored[code]) - return; - - msg = messages.warnings[code]; - } else if (/E\d{3}/.test(code)) { - msg = messages.errors[code]; - } else if (/I\d{3}/.test(code)) { - msg = messages.info[code]; - } - - t = t || state.tokens.next; - if (t.id === "(end)") { // `~ - t = state.tokens.curr; - } - - l = t.line || 0; - ch = t.from || 0; - - w = { - id: "(error)", - raw: msg.desc, - code: msg.code, - evidence: state.lines[l - 1] || "", - line: l, - character: ch, - scope: JSHINT.scope, - a: a, - b: b, - c: c, - d: d - }; - - w.reason = supplant(msg.desc, w); - JSHINT.errors.push(w); - - if (state.option.passfail) { - quit("E042", l, ch); - } - - warnings += 1; - if (warnings >= state.option.maxerr) { - quit("E043", l, ch); - } - - return w; - } - - function warningAt(m, l, ch, a, b, c, d) { - return warning(m, { - line: l, - from: ch - }, a, b, c, d); - } - - function error(m, t, a, b, c, d) { - warning(m, t, a, b, c, d); - } - - function errorAt(m, l, ch, a, b, c, d) { - return error(m, { - line: l, - from: ch - }, a, b, c, d); - } - - // Tracking of "internal" scripts, like eval containing a static string - function addInternalSrc(elem, src) { - var i; - i = { - id: "(internal)", - elem: elem, - value: src - }; - JSHINT.internals.push(i); - return i; - } - - function addlabel(t, type, tkn, islet) { - // Define t in the current function in the current scope. - if (type === "exception") { - if (_.has(funct["(context)"], t)) { - if (funct[t] !== true && !state.option.node) { - warning("W002", state.tokens.next, t); - } - } - } - - if (_.has(funct, t) && !funct["(global)"]) { - if (funct[t] === true) { - if (state.option.latedef) { - if ((state.option.latedef === true && _.contains([funct[t], type], "unction")) || - !_.contains([funct[t], type], "unction")) { - warning("W003", state.tokens.next, t); - } - } - } else { - if (!state.option.shadow && type !== "exception" || - (funct["(blockscope)"].getlabel(t))) { - warning("W004", state.tokens.next, t); - } - } - } - - // a double definition of a let variable in same block throws a TypeError - if (funct["(blockscope)"] && funct["(blockscope)"].current.has(t)) { - error("E044", state.tokens.next, t); - } - - // if the identifier is from a let, adds it only to the current blockscope - if (islet) { - funct["(blockscope)"].current.add(t, type, state.tokens.curr); - } else { - - funct[t] = type; - - if (tkn) { - funct["(tokens)"][t] = tkn; - } - - if (funct["(global)"]) { - global[t] = funct; - if (_.has(implied, t)) { - if (state.option.latedef) { - if ((state.option.latedef === true && _.contains([funct[t], type], "unction")) || - !_.contains([funct[t], type], "unction")) { - warning("W003", state.tokens.next, t); - } - } - - delete implied[t]; - } - } else { - scope[t] = funct; - } - } - } - - function doOption() { - var nt = state.tokens.next; - var body = nt.body.match(/(-\s+)?[^\s,]+(?:\s*:\s*(-\s+)?[^\s,]+)?/g); - var predef = {}; - - if (nt.type === "globals") { - body.forEach(function (g) { - g = g.split(":"); - var key = (g[0] || "").trim(); - var val = (g[1] || "").trim(); - - if (key.charAt(0) === "-") { - key = key.slice(1); - val = false; - - JSHINT.blacklist[key] = key; - updatePredefined(); - } else { - predef[key] = (val === "true"); - } - }); - - combine(predefined, predef); - - for (var key in predef) { - if (_.has(predef, key)) { - declared[key] = nt; - } - } - } - - if (nt.type === "exported") { - body.forEach(function (e) { - exported[e] = true; - }); - } - - if (nt.type === "members") { - membersOnly = membersOnly || {}; - - body.forEach(function (m) { - var ch1 = m.charAt(0); - var ch2 = m.charAt(m.length - 1); - - if (ch1 === ch2 && (ch1 === "\"" || ch1 === "'")) { - m = m - .substr(1, m.length - 2) - .replace("\\b", "\b") - .replace("\\t", "\t") - .replace("\\n", "\n") - .replace("\\v", "\v") - .replace("\\f", "\f") - .replace("\\r", "\r") - .replace("\\\\", "\\") - .replace("\\\"", "\""); - } - - membersOnly[m] = false; - }); - } - - var numvals = [ - "maxstatements", - "maxparams", - "maxdepth", - "maxcomplexity", - "maxerr", - "maxlen", - "indent" - ]; - - if (nt.type === "jshint" || nt.type === "jslint") { - body.forEach(function (g) { - g = g.split(":"); - var key = (g[0] || "").trim(); - var val = (g[1] || "").trim(); - - if (!checkOption(key, nt)) { - return; - } - - if (numvals.indexOf(key) >= 0) { - - // GH988 - numeric options can be disabled by setting them to `false` - if (val !== "false") { - val = +val; - - if (typeof val !== "number" || !isFinite(val) || val <= 0 || Math.floor(val) !== val) { - error("E032", nt, g[1].trim()); - return; - } - - if (key === "indent") { - state.option["(explicitIndent)"] = true; - } - state.option[key] = val; - } else { - if (key === "indent") { - state.option["(explicitIndent)"] = false; - } else { - state.option[key] = false; - } - } - - return; - } - - if (key === "validthis") { - // `validthis` is valid only within a function scope. - if (funct["(global)"]) { - error("E009"); - } else { - if (val === "true" || val === "false") { - state.option.validthis = (val === "true"); - } else { - error("E002", nt); - } - } - return; - } - - if (key === "quotmark") { - switch (val) { - case "true": - case "false": - state.option.quotmark = (val === "true"); - break; - case "double": - case "single": - state.option.quotmark = val; - break; - default: - error("E002", nt); - } - return; - } - - if (key === "unused") { - switch (val) { - case "true": - state.option.unused = true; - break; - case "false": - state.option.unused = false; - break; - case "vars": - case "strict": - state.option.unused = val; - break; - default: - error("E002", nt); - } - return; - } - - if (key === "latedef") { - switch (val) { - case "true": - state.option.latedef = true; - break; - case "false": - state.option.latedef = false; - break; - case "nofunc": - state.option.latedef = "nofunc"; - break; - default: - error("E002", nt); - } - return; - } - - var match = /^([+-])(W\d{3})$/g.exec(key); - if (match) { - // ignore for -W..., unignore for +W... - state.ignored[match[2]] = (match[1] === "-"); - return; - } - - var tn; - if (val === "true" || val === "false") { - if (nt.type === "jslint") { - tn = renamedOptions[key] || key; - state.option[tn] = (val === "true"); - - if (invertedOptions[tn] !== undefined) { - state.option[tn] = !state.option[tn]; - } - } else { - state.option[key] = (val === "true"); - } - - if (key === "newcap") { - state.option["(explicitNewcap)"] = true; - } - return; - } - - error("E002", nt); - }); - - assume(); - } - } - - // We need a peek function. If it has an argument, it peeks that much farther - // ahead. It is used to distinguish - // for ( var i in ... - // from - // for ( var i = ... - - function peek(p) { - var i = p || 0, j = 0, t; - - while (j <= i) { - t = lookahead[j]; - if (!t) { - t = lookahead[j] = lex.token(); - } - j += 1; - } - return t; - } - - // Produce the next token. It looks for programming errors. - - function advance(id, t) { - switch (state.tokens.curr.id) { - case "(number)": - if (state.tokens.next.id === ".") { - warning("W005", state.tokens.curr); - } - break; - case "-": - if (state.tokens.next.id === "-" || state.tokens.next.id === "--") { - warning("W006"); - } - break; - case "+": - if (state.tokens.next.id === "+" || state.tokens.next.id === "++") { - warning("W007"); - } - break; - } - - if (state.tokens.curr.type === "(string)" || state.tokens.curr.identifier) { - anonname = state.tokens.curr.value; - } - - if (id && state.tokens.next.id !== id) { - if (t) { - if (state.tokens.next.id === "(end)") { - error("E019", t, t.id); - } else { - error("E020", state.tokens.next, id, t.id, t.line, state.tokens.next.value); - } - } else if (state.tokens.next.type !== "(identifier)" || state.tokens.next.value !== id) { - warning("W116", state.tokens.next, id, state.tokens.next.value); - } - } - - state.tokens.prev = state.tokens.curr; - state.tokens.curr = state.tokens.next; - for (;;) { - state.tokens.next = lookahead.shift() || lex.token(); - - if (!state.tokens.next) { // No more tokens left, give up - quit("E041", state.tokens.curr.line); - } - - if (state.tokens.next.id === "(end)" || state.tokens.next.id === "(error)") { - return; - } - - if (state.tokens.next.check) { - state.tokens.next.check(); - } - - if (state.tokens.next.isSpecial) { - doOption(); - } else { - if (state.tokens.next.id !== "(endline)") { - break; - } - } - } - } - - function isInfix(token) { - return token.infix || (!token.identifier && !!token.led); - } - - function isEndOfExpr() { - var curr = state.tokens.curr; - var next = state.tokens.next; - if (next.id === ";" || next.id === "}" || next.id === ":") { - return true; - } - if (isInfix(next) === isInfix(curr) || (curr.id === "yield" && state.option.inMoz(true))) { - return curr.line !== next.line; - } - return false; - } - - // This is the heart of JSHINT, the Pratt parser. In addition to parsing, it - // is looking for ad hoc lint patterns. We add .fud to Pratt's model, which is - // like .nud except that it is only used on the first token of a statement. - // Having .fud makes it much easier to define statement-oriented languages like - // JavaScript. I retained Pratt's nomenclature. - - // .nud Null denotation - // .fud First null denotation - // .led Left denotation - // lbp Left binding power - // rbp Right binding power - - // They are elements of the parsing method called Top Down Operator Precedence. - - function expression(rbp, initial) { - var left, isArray = false, isObject = false, isLetExpr = false; - - // if current expression is a let expression - if (!initial && state.tokens.next.value === "let" && peek(0).value === "(") { - if (!state.option.inMoz(true)) { - warning("W118", state.tokens.next, "let expressions"); - } - isLetExpr = true; - // create a new block scope we use only for the current expression - funct["(blockscope)"].stack(); - advance("let"); - advance("("); - state.syntax["let"].fud.call(state.syntax["let"].fud, false); - advance(")"); - } - - if (state.tokens.next.id === "(end)") - error("E006", state.tokens.curr); - - advance(); - - if (initial) { - anonname = "anonymous"; - funct["(verb)"] = state.tokens.curr.value; - } - - if (initial === true && state.tokens.curr.fud) { - left = state.tokens.curr.fud(); - } else { - if (state.tokens.curr.nud) { - left = state.tokens.curr.nud(); - } else { - error("E030", state.tokens.curr, state.tokens.curr.id); - } - - while (rbp < state.tokens.next.lbp && !isEndOfExpr()) { - isArray = state.tokens.curr.value === "Array"; - isObject = state.tokens.curr.value === "Object"; - - // #527, new Foo.Array(), Foo.Array(), new Foo.Object(), Foo.Object() - // Line breaks in IfStatement heads exist to satisfy the checkJSHint - // "Line too long." error. - if (left && (left.value || (left.first && left.first.value))) { - // If the left.value is not "new", or the left.first.value is a "." - // then safely assume that this is not "new Array()" and possibly - // not "new Object()"... - if (left.value !== "new" || - (left.first && left.first.value && left.first.value === ".")) { - isArray = false; - // ...In the case of Object, if the left.value and state.tokens.curr.value - // are not equal, then safely assume that this not "new Object()" - if (left.value !== state.tokens.curr.value) { - isObject = false; - } - } - } - - advance(); - - if (isArray && state.tokens.curr.id === "(" && state.tokens.next.id === ")") { - warning("W009", state.tokens.curr); - } - - if (isObject && state.tokens.curr.id === "(" && state.tokens.next.id === ")") { - warning("W010", state.tokens.curr); - } - - if (left && state.tokens.curr.led) { - left = state.tokens.curr.led(left); - } else { - error("E033", state.tokens.curr, state.tokens.curr.id); - } - } - } - if (isLetExpr) { - funct["(blockscope)"].unstack(); - } - return left; - } - - -// Functions for conformance of style. - - function adjacent(left, right) { - left = left || state.tokens.curr; - right = right || state.tokens.next; - if (state.option.white) { - if (left.character !== right.from && left.line === right.line) { - left.from += (left.character - left.from); - warning("W011", left, left.value); - } - } - } - - function nobreak(left, right) { - left = left || state.tokens.curr; - right = right || state.tokens.next; - if (state.option.white && (left.character !== right.from || left.line !== right.line)) { - warning("W012", right, right.value); - } - } - - function nospace(left, right) { - left = left || state.tokens.curr; - right = right || state.tokens.next; - if (state.option.white && !left.comment) { - if (left.line === right.line) { - adjacent(left, right); - } - } - } - - function nonadjacent(left, right) { - if (state.option.white) { - left = left || state.tokens.curr; - right = right || state.tokens.next; - - if (left.value === ";" && right.value === ";") { - return; - } - - if (left.line === right.line && left.character === right.from) { - left.from += (left.character - left.from); - warning("W013", left, left.value); - } - } - } - - function nobreaknonadjacent(left, right) { - left = left || state.tokens.curr; - right = right || state.tokens.next; - if (!state.option.laxbreak && left.line !== right.line) { - warning("W014", right, right.value); - } else if (state.option.white) { - left = left || state.tokens.curr; - right = right || state.tokens.next; - if (left.character === right.from) { - left.from += (left.character - left.from); - warning("W013", left, left.value); - } - } - } - - function indentation(bias) { - if (!state.option.white && !state.option["(explicitIndent)"]) { - return; - } - - if (state.tokens.next.id === "(end)") { - return; - } - - var i = indent + (bias || 0); - if (state.tokens.next.from !== i) { - warning("W015", state.tokens.next, state.tokens.next.value, i, state.tokens.next.from); - } - } - - function nolinebreak(t) { - t = t || state.tokens.curr; - if (t.line !== state.tokens.next.line) { - warning("E022", t, t.value); - } - } - - function nobreakcomma(left, right) { - if (left.line !== right.line) { - if (!state.option.laxcomma) { - if (comma.first) { - warning("I001"); - comma.first = false; - } - warning("W014", left, right.value); - } - } else if (!left.comment && left.character !== right.from && state.option.white) { - left.from += (left.character - left.from); - warning("W011", left, left.value); - } - } - - function comma(opts) { - opts = opts || {}; - - if (!opts.peek) { - nobreakcomma(state.tokens.curr, state.tokens.next); - advance(","); - } else { - nobreakcomma(state.tokens.prev, state.tokens.curr); - } - - // TODO: This is a temporary solution to fight against false-positives in - // arrays and objects with trailing commas (see GH-363). The best solution - // would be to extract all whitespace rules out of parser. - - if (state.tokens.next.value !== "]" && state.tokens.next.value !== "}") { - nonadjacent(state.tokens.curr, state.tokens.next); - } - - if (state.tokens.next.identifier && !(opts.property && state.option.inES5())) { - // Keywords that cannot follow a comma operator. - switch (state.tokens.next.value) { - case "break": - case "case": - case "catch": - case "continue": - case "default": - case "do": - case "else": - case "finally": - case "for": - case "if": - case "in": - case "instanceof": - case "return": - case "switch": - case "throw": - case "try": - case "var": - case "let": - case "while": - case "with": - error("E024", state.tokens.next, state.tokens.next.value); - return false; - } - } - - if (state.tokens.next.type === "(punctuator)") { - switch (state.tokens.next.value) { - case "}": - case "]": - case ",": - if (opts.allowTrailing) { - return true; - } - - /* falls through */ - case ")": - error("E024", state.tokens.next, state.tokens.next.value); - return false; - } - } - return true; - } - - // Functional constructors for making the symbols that will be inherited by - // tokens. - - function symbol(s, p) { - var x = state.syntax[s]; - if (!x || typeof x !== "object") { - state.syntax[s] = x = { - id: s, - lbp: p, - value: s - }; - } - return x; - } - - function delim(s) { - return symbol(s, 0); - } - - function stmt(s, f) { - var x = delim(s); - x.identifier = x.reserved = true; - x.fud = f; - return x; - } - - function blockstmt(s, f) { - var x = stmt(s, f); - x.block = true; - return x; - } - - function reserveName(x) { - var c = x.id.charAt(0); - if ((c >= "a" && c <= "z") || (c >= "A" && c <= "Z")) { - x.identifier = x.reserved = true; - } - return x; - } - - function prefix(s, f) { - var x = symbol(s, 150); - reserveName(x); - x.nud = (typeof f === "function") ? f : function () { - this.right = expression(150); - this.arity = "unary"; - if (this.id === "++" || this.id === "--") { - if (state.option.plusplus) { - warning("W016", this, this.id); - } else if (this.right && - (!this.right.identifier || isReserved(this.right)) && - this.right.id !== "." && this.right.id !== "[") { - warning("W017", this); - } - } - return this; - }; - return x; - } - - function type(s, f) { - var x = delim(s); - x.type = s; - x.nud = f; - return x; - } - - function reserve(name, func) { - var x = type(name, func); - x.identifier = true; - x.reserved = true; - return x; - } - - function FutureReservedWord(name, meta) { - var x = type(name, (meta && meta.nud) || function () { - return this; - }); - - meta = meta || {}; - meta.isFutureReservedWord = true; - - x.value = name; - x.identifier = true; - x.reserved = true; - x.meta = meta; - - return x; - } - - function reservevar(s, v) { - return reserve(s, function () { - if (typeof v === "function") { - v(this); - } - return this; - }); - } - - function infix(s, f, p, w) { - var x = symbol(s, p); - reserveName(x); - x.infix = true; - x.led = function (left) { - if (!w) { - nobreaknonadjacent(state.tokens.prev, state.tokens.curr); - nonadjacent(state.tokens.curr, state.tokens.next); - } - if (s === "in" && left.id === "!") { - warning("W018", left, "!"); - } - if (typeof f === "function") { - return f(left, this); - } else { - this.left = left; - this.right = expression(p); - return this; - } - }; - return x; - } - - - function application(s) { - var x = symbol(s, 42); - - x.led = function (left) { - if (!state.option.inESNext()) { - warning("W104", state.tokens.curr, "arrow function syntax (=>)"); - } - - nobreaknonadjacent(state.tokens.prev, state.tokens.curr); - nonadjacent(state.tokens.curr, state.tokens.next); - - this.left = left; - this.right = doFunction(undefined, undefined, false, left); - return this; - }; - return x; - } - - function relation(s, f) { - var x = symbol(s, 100); - - x.led = function (left) { - nobreaknonadjacent(state.tokens.prev, state.tokens.curr); - nonadjacent(state.tokens.curr, state.tokens.next); - var right = expression(100); - - if (isIdentifier(left, "NaN") || isIdentifier(right, "NaN")) { - warning("W019", this); - } else if (f) { - f.apply(this, [left, right]); - } - - if (!left || !right) { - quit("E041", state.tokens.curr.line); - } - - if (left.id === "!") { - warning("W018", left, "!"); - } - - if (right.id === "!") { - warning("W018", right, "!"); - } - - this.left = left; - this.right = right; - return this; - }; - return x; - } - - function isPoorRelation(node) { - return node && - ((node.type === "(number)" && +node.value === 0) || - (node.type === "(string)" && node.value === "") || - (node.type === "null" && !state.option.eqnull) || - node.type === "true" || - node.type === "false" || - node.type === "undefined"); - } - - function assignop(s, f, p) { - var x = infix(s, typeof f === "function" ? f : function (left, that) { - that.left = left; - - if (left) { - if (predefined[left.value] === false && - scope[left.value]["(global)"] === true) { - warning("W020", left); - } else if (left["function"]) { - warning("W021", left, left.value); - } - - if (funct[left.value] === "const") { - error("E013", left, left.value); - } - - if (left.id === ".") { - if (!left.left) { - warning("E031", that); - } else if (left.left.value === "arguments" && !state.directive["use strict"]) { - warning("E031", that); - } - - that.right = expression(10); - return that; - } else if (left.id === "[") { - if (state.tokens.curr.left.first) { - state.tokens.curr.left.first.forEach(function (t) { - if (funct[t.value] === "const") { - error("E013", t, t.value); - } - }); - } else if (!left.left) { - warning("E031", that); - } else if (left.left.value === "arguments" && !state.directive["use strict"]) { - warning("E031", that); - } - that.right = expression(10); - return that; - } else if (left.identifier && !isReserved(left)) { - if (funct[left.value] === "exception") { - warning("W022", left); - } - that.right = expression(10); - return that; - } - - if (left === state.syntax["function"]) { - warning("W023", state.tokens.curr); - } - } - - error("E031", that); - }, p); - - x.exps = true; - x.assign = true; - return x; - } - - - function bitwise(s, f, p) { - var x = symbol(s, p); - reserveName(x); - x.led = (typeof f === "function") ? f : function (left) { - if (state.option.bitwise) { - warning("W016", this, this.id); - } - this.left = left; - this.right = expression(p); - return this; - }; - return x; - } - - - function bitwiseassignop(s) { - return assignop(s, function (left, that) { - if (state.option.bitwise) { - warning("W016", that, that.id); - } - nonadjacent(state.tokens.prev, state.tokens.curr); - nonadjacent(state.tokens.curr, state.tokens.next); - if (left) { - if (left.id === "." || left.id === "[" || - (left.identifier && !isReserved(left))) { - expression(10); - return that; - } - if (left === state.syntax["function"]) { - warning("W023", state.tokens.curr); - } - return that; - } - error("E031", that); - }, 20); - } - - - function suffix(s) { - var x = symbol(s, 150); - - x.led = function (left) { - if (state.option.plusplus) { - warning("W016", this, this.id); - } else if ((!left.identifier || isReserved(left)) && left.id !== "." && left.id !== "[") { - warning("W017", this); - } - - this.left = left; - return this; - }; - return x; - } - - // fnparam means that this identifier is being defined as a function - // argument (see identifier()) - // prop means that this identifier is that of an object property - - function optionalidentifier(fnparam, prop) { - if (!state.tokens.next.identifier) { - return; - } - - advance(); - - var curr = state.tokens.curr; - var val = state.tokens.curr.value; - - if (!isReserved(curr)) { - return val; - } - - if (prop) { - if (state.option.inES5()) { - return val; - } - } - - if (fnparam && val === "undefined") { - return val; - } - - // Display an info message about reserved words as properties - // and ES5 but do it only once. - if (prop && !api.getCache("displayed:I002")) { - api.setCache("displayed:I002", true); - warning("I002"); - } - - warning("W024", state.tokens.curr, state.tokens.curr.id); - return val; - } - - // fnparam means that this identifier is being defined as a function - // argument - // prop means that this identifier is that of an object property - function identifier(fnparam, prop) { - var i = optionalidentifier(fnparam, prop); - if (i) { - return i; - } - if (state.tokens.curr.id === "function" && state.tokens.next.id === "(") { - warning("W025"); - } else { - error("E030", state.tokens.next, state.tokens.next.value); - } - } - - - function reachable(s) { - var i = 0, t; - if (state.tokens.next.id !== ";" || noreach) { - return; - } - for (;;) { - t = peek(i); - if (t.reach) { - return; - } - if (t.id !== "(endline)") { - if (t.id === "function") { - if (!state.option.latedef) { - break; - } - - warning("W026", t); - break; - } - - warning("W027", t, t.value, s); - break; - } - i += 1; - } - } - - - function statement(noindent) { - var values; - var i = indent, r, s = scope, t = state.tokens.next; - - if (t.id === ";") { - advance(";"); - return; - } - - // Is this a labelled statement? - var res = isReserved(t); - - // We're being more tolerant here: if someone uses - // a FutureReservedWord as a label, we warn but proceed - // anyway. - - if (res && t.meta && t.meta.isFutureReservedWord && peek().id === ":") { - warning("W024", t, t.id); - res = false; - } - - // detect a destructuring assignment - if (_.has(["[", "{"], t.value)) { - if (lookupBlockType().isDestAssign) { - if (!state.option.inESNext()) { - warning("W104", state.tokens.curr, "destructuring expression"); - } - values = destructuringExpression(); - values.forEach(function (tok) { - isundef(funct, "W117", tok.token, tok.id); - }); - advance("="); - destructuringExpressionMatch(values, expression(10, true)); - advance(";"); - return; - } - } - if (t.identifier && !res && peek().id === ":") { - advance(); - advance(":"); - scope = Object.create(s); - addlabel(t.value, "label"); - - if (!state.tokens.next.labelled && state.tokens.next.value !== "{") { - warning("W028", state.tokens.next, t.value, state.tokens.next.value); - } - - state.tokens.next.label = t.value; - t = state.tokens.next; - } - - // Is it a lonely block? - - if (t.id === "{") { - block(true, true); - return; - } - - // Parse the statement. - - if (!noindent) { - indentation(); - } - r = expression(0, true); - - // Look for the final semicolon. - - if (!t.block) { - if (!state.option.expr && (!r || !r.exps)) { - warning("W030", state.tokens.curr); - } else if (state.option.nonew && r && r.left && r.id === "(" && r.left.id === "new") { - warning("W031", t); - } - - if (state.tokens.next.id !== ";") { - if (!state.option.asi) { - // If this is the last statement in a block that ends on - // the same line *and* option lastsemic is on, ignore the warning. - // Otherwise, complain about missing semicolon. - if (!state.option.lastsemic || state.tokens.next.id !== "}" || - state.tokens.next.line !== state.tokens.curr.line) { - warningAt("W033", state.tokens.curr.line, state.tokens.curr.character); - } - } - } else { - adjacent(state.tokens.curr, state.tokens.next); - advance(";"); - nonadjacent(state.tokens.curr, state.tokens.next); - } - } - - // Restore the indentation. - - indent = i; - scope = s; - return r; - } - - - function statements(startLine) { - var a = [], p; - - while (!state.tokens.next.reach && state.tokens.next.id !== "(end)") { - if (state.tokens.next.id === ";") { - p = peek(); - - if (!p || (p.id !== "(" && p.id !== "[")) { - warning("W032"); - } - - advance(";"); - } else { - a.push(statement(startLine === state.tokens.next.line)); - } - } - return a; - } - - - /* - * read all directives - * recognizes a simple form of asi, but always - * warns, if it is used - */ - function directives() { - var i, p, pn; - - for (;;) { - if (state.tokens.next.id === "(string)") { - p = peek(0); - if (p.id === "(endline)") { - i = 1; - do { - pn = peek(i); - i = i + 1; - } while (pn.id === "(endline)"); - - if (pn.id !== ";") { - if (pn.id !== "(string)" && pn.id !== "(number)" && - pn.id !== "(regexp)" && pn.identifier !== true && - pn.id !== "}") { - break; - } - warning("W033", state.tokens.next); - } else { - p = pn; - } - } else if (p.id === "}") { - // Directive with no other statements, warn about missing semicolon - warning("W033", p); - } else if (p.id !== ";") { - break; - } - - indentation(); - advance(); - if (state.directive[state.tokens.curr.value]) { - warning("W034", state.tokens.curr, state.tokens.curr.value); - } - - if (state.tokens.curr.value === "use strict") { - if (!state.option["(explicitNewcap)"]) - state.option.newcap = true; - state.option.undef = true; - } - - // there's no directive negation, so always set to true - state.directive[state.tokens.curr.value] = true; - - if (p.id === ";") { - advance(";"); - } - continue; - } - break; - } - } - - - /* - * Parses a single block. A block is a sequence of statements wrapped in - * braces. - * - * ordinary - true for everything but function bodies and try blocks. - * stmt - true if block can be a single statement (e.g. in if/for/while). - * isfunc - true if block is a function body - */ - function block(ordinary, stmt, isfunc, isfatarrow) { - var a, - b = inblock, - old_indent = indent, - m, - s = scope, - t, - line, - d; - - inblock = ordinary; - - if (!ordinary || !state.option.funcscope) - scope = Object.create(scope); - - nonadjacent(state.tokens.curr, state.tokens.next); - t = state.tokens.next; - - var metrics = funct["(metrics)"]; - metrics.nestedBlockDepth += 1; - metrics.verifyMaxNestedBlockDepthPerFunction(); - - if (state.tokens.next.id === "{") { - advance("{"); - - // create a new block scope - funct["(blockscope)"].stack(); - - line = state.tokens.curr.line; - if (state.tokens.next.id !== "}") { - indent += state.option.indent; - while (!ordinary && state.tokens.next.from > indent) { - indent += state.option.indent; - } - - if (isfunc) { - m = {}; - for (d in state.directive) { - if (_.has(state.directive, d)) { - m[d] = state.directive[d]; - } - } - directives(); - - if (state.option.strict && funct["(context)"]["(global)"]) { - if (!m["use strict"] && !state.directive["use strict"]) { - warning("E007"); - } - } - } - - a = statements(line); - - metrics.statementCount += a.length; - - if (isfunc) { - state.directive = m; - } - - indent -= state.option.indent; - if (line !== state.tokens.next.line) { - indentation(); - } - } else if (line !== state.tokens.next.line) { - indentation(); - } - advance("}", t); - - funct["(blockscope)"].unstack(); - - indent = old_indent; - } else if (!ordinary) { - if (isfunc) { - m = {}; - if (stmt && !isfatarrow && !state.option.inMoz(true)) { - error("W118", state.tokens.curr, "function closure expressions"); - } - - if (!stmt) { - for (d in state.directive) { - if (_.has(state.directive, d)) { - m[d] = state.directive[d]; - } - } - } - expression(10); - - if (state.option.strict && funct["(context)"]["(global)"]) { - if (!m["use strict"] && !state.directive["use strict"]) { - warning("E007"); - } - } - } else { - error("E021", state.tokens.next, "{", state.tokens.next.value); - } - } else { - - // check to avoid let declaration not within a block - funct["(nolet)"] = true; - - if (!stmt || state.option.curly) { - warning("W116", state.tokens.next, "{", state.tokens.next.value); - } - - noreach = true; - indent += state.option.indent; - // test indentation only if statement is in new line - a = [statement(state.tokens.next.line === state.tokens.curr.line)]; - indent -= state.option.indent; - noreach = false; - - delete funct["(nolet)"]; - } - funct["(verb)"] = null; - if (!ordinary || !state.option.funcscope) scope = s; - inblock = b; - if (ordinary && state.option.noempty && (!a || a.length === 0)) { - warning("W035"); - } - metrics.nestedBlockDepth -= 1; - return a; - } - - - function countMember(m) { - if (membersOnly && typeof membersOnly[m] !== "boolean") { - warning("W036", state.tokens.curr, m); - } - if (typeof member[m] === "number") { - member[m] += 1; - } else { - member[m] = 1; - } - } - - - function note_implied(tkn) { - var name = tkn.value, line = tkn.line, a = implied[name]; - if (typeof a === "function") { - a = false; - } - - if (!a) { - a = [line]; - implied[name] = a; - } else if (a[a.length - 1] !== line) { - a.push(line); - } - } - - - // Build the syntax table by declaring the syntactic elements of the language. - - type("(number)", function () { - return this; - }); - - type("(string)", function () { - return this; - }); - - state.syntax["(identifier)"] = { - type: "(identifier)", - lbp: 0, - identifier: true, - nud: function () { - var v = this.value, - s = scope[v], - f; - - if (typeof s === "function") { - // Protection against accidental inheritance. - s = undefined; - } else if (typeof s === "boolean") { - f = funct; - funct = functions[0]; - addlabel(v, "var"); - s = funct; - funct = f; - } - var block; - if (_.has(funct, "(blockscope)")) { - block = funct["(blockscope)"].getlabel(v); - } - - // The name is in scope and defined in the current function. - if (funct === s || block) { - // Change 'unused' to 'var', and reject labels. - // the name is in a block scope - switch (block ? block[v]["(type)"] : funct[v]) { - case "unused": - if (block) block[v]["(type)"] = "var"; - else funct[v] = "var"; - break; - case "unction": - if (block) block[v]["(type)"] = "function"; - else funct[v] = "function"; - this["function"] = true; - break; - case "function": - this["function"] = true; - break; - case "label": - warning("W037", state.tokens.curr, v); - break; - } - } else if (funct["(global)"]) { - // The name is not defined in the function. If we are in the global - // scope, then we have an undefined variable. - // - // Operators typeof and delete do not raise runtime errors even if - // the base object of a reference is null so no need to display warning - // if we're inside of typeof or delete. - - if (typeof predefined[v] !== "boolean") { - // Attempting to subscript a null reference will throw an - // error, even within the typeof and delete operators - if (!(anonname === "typeof" || anonname === "delete") || - (state.tokens.next && (state.tokens.next.value === "." || - state.tokens.next.value === "["))) { - - // if we're in a list comprehension, variables are declared - // locally and used before being defined. So we check - // the presence of the given variable in the comp array - // before declaring it undefined. - - if (!funct["(comparray)"].check(v)) { - isundef(funct, "W117", state.tokens.curr, v); - } - } - } - - note_implied(state.tokens.curr); - } else { - // If the name is already defined in the current - // function, but not as outer, then there is a scope error. - - switch (funct[v]) { - case "closure": - case "function": - case "var": - case "unused": - warning("W038", state.tokens.curr, v); - break; - case "label": - warning("W037", state.tokens.curr, v); - break; - case "outer": - case "global": - break; - default: - // If the name is defined in an outer function, make an outer entry, - // and if it was unused, make it var. - if (s === true) { - funct[v] = true; - } else if (s === null) { - warning("W039", state.tokens.curr, v); - note_implied(state.tokens.curr); - } else if (typeof s !== "object") { - // Operators typeof and delete do not raise runtime errors even - // if the base object of a reference is null so no need to - // - // display warning if we're inside of typeof or delete. - // Attempting to subscript a null reference will throw an - // error, even within the typeof and delete operators - if (!(anonname === "typeof" || anonname === "delete") || - (state.tokens.next && - (state.tokens.next.value === "." || state.tokens.next.value === "["))) { - - isundef(funct, "W117", state.tokens.curr, v); - } - funct[v] = true; - note_implied(state.tokens.curr); - } else { - switch (s[v]) { - case "function": - case "unction": - this["function"] = true; - s[v] = "closure"; - funct[v] = s["(global)"] ? "global" : "outer"; - break; - case "var": - case "unused": - s[v] = "closure"; - funct[v] = s["(global)"] ? "global" : "outer"; - break; - case "closure": - funct[v] = s["(global)"] ? "global" : "outer"; - break; - case "label": - warning("W037", state.tokens.curr, v); - } - } - } - } - return this; - }, - led: function () { - error("E033", state.tokens.next, state.tokens.next.value); - } - }; - - type("(regexp)", function () { - return this; - }); - - // ECMAScript parser - - delim("(endline)"); - delim("(begin)"); - delim("(end)").reach = true; - delim("(error)").reach = true; - delim("}").reach = true; - delim(")"); - delim("]"); - delim("\"").reach = true; - delim("'").reach = true; - delim(";"); - delim(":").reach = true; - delim("#"); - - reserve("else"); - reserve("case").reach = true; - reserve("catch"); - reserve("default").reach = true; - reserve("finally"); - reservevar("arguments", function (x) { - if (state.directive["use strict"] && funct["(global)"]) { - warning("E008", x); - } - }); - reservevar("eval"); - reservevar("false"); - reservevar("Infinity"); - reservevar("null"); - reservevar("this", function (x) { - if (state.directive["use strict"] && !state.option.validthis && ((funct["(statement)"] && - funct["(name)"].charAt(0) > "Z") || funct["(global)"])) { - warning("W040", x); - } - }); - reservevar("true"); - reservevar("undefined"); - - assignop("=", "assign", 20); - assignop("+=", "assignadd", 20); - assignop("-=", "assignsub", 20); - assignop("*=", "assignmult", 20); - assignop("/=", "assigndiv", 20).nud = function () { - error("E014"); - }; - assignop("%=", "assignmod", 20); - - bitwiseassignop("&=", "assignbitand", 20); - bitwiseassignop("|=", "assignbitor", 20); - bitwiseassignop("^=", "assignbitxor", 20); - bitwiseassignop("<<=", "assignshiftleft", 20); - bitwiseassignop(">>=", "assignshiftright", 20); - bitwiseassignop(">>>=", "assignshiftrightunsigned", 20); - infix(",", function (left, that) { - var expr; - that.exprs = [left]; - if (!comma({peek: true})) { - return that; - } - while (true) { - if (!(expr = expression(10))) { - break; - } - that.exprs.push(expr); - if (state.tokens.next.value !== "," || !comma()) { - break; - } - } - return that; - }, 10, true); - - infix("?", function (left, that) { - increaseComplexityCount(); - that.left = left; - that.right = expression(10); - advance(":"); - that["else"] = expression(10); - return that; - }, 30); - - var orPrecendence = 40; - infix("||", function (left, that) { - increaseComplexityCount(); - that.left = left; - that.right = expression(orPrecendence); - return that; - }, orPrecendence); - infix("&&", "and", 50); - bitwise("|", "bitor", 70); - bitwise("^", "bitxor", 80); - bitwise("&", "bitand", 90); - relation("==", function (left, right) { - var eqnull = state.option.eqnull && (left.value === "null" || right.value === "null"); - - if (!eqnull && state.option.eqeqeq) - warning("W116", this, "===", "=="); - else if (isPoorRelation(left)) - warning("W041", this, "===", left.value); - else if (isPoorRelation(right)) - warning("W041", this, "===", right.value); - - return this; - }); - relation("==="); - relation("!=", function (left, right) { - var eqnull = state.option.eqnull && - (left.value === "null" || right.value === "null"); - - if (!eqnull && state.option.eqeqeq) { - warning("W116", this, "!==", "!="); - } else if (isPoorRelation(left)) { - warning("W041", this, "!==", left.value); - } else if (isPoorRelation(right)) { - warning("W041", this, "!==", right.value); - } - return this; - }); - relation("!=="); - relation("<"); - relation(">"); - relation("<="); - relation(">="); - bitwise("<<", "shiftleft", 120); - bitwise(">>", "shiftright", 120); - bitwise(">>>", "shiftrightunsigned", 120); - infix("in", "in", 120); - infix("instanceof", "instanceof", 120); - infix("+", function (left, that) { - var right = expression(130); - if (left && right && left.id === "(string)" && right.id === "(string)") { - left.value += right.value; - left.character = right.character; - if (!state.option.scripturl && reg.javascriptURL.test(left.value)) { - warning("W050", left); - } - return left; - } - that.left = left; - that.right = right; - return that; - }, 130); - prefix("+", "num"); - prefix("+++", function () { - warning("W007"); - this.right = expression(150); - this.arity = "unary"; - return this; - }); - infix("+++", function (left) { - warning("W007"); - this.left = left; - this.right = expression(130); - return this; - }, 130); - infix("-", "sub", 130); - prefix("-", "neg"); - prefix("---", function () { - warning("W006"); - this.right = expression(150); - this.arity = "unary"; - return this; - }); - infix("---", function (left) { - warning("W006"); - this.left = left; - this.right = expression(130); - return this; - }, 130); - infix("*", "mult", 140); - infix("/", "div", 140); - infix("%", "mod", 140); - - suffix("++", "postinc"); - prefix("++", "preinc"); - state.syntax["++"].exps = true; - - suffix("--", "postdec"); - prefix("--", "predec"); - state.syntax["--"].exps = true; - prefix("delete", function () { - var p = expression(10); - if (!p || (p.id !== "." && p.id !== "[")) { - warning("W051"); - } - this.first = p; - return this; - }).exps = true; - - prefix("~", function () { - if (state.option.bitwise) { - warning("W052", this, "~"); - } - expression(150); - return this; - }); - - prefix("...", function () { - if (!state.option.inESNext()) { - warning("W104", this, "spread/rest operator"); - } - if (!state.tokens.next.identifier) { - error("E030", state.tokens.next, state.tokens.next.value); - } - expression(150); - return this; - }); - - prefix("!", function () { - this.right = expression(150); - this.arity = "unary"; - - if (!this.right) { // '!' followed by nothing? Give up. - quit("E041", this.line || 0); - } - - if (bang[this.right.id] === true) { - warning("W018", this, "!"); - } - return this; - }); - - prefix("typeof", "typeof"); - prefix("new", function () { - var c = expression(155), i; - if (c && c.id !== "function") { - if (c.identifier) { - c["new"] = true; - switch (c.value) { - case "Number": - case "String": - case "Boolean": - case "Math": - case "JSON": - warning("W053", state.tokens.prev, c.value); - break; - case "Function": - if (!state.option.evil) { - warning("W054"); - } - break; - case "Date": - case "RegExp": - break; - default: - if (c.id !== "function") { - i = c.value.substr(0, 1); - if (state.option.newcap && (i < "A" || i > "Z") && !_.has(global, c.value)) { - warning("W055", state.tokens.curr); - } - } - } - } else { - if (c.id !== "." && c.id !== "[" && c.id !== "(") { - warning("W056", state.tokens.curr); - } - } - } else { - if (!state.option.supernew) - warning("W057", this); - } - adjacent(state.tokens.curr, state.tokens.next); - if (state.tokens.next.id !== "(" && !state.option.supernew) { - warning("W058", state.tokens.curr, state.tokens.curr.value); - } - this.first = c; - return this; - }); - state.syntax["new"].exps = true; - - prefix("void").exps = true; - - infix(".", function (left, that) { - adjacent(state.tokens.prev, state.tokens.curr); - nobreak(); - var m = identifier(false, true); - - if (typeof m === "string") { - countMember(m); - } - - that.left = left; - that.right = m; - - if (m && m === "hasOwnProperty" && state.tokens.next.value === "=") { - warning("W001"); - } - - if (left && left.value === "arguments" && (m === "callee" || m === "caller")) { - if (state.option.noarg) - warning("W059", left, m); - else if (state.directive["use strict"]) - error("E008"); - } else if (!state.option.evil && left && left.value === "document" && - (m === "write" || m === "writeln")) { - warning("W060", left); - } - - if (!state.option.evil && (m === "eval" || m === "execScript")) { - warning("W061"); - } - - return that; - }, 160, true); - - infix("(", function (left, that) { - if (state.tokens.prev.id !== "}" && state.tokens.prev.id !== ")") { - nobreak(state.tokens.prev, state.tokens.curr); - } - - nospace(); - if (state.option.immed && left && !left.immed && left.id === "function") { - warning("W062"); - } - - var n = 0; - var p = []; - - if (left) { - if (left.type === "(identifier)") { - if (left.value.match(/^[A-Z]([A-Z0-9_$]*[a-z][A-Za-z0-9_$]*)?$/)) { - if ("Number String Boolean Date Object".indexOf(left.value) === -1) { - if (left.value === "Math") { - warning("W063", left); - } else if (state.option.newcap) { - warning("W064", left); - } - } - } - } - } - - if (state.tokens.next.id !== ")") { - for (;;) { - p[p.length] = expression(10); - n += 1; - if (state.tokens.next.id !== ",") { - break; - } - comma(); - } - } - - advance(")"); - nospace(state.tokens.prev, state.tokens.curr); - - if (typeof left === "object") { - if (left.value === "parseInt" && n === 1) { - warning("W065", state.tokens.curr); - } - if (!state.option.evil) { - if (left.value === "eval" || left.value === "Function" || - left.value === "execScript") { - warning("W061", left); - - if (p[0] && [0].id === "(string)") { - addInternalSrc(left, p[0].value); - } - } else if (p[0] && p[0].id === "(string)" && - (left.value === "setTimeout" || - left.value === "setInterval")) { - warning("W066", left); - addInternalSrc(left, p[0].value); - - // window.setTimeout/setInterval - } else if (p[0] && p[0].id === "(string)" && - left.value === "." && - left.left.value === "window" && - (left.right === "setTimeout" || - left.right === "setInterval")) { - warning("W066", left); - addInternalSrc(left, p[0].value); - } - } - if (!left.identifier && left.id !== "." && left.id !== "[" && - left.id !== "(" && left.id !== "&&" && left.id !== "||" && - left.id !== "?") { - warning("W067", left); - } - } - - that.left = left; - return that; - }, 155, true).exps = true; - - prefix("(", function () { - nospace(); - var bracket, brackets = []; - var pn, pn1, i = 0; - var ret; - - do { - pn = peek(i); - i += 1; - pn1 = peek(i); - i += 1; - } while (pn.value !== ")" && pn1.value !== "=>" && pn1.value !== ";" && pn1.type !== "(end)"); - - if (state.tokens.next.id === "function") { - state.tokens.next.immed = true; - } - - var exprs = []; - - if (state.tokens.next.id !== ")") { - for (;;) { - if (pn1.value === "=>" && state.tokens.next.value === "{") { - bracket = state.tokens.next; - bracket.left = destructuringExpression(); - brackets.push(bracket); - for (var t in bracket.left) { - exprs.push(bracket.left[t].token); - } - } else { - exprs.push(expression(10)); - } - if (state.tokens.next.id !== ",") { - break; - } - comma(); - } - } - - advance(")", this); - nospace(state.tokens.prev, state.tokens.curr); - if (state.option.immed && exprs[0] && exprs[0].id === "function") { - if (state.tokens.next.id !== "(" && - (state.tokens.next.id !== "." || (peek().value !== "call" && peek().value !== "apply"))) { - warning("W068", this); - } - } - - if (state.tokens.next.value === "=>") { - return exprs; - } - if (!exprs.length) { - return; - } - if (exprs.length > 1) { - ret = Object.create(state.syntax[","]); - ret.exprs = exprs; - } else { - ret = exprs[0]; - } - if (ret) { - ret.paren = true; - } - return ret; - }); - - application("=>"); - - infix("[", function (left, that) { - nobreak(state.tokens.prev, state.tokens.curr); - nospace(); - var e = expression(10), s; - if (e && e.type === "(string)") { - if (!state.option.evil && (e.value === "eval" || e.value === "execScript")) { - warning("W061", that); - } - - countMember(e.value); - if (!state.option.sub && reg.identifier.test(e.value)) { - s = state.syntax[e.value]; - if (!s || !isReserved(s)) { - warning("W069", state.tokens.prev, e.value); - } - } - } - advance("]", that); - - if (e && e.value === "hasOwnProperty" && state.tokens.next.value === "=") { - warning("W001"); - } - - nospace(state.tokens.prev, state.tokens.curr); - that.left = left; - that.right = e; - return that; - }, 160, true); - - function comprehensiveArrayExpression() { - var res = {}; - res.exps = true; - funct["(comparray)"].stack(); - - res.right = expression(10); - advance("for"); - if (state.tokens.next.value === "each") { - advance("each"); - if (!state.option.inMoz(true)) { - warning("W118", state.tokens.curr, "for each"); - } - } - advance("("); - funct["(comparray)"].setState("define"); - res.left = expression(10); - advance(")"); - if (state.tokens.next.value === "if") { - advance("if"); - advance("("); - funct["(comparray)"].setState("filter"); - res.filter = expression(10); - advance(")"); - } - advance("]"); - funct["(comparray)"].unstack(); - return res; - } - - prefix("[", function () { - var blocktype = lookupBlockType(true); - if (blocktype.isCompArray) { - if (!state.option.inMoz(true)) { - warning("W118", state.tokens.curr, "array comprehension"); - } - return comprehensiveArrayExpression(); - } else if (blocktype.isDestAssign && !state.option.inESNext()) { - warning("W104", state.tokens.curr, "destructuring assignment"); - } - var b = state.tokens.curr.line !== state.tokens.next.line; - this.first = []; - if (b) { - indent += state.option.indent; - if (state.tokens.next.from === indent + state.option.indent) { - indent += state.option.indent; - } - } - while (state.tokens.next.id !== "(end)") { - while (state.tokens.next.id === ",") { - if (!state.option.inES5()) - warning("W070"); - advance(","); - } - if (state.tokens.next.id === "]") { - break; - } - if (b && state.tokens.curr.line !== state.tokens.next.line) { - indentation(); - } - this.first.push(expression(10)); - if (state.tokens.next.id === ",") { - comma({ allowTrailing: true }); - if (state.tokens.next.id === "]" && !state.option.inES5(true)) { - warning("W070", state.tokens.curr); - break; - } - } else { - break; - } - } - if (b) { - indent -= state.option.indent; - indentation(); - } - advance("]", this); - return this; - }, 160); - - - function property_name() { - var id = optionalidentifier(false, true); - - if (!id) { - if (state.tokens.next.id === "(string)") { - id = state.tokens.next.value; - advance(); - } else if (state.tokens.next.id === "(number)") { - id = state.tokens.next.value.toString(); - advance(); - } - } - - if (id === "hasOwnProperty") { - warning("W001"); - } - - return id; - } - - - function functionparams(parsed) { - var curr, next; - var params = []; - var ident; - var tokens = []; - var t; - var pastDefault = false; - - if (parsed) { - if (parsed instanceof Array) { - for (var i in parsed) { - curr = parsed[i]; - if (_.contains(["{", "["], curr.id)) { - for (t in curr.left) { - t = tokens[t]; - if (t.id) { - params.push(t.id); - addlabel(t.id, "unused", t.token); - } - } - } else if (curr.value === "...") { - if (!state.option.inESNext()) { - warning("W104", curr, "spread/rest operator"); - } - continue; - } else { - addlabel(curr.value, "unused", curr); - } - } - return params; - } else { - if (parsed.identifier === true) { - addlabel(parsed.value, "unused", parsed); - return [parsed]; - } - } - } - - next = state.tokens.next; - - advance("("); - nospace(); - - if (state.tokens.next.id === ")") { - advance(")"); - return; - } - - for (;;) { - if (_.contains(["{", "["], state.tokens.next.id)) { - tokens = destructuringExpression(); - for (t in tokens) { - t = tokens[t]; - if (t.id) { - params.push(t.id); - addlabel(t.id, "unused", t.token); - } - } - } else if (state.tokens.next.value === "...") { - if (!state.option.inESNext()) { - warning("W104", state.tokens.next, "spread/rest operator"); - } - advance("..."); - nospace(); - ident = identifier(true); - params.push(ident); - addlabel(ident, "unused", state.tokens.curr); - } else { - ident = identifier(true); - params.push(ident); - addlabel(ident, "unused", state.tokens.curr); - } - - // it is a syntax error to have a regular argument after a default argument - if (pastDefault) { - if (state.tokens.next.id !== "=") { - error("E051", state.tokens.current); - } - } - if (state.tokens.next.id === "=") { - if (!state.option.inESNext()) { - warning("W119", state.tokens.next, "default parameters"); - } - advance("="); - pastDefault = true; - expression(10); - } - if (state.tokens.next.id === ",") { - comma(); - } else { - advance(")", next); - nospace(state.tokens.prev, state.tokens.curr); - return params; - } - } - } - - - function doFunction(name, statement, generator, fatarrowparams) { - var f; - var oldOption = state.option; - var oldIgnored = state.ignored; - var oldScope = scope; - - state.option = Object.create(state.option); - state.ignored = Object.create(state.ignored); - scope = Object.create(scope); - - funct = { - "(name)" : name || "\"" + anonname + "\"", - "(line)" : state.tokens.next.line, - "(character)" : state.tokens.next.character, - "(context)" : funct, - "(breakage)" : 0, - "(loopage)" : 0, - "(metrics)" : createMetrics(state.tokens.next), - "(scope)" : scope, - "(statement)" : statement, - "(tokens)" : {}, - "(blockscope)": funct["(blockscope)"], - "(comparray)" : funct["(comparray)"] - }; - - if (generator) { - funct["(generator)"] = true; - } - - f = funct; - state.tokens.curr.funct = funct; - - functions.push(funct); - - if (name) { - addlabel(name, "function"); - } - - funct["(params)"] = functionparams(fatarrowparams); - - funct["(metrics)"].verifyMaxParametersPerFunction(funct["(params)"]); - - block(false, true, true, fatarrowparams ? true:false); - - if (generator && funct["(generator)"] !== "yielded") { - error("E047", state.tokens.curr); - } - - funct["(metrics)"].verifyMaxStatementsPerFunction(); - funct["(metrics)"].verifyMaxComplexityPerFunction(); - funct["(unusedOption)"] = state.option.unused; - - scope = oldScope; - state.option = oldOption; - state.ignored = oldIgnored; - funct["(last)"] = state.tokens.curr.line; - funct["(lastcharacter)"] = state.tokens.curr.character; - funct = funct["(context)"]; - - return f; - } - - function createMetrics(functionStartToken) { - return { - statementCount: 0, - nestedBlockDepth: -1, - ComplexityCount: 1, - verifyMaxStatementsPerFunction: function () { - if (state.option.maxstatements && - this.statementCount > state.option.maxstatements) { - warning("W071", functionStartToken, this.statementCount); - } - }, - - verifyMaxParametersPerFunction: function (params) { - params = params || []; - - if (state.option.maxparams && params.length > state.option.maxparams) { - warning("W072", functionStartToken, params.length); - } - }, - - verifyMaxNestedBlockDepthPerFunction: function () { - if (state.option.maxdepth && - this.nestedBlockDepth > 0 && - this.nestedBlockDepth === state.option.maxdepth + 1) { - warning("W073", null, this.nestedBlockDepth); - } - }, - - verifyMaxComplexityPerFunction: function () { - var max = state.option.maxcomplexity; - var cc = this.ComplexityCount; - if (max && cc > max) { - warning("W074", functionStartToken, cc); - } - } - }; - } - - function increaseComplexityCount() { - funct["(metrics)"].ComplexityCount += 1; - } - - // Parse assignments that were found instead of conditionals. - // For example: if (a = 1) { ... } - - function checkCondAssignment(expr) { - var id, paren; - if (expr) { - id = expr.id; - paren = expr.paren; - if (id === "," && (expr = expr.exprs[expr.exprs.length - 1])) { - id = expr.id; - paren = paren || expr.paren; - } - } - switch (id) { - case "=": - case "+=": - case "-=": - case "*=": - case "%=": - case "&=": - case "|=": - case "^=": - case "/=": - if (!paren && !state.option.boss) { - warning("W084"); - } - } - } - - - (function (x) { - x.nud = function (isclassdef) { - var b, f, i, p, t, g; - var props = {}; // All properties, including accessors - var tag = ""; - - function saveProperty(name, tkn) { - if (props[name] && _.has(props, name)) - warning("W075", state.tokens.next, i); - else - props[name] = {}; - - props[name].basic = true; - props[name].basictkn = tkn; - } - - function saveSetter(name, tkn) { - if (props[name] && _.has(props, name)) { - if (props[name].basic || props[name].setter) - warning("W075", state.tokens.next, i); - } else { - props[name] = {}; - } - - props[name].setter = true; - props[name].setterToken = tkn; - } - - function saveGetter(name) { - if (props[name] && _.has(props, name)) { - if (props[name].basic || props[name].getter) - warning("W075", state.tokens.next, i); - } else { - props[name] = {}; - } - - props[name].getter = true; - props[name].getterToken = state.tokens.curr; - } - - b = state.tokens.curr.line !== state.tokens.next.line; - if (b) { - indent += state.option.indent; - if (state.tokens.next.from === indent + state.option.indent) { - indent += state.option.indent; - } - } - - for (;;) { - if (state.tokens.next.id === "}") { - break; - } - - if (b) { - indentation(); - } - - if (isclassdef && state.tokens.next.value === "static") { - advance("static"); - tag = "static "; - } - - if (state.tokens.next.value === "get" && peek().id !== ":") { - advance("get"); - - if (!state.option.inES5(!isclassdef)) { - error("E034"); - } - - i = property_name(); - if (!i) { - error("E035"); - } - - // It is a Syntax Error if PropName of MethodDefinition is - // "constructor" and SpecialMethod of MethodDefinition is true. - if (isclassdef && i === "constructor") { - error("E049", state.tokens.next, "class getter method", i); - } - - saveGetter(tag + i); - t = state.tokens.next; - adjacent(state.tokens.curr, state.tokens.next); - f = doFunction(); - p = f["(params)"]; - - if (p) { - warning("W076", t, p[0], i); - } - - adjacent(state.tokens.curr, state.tokens.next); - } else if (state.tokens.next.value === "set" && peek().id !== ":") { - advance("set"); - - if (!state.option.inES5(!isclassdef)) { - error("E034"); - } - - i = property_name(); - if (!i) { - error("E035"); - } - - // It is a Syntax Error if PropName of MethodDefinition is - // "constructor" and SpecialMethod of MethodDefinition is true. - if (isclassdef && i === "constructor") { - error("E049", state.tokens.next, "class setter method", i); - } - - saveSetter(tag + i, state.tokens.next); - t = state.tokens.next; - adjacent(state.tokens.curr, state.tokens.next); - f = doFunction(); - p = f["(params)"]; - - if (!p || p.length !== 1) { - warning("W077", t, i); - } - } else { - g = false; - if (state.tokens.next.value === "*" && state.tokens.next.type === "(punctuator)") { - if (!state.option.inESNext()) { - warning("W104", state.tokens.next, "generator functions"); - } - advance("*"); - g = true; - } - i = property_name(); - saveProperty(tag + i, state.tokens.next); - - if (typeof i !== "string") { - break; - } - - if (state.tokens.next.value === "(") { - if (!state.option.inESNext()) { - warning("W104", state.tokens.curr, "concise methods"); - } - doFunction(i, undefined, g); - } else if (!isclassdef) { - advance(":"); - nonadjacent(state.tokens.curr, state.tokens.next); - expression(10); - } - } - // It is a Syntax Error if PropName of MethodDefinition is "prototype". - if (isclassdef && i === "prototype") { - error("E049", state.tokens.next, "class method", i); - } - - countMember(i); - if (isclassdef) { - tag = ""; - continue; - } - if (state.tokens.next.id === ",") { - comma({ allowTrailing: true, property: true }); - if (state.tokens.next.id === ",") { - warning("W070", state.tokens.curr); - } else if (state.tokens.next.id === "}" && !state.option.inES5(true)) { - warning("W070", state.tokens.curr); - } - } else { - break; - } - } - if (b) { - indent -= state.option.indent; - indentation(); - } - advance("}", this); - - // Check for lonely setters if in the ES5 mode. - if (state.option.inES5()) { - for (var name in props) { - if (_.has(props, name) && props[name].setter && !props[name].getter) { - warning("W078", props[name].setterToken); - } - } - } - return this; - }; - x.fud = function () { - error("E036", state.tokens.curr); - }; - }(delim("{"))); - - function destructuringExpression() { - var id, ids; - var identifiers = []; - if (!state.option.inESNext()) { - warning("W104", state.tokens.curr, "destructuring expression"); - } - var nextInnerDE = function () { - var ident; - if (_.contains(["[", "{"], state.tokens.next.value)) { - ids = destructuringExpression(); - for (var id in ids) { - id = ids[id]; - identifiers.push({ id: id.id, token: id.token }); - } - } else if (state.tokens.next.value === ",") { - identifiers.push({ id: null, token: state.tokens.curr }); - } else { - ident = identifier(); - if (ident) - identifiers.push({ id: ident, token: state.tokens.curr }); - } - }; - if (state.tokens.next.value === "[") { - advance("["); - nextInnerDE(); - while (state.tokens.next.value !== "]") { - advance(","); - nextInnerDE(); - } - advance("]"); - } else if (state.tokens.next.value === "{") { - advance("{"); - id = identifier(); - if (state.tokens.next.value === ":") { - advance(":"); - nextInnerDE(); - } else { - identifiers.push({ id: id, token: state.tokens.curr }); - } - while (state.tokens.next.value !== "}") { - advance(","); - id = identifier(); - if (state.tokens.next.value === ":") { - advance(":"); - nextInnerDE(); - } else { - identifiers.push({ id: id, token: state.tokens.curr }); - } - } - advance("}"); - } - return identifiers; - } - function destructuringExpressionMatch(tokens, value) { - if (value.first) { - _.zip(tokens, value.first).forEach(function (val) { - var token = val[0]; - var value = val[1]; - if (token && value) { - token.first = value; - } else if (token && token.first && !value) { - warning("W080", token.first, token.first.value); - } /* else { - XXX value is discarded: wouldn't it need a warning ? - } */ - }); - } - } - - var conststatement = stmt("const", function (prefix) { - var tokens, value; - // state variable to know if it is a lone identifier, or a destructuring statement. - var lone; - - if (!state.option.inESNext()) { - warning("W104", state.tokens.curr, "const"); - } - - this.first = []; - for (;;) { - var names = []; - nonadjacent(state.tokens.curr, state.tokens.next); - if (_.contains(["{", "["], state.tokens.next.value)) { - tokens = destructuringExpression(); - lone = false; - } else { - tokens = [ { id: identifier(), token: state.tokens.curr } ]; - lone = true; - } - for (var t in tokens) { - t = tokens[t]; - if (funct[t.id] === "const") { - warning("E011", null, t.id); - } - if (funct["(global)"] && predefined[t.id] === false) { - warning("W079", t.token, t.id); - } - if (t.id) { - addlabel(t.id, "const"); - names.push(t.token); - } - } - if (prefix) { - break; - } - - this.first = this.first.concat(names); - - if (state.tokens.next.id !== "=") { - warning("E012", state.tokens.curr, state.tokens.curr.value); - } - - if (state.tokens.next.id === "=") { - nonadjacent(state.tokens.curr, state.tokens.next); - advance("="); - nonadjacent(state.tokens.curr, state.tokens.next); - if (state.tokens.next.id === "undefined") { - warning("W080", state.tokens.prev, state.tokens.prev.value); - } - if (peek(0).id === "=" && state.tokens.next.identifier) { - warning("W120", state.tokens.next, state.tokens.next.value); - } - value = expression(10); - if (lone) { - tokens[0].first = value; - } else { - destructuringExpressionMatch(names, value); - } - } - - if (state.tokens.next.id !== ",") { - break; - } - comma(); - } - return this; - }); - conststatement.exps = true; - var varstatement = stmt("var", function (prefix) { - // JavaScript does not have block scope. It only has function scope. So, - // declaring a variable in a block can have unexpected consequences. - var tokens, lone, value; - - if (funct["(onevar)"] && state.option.onevar) { - warning("W081"); - } else if (!funct["(global)"]) { - funct["(onevar)"] = true; - } - - this.first = []; - for (;;) { - var names = []; - nonadjacent(state.tokens.curr, state.tokens.next); - if (_.contains(["{", "["], state.tokens.next.value)) { - tokens = destructuringExpression(); - lone = false; - } else { - tokens = [ { id: identifier(), token: state.tokens.curr } ]; - lone = true; - } - for (var t in tokens) { - t = tokens[t]; - if (state.option.inESNext() && funct[t.id] === "const") { - warning("E011", null, t.id); - } - if (funct["(global)"] && predefined[t.id] === false) { - warning("W079", t.token, t.id); - } - if (t.id) { - addlabel(t.id, "unused", t.token); - names.push(t.token); - } - } - if (prefix) { - break; - } - - this.first = this.first.concat(names); - - if (state.tokens.next.id === "=") { - nonadjacent(state.tokens.curr, state.tokens.next); - advance("="); - nonadjacent(state.tokens.curr, state.tokens.next); - if (state.tokens.next.id === "undefined") { - warning("W080", state.tokens.prev, state.tokens.prev.value); - } - if (peek(0).id === "=" && state.tokens.next.identifier) { - warning("W120", state.tokens.next, state.tokens.next.value); - } - value = expression(10); - if (lone) { - tokens[0].first = value; - } else { - destructuringExpressionMatch(names, value); - } - } - - if (state.tokens.next.id !== ",") { - break; - } - comma(); - } - return this; - }); - varstatement.exps = true; - var letstatement = stmt("let", function (prefix) { - var tokens, lone, value, letblock; - - if (!state.option.inESNext()) { - warning("W104", state.tokens.curr, "let"); - } - - if (state.tokens.next.value === "(") { - if (!state.option.inMoz(true)) { - warning("W118", state.tokens.next, "let block"); - } - advance("("); - funct["(blockscope)"].stack(); - letblock = true; - } else if (funct["(nolet)"]) { - error("E048", state.tokens.curr); - } - - if (funct["(onevar)"] && state.option.onevar) { - warning("W081"); - } else if (!funct["(global)"]) { - funct["(onevar)"] = true; - } - - this.first = []; - for (;;) { - var names = []; - nonadjacent(state.tokens.curr, state.tokens.next); - if (_.contains(["{", "["], state.tokens.next.value)) { - tokens = destructuringExpression(); - lone = false; - } else { - tokens = [ { id: identifier(), token: state.tokens.curr.value } ]; - lone = true; - } - for (var t in tokens) { - t = tokens[t]; - if (state.option.inESNext() && funct[t.id] === "const") { - warning("E011", null, t.id); - } - if (funct["(global)"] && predefined[t.id] === false) { - warning("W079", t.token, t.id); - } - if (t.id && !funct["(nolet)"]) { - addlabel(t.id, "unused", t.token, true); - names.push(t.token); - } - } - if (prefix) { - break; - } - - this.first = this.first.concat(names); - - if (state.tokens.next.id === "=") { - nonadjacent(state.tokens.curr, state.tokens.next); - advance("="); - nonadjacent(state.tokens.curr, state.tokens.next); - if (state.tokens.next.id === "undefined") { - warning("W080", state.tokens.prev, state.tokens.prev.value); - } - if (peek(0).id === "=" && state.tokens.next.identifier) { - warning("W120", state.tokens.next, state.tokens.next.value); - } - value = expression(10); - if (lone) { - tokens[0].first = value; - } else { - destructuringExpressionMatch(names, value); - } - } - - if (state.tokens.next.id !== ",") { - break; - } - comma(); - } - if (letblock) { - advance(")"); - block(true, true); - this.block = true; - funct["(blockscope)"].unstack(); - } - - return this; - }); - letstatement.exps = true; - - blockstmt("class", function () { - return classdef.call(this, true); - }); - - function classdef(stmt) { - /*jshint validthis:true */ - if (!state.option.inESNext()) { - warning("W104", state.tokens.curr, "class"); - } - if (stmt) { - // BindingIdentifier - this.name = identifier(); - addlabel(this.name, "unused", state.tokens.curr); - } else if (state.tokens.next.identifier && state.tokens.next.value !== "extends") { - // BindingIdentifier(opt) - this.name = identifier(); - } - classtail(this); - return this; - } - - function classtail(c) { - var strictness = state.directive["use strict"]; - - // ClassHeritage(opt) - if (state.tokens.next.value === "extends") { - advance("extends"); - c.heritage = expression(10); - } - - // A ClassBody is always strict code. - state.directive["use strict"] = true; - advance("{"); - // ClassBody(opt) - c.body = state.syntax["{"].nud(true); - state.directive["use strict"] = strictness; - } - - blockstmt("function", function () { - var generator = false; - if (state.tokens.next.value === "*") { - advance("*"); - if (state.option.inESNext(true)) { - generator = true; - } else { - warning("W119", state.tokens.curr, "function*"); - } - } - if (inblock) { - warning("W082", state.tokens.curr); - - } - var i = identifier(); - if (funct[i] === "const") { - warning("E011", null, i); - } - adjacent(state.tokens.curr, state.tokens.next); - addlabel(i, "unction", state.tokens.curr); - - doFunction(i, { statement: true }, generator); - if (state.tokens.next.id === "(" && state.tokens.next.line === state.tokens.curr.line) { - error("E039"); - } - return this; - }); - - prefix("function", function () { - var generator = false; - if (state.tokens.next.value === "*") { - if (!state.option.inESNext()) { - warning("W119", state.tokens.curr, "function*"); - } - advance("*"); - generator = true; - } - var i = optionalidentifier(); - if (i || state.option.gcl) { - adjacent(state.tokens.curr, state.tokens.next); - } else { - nonadjacent(state.tokens.curr, state.tokens.next); - } - doFunction(i, undefined, generator); - if (!state.option.loopfunc && funct["(loopage)"]) { - warning("W083"); - } - return this; - }); - - blockstmt("if", function () { - var t = state.tokens.next; - increaseComplexityCount(); - state.condition = true; - advance("("); - nonadjacent(this, t); - nospace(); - checkCondAssignment(expression(0)); - advance(")", t); - state.condition = false; - nospace(state.tokens.prev, state.tokens.curr); - block(true, true); - if (state.tokens.next.id === "else") { - nonadjacent(state.tokens.curr, state.tokens.next); - advance("else"); - if (state.tokens.next.id === "if" || state.tokens.next.id === "switch") { - statement(true); - } else { - block(true, true); - } - } - return this; - }); - - blockstmt("try", function () { - var b; - - function doCatch() { - var oldScope = scope; - var e; - - advance("catch"); - nonadjacent(state.tokens.curr, state.tokens.next); - advance("("); - - scope = Object.create(oldScope); - - e = state.tokens.next.value; - if (state.tokens.next.type !== "(identifier)") { - e = null; - warning("E030", state.tokens.next, e); - } - - advance(); - - funct = { - "(name)" : "(catch)", - "(line)" : state.tokens.next.line, - "(character)": state.tokens.next.character, - "(context)" : funct, - "(breakage)" : funct["(breakage)"], - "(loopage)" : funct["(loopage)"], - "(scope)" : scope, - "(statement)": false, - "(metrics)" : createMetrics(state.tokens.next), - "(catch)" : true, - "(tokens)" : {}, - "(blockscope)": funct["(blockscope)"], - "(comparray)": funct["(comparray)"] - }; - - if (e) { - addlabel(e, "exception"); - } - - if (state.tokens.next.value === "if") { - if (!state.option.inMoz(true)) { - warning("W118", state.tokens.curr, "catch filter"); - } - advance("if"); - expression(0); - } - - advance(")"); - - state.tokens.curr.funct = funct; - functions.push(funct); - - block(false); - - scope = oldScope; - - funct["(last)"] = state.tokens.curr.line; - funct["(lastcharacter)"] = state.tokens.curr.character; - funct = funct["(context)"]; - } - - block(false); - - while (state.tokens.next.id === "catch") { - increaseComplexityCount(); - if (b && (!state.option.inMoz(true))) { - warning("W118", state.tokens.next, "multiple catch blocks"); - } - doCatch(); - b = true; - } - - if (state.tokens.next.id === "finally") { - advance("finally"); - block(false); - return; - } - - if (!b) { - error("E021", state.tokens.next, "catch", state.tokens.next.value); - } - - return this; - }); - - blockstmt("while", function () { - var t = state.tokens.next; - funct["(breakage)"] += 1; - funct["(loopage)"] += 1; - increaseComplexityCount(); - advance("("); - nonadjacent(this, t); - nospace(); - checkCondAssignment(expression(0)); - advance(")", t); - nospace(state.tokens.prev, state.tokens.curr); - block(true, true); - funct["(breakage)"] -= 1; - funct["(loopage)"] -= 1; - return this; - }).labelled = true; - - blockstmt("with", function () { - var t = state.tokens.next; - if (state.directive["use strict"]) { - error("E010", state.tokens.curr); - } else if (!state.option.withstmt) { - warning("W085", state.tokens.curr); - } - - advance("("); - nonadjacent(this, t); - nospace(); - expression(0); - advance(")", t); - nospace(state.tokens.prev, state.tokens.curr); - block(true, true); - - return this; - }); - - blockstmt("switch", function () { - var t = state.tokens.next, - g = false; - funct["(breakage)"] += 1; - advance("("); - nonadjacent(this, t); - nospace(); - checkCondAssignment(expression(0)); - advance(")", t); - nospace(state.tokens.prev, state.tokens.curr); - nonadjacent(state.tokens.curr, state.tokens.next); - t = state.tokens.next; - advance("{"); - nonadjacent(state.tokens.curr, state.tokens.next); - indent += state.option.indent; - this.cases = []; - - for (;;) { - switch (state.tokens.next.id) { - case "case": - switch (funct["(verb)"]) { - case "yield": - case "break": - case "case": - case "continue": - case "return": - case "switch": - case "throw": - break; - default: - // You can tell JSHint that you don't use break intentionally by - // adding a comment /* falls through */ on a line just before - // the next `case`. - if (!reg.fallsThrough.test(state.lines[state.tokens.next.line - 2])) { - warning("W086", state.tokens.curr, "case"); - } - } - indentation(-state.option.indent); - advance("case"); - this.cases.push(expression(20)); - increaseComplexityCount(); - g = true; - advance(":"); - funct["(verb)"] = "case"; - break; - case "default": - switch (funct["(verb)"]) { - case "yield": - case "break": - case "continue": - case "return": - case "throw": - break; - default: - // Do not display a warning if 'default' is the first statement or if - // there is a special /* falls through */ comment. - if (this.cases.length) { - if (!reg.fallsThrough.test(state.lines[state.tokens.next.line - 2])) { - warning("W086", state.tokens.curr, "default"); - } - } - } - indentation(-state.option.indent); - advance("default"); - g = true; - advance(":"); - break; - case "}": - indent -= state.option.indent; - indentation(); - advance("}", t); - funct["(breakage)"] -= 1; - funct["(verb)"] = undefined; - return; - case "(end)": - error("E023", state.tokens.next, "}"); - return; - default: - if (g) { - switch (state.tokens.curr.id) { - case ",": - error("E040"); - return; - case ":": - g = false; - statements(); - break; - default: - error("E025", state.tokens.curr); - return; - } - } else { - if (state.tokens.curr.id === ":") { - advance(":"); - error("E024", state.tokens.curr, ":"); - statements(); - } else { - error("E021", state.tokens.next, "case", state.tokens.next.value); - return; - } - } - } - } - }).labelled = true; - - stmt("debugger", function () { - if (!state.option.debug) { - warning("W087"); - } - return this; - }).exps = true; - - (function () { - var x = stmt("do", function () { - funct["(breakage)"] += 1; - funct["(loopage)"] += 1; - increaseComplexityCount(); - - this.first = block(true, true); - advance("while"); - var t = state.tokens.next; - nonadjacent(state.tokens.curr, t); - advance("("); - nospace(); - checkCondAssignment(expression(0)); - advance(")", t); - nospace(state.tokens.prev, state.tokens.curr); - funct["(breakage)"] -= 1; - funct["(loopage)"] -= 1; - return this; - }); - x.labelled = true; - x.exps = true; - }()); - - blockstmt("for", function () { - var s, t = state.tokens.next; - var letscope = false; - var foreachtok = null; - - if (t.value === "each") { - foreachtok = t; - advance("each"); - if (!state.option.inMoz(true)) { - warning("W118", state.tokens.curr, "for each"); - } - } - - funct["(breakage)"] += 1; - funct["(loopage)"] += 1; - increaseComplexityCount(); - advance("("); - nonadjacent(this, t); - nospace(); - - // what kind of for(…) statement it is? for(…of…)? for(…in…)? for(…;…;…)? - var nextop; // contains the token of the "in" or "of" operator - var i = 0; - var inof = ["in", "of"]; - do { - nextop = peek(i); - ++i; - } while (!_.contains(inof, nextop.value) && nextop.value !== ";" && - nextop.type !== "(end)"); - - // if we're in a for (… in|of …) statement - if (_.contains(inof, nextop.value)) { - if (!state.option.inESNext() && nextop.value === "of") { - error("W104", nextop, "for of"); - } - if (state.tokens.next.id === "var") { - advance("var"); - state.syntax["var"].fud.call(state.syntax["var"].fud, true); - } else if (state.tokens.next.id === "let") { - advance("let"); - // create a new block scope - letscope = true; - funct["(blockscope)"].stack(); - state.syntax["let"].fud.call(state.syntax["let"].fud, true); - } else { - switch (funct[state.tokens.next.value]) { - case "unused": - funct[state.tokens.next.value] = "var"; - break; - case "var": - break; - default: - if (!funct["(blockscope)"].getlabel(state.tokens.next.value)) - warning("W088", state.tokens.next, state.tokens.next.value); - } - advance(); - } - advance(nextop.value); - expression(20); - advance(")", t); - s = block(true, true); - if (state.option.forin && s && (s.length > 1 || typeof s[0] !== "object" || - s[0].value !== "if")) { - warning("W089", this); - } - funct["(breakage)"] -= 1; - funct["(loopage)"] -= 1; - } else { - if (foreachtok) { - error("E045", foreachtok); - } - if (state.tokens.next.id !== ";") { - if (state.tokens.next.id === "var") { - advance("var"); - state.syntax["var"].fud.call(state.syntax["var"].fud); - } else if (state.tokens.next.id === "let") { - advance("let"); - // create a new block scope - letscope = true; - funct["(blockscope)"].stack(); - state.syntax["let"].fud.call(state.syntax["let"].fud); - } else { - for (;;) { - expression(0, "for"); - if (state.tokens.next.id !== ",") { - break; - } - comma(); - } - } - } - nolinebreak(state.tokens.curr); - advance(";"); - if (state.tokens.next.id !== ";") { - checkCondAssignment(expression(0)); - } - nolinebreak(state.tokens.curr); - advance(";"); - if (state.tokens.next.id === ";") { - error("E021", state.tokens.next, ")", ";"); - } - if (state.tokens.next.id !== ")") { - for (;;) { - expression(0, "for"); - if (state.tokens.next.id !== ",") { - break; - } - comma(); - } - } - advance(")", t); - nospace(state.tokens.prev, state.tokens.curr); - block(true, true); - funct["(breakage)"] -= 1; - funct["(loopage)"] -= 1; - - } - // unstack loop blockscope - if (letscope) { - funct["(blockscope)"].unstack(); - } - return this; - }).labelled = true; - - - stmt("break", function () { - var v = state.tokens.next.value; - - if (funct["(breakage)"] === 0) - warning("W052", state.tokens.next, this.value); - - if (!state.option.asi) - nolinebreak(this); - - if (state.tokens.next.id !== ";" && !state.tokens.next.reach) { - if (state.tokens.curr.line === state.tokens.next.line) { - if (funct[v] !== "label") { - warning("W090", state.tokens.next, v); - } else if (scope[v] !== funct) { - warning("W091", state.tokens.next, v); - } - this.first = state.tokens.next; - advance(); - } - } - reachable("break"); - return this; - }).exps = true; - - - stmt("continue", function () { - var v = state.tokens.next.value; - - if (funct["(breakage)"] === 0) - warning("W052", state.tokens.next, this.value); - - if (!state.option.asi) - nolinebreak(this); - - if (state.tokens.next.id !== ";" && !state.tokens.next.reach) { - if (state.tokens.curr.line === state.tokens.next.line) { - if (funct[v] !== "label") { - warning("W090", state.tokens.next, v); - } else if (scope[v] !== funct) { - warning("W091", state.tokens.next, v); - } - this.first = state.tokens.next; - advance(); - } - } else if (!funct["(loopage)"]) { - warning("W052", state.tokens.next, this.value); - } - reachable("continue"); - return this; - }).exps = true; - - - stmt("return", function () { - if (this.line === state.tokens.next.line) { - if (state.tokens.next.id === "(regexp)") - warning("W092"); - - if (state.tokens.next.id !== ";" && !state.tokens.next.reach) { - nonadjacent(state.tokens.curr, state.tokens.next); - this.first = expression(0); - - if (this.first && - this.first.type === "(punctuator)" && this.first.value === "=" && !state.option.boss) { - warningAt("W093", this.first.line, this.first.character); - } - } - } else { - if (state.tokens.next.type === "(punctuator)" && - ["[", "{", "+", "-"].indexOf(state.tokens.next.value) > -1) { - nolinebreak(this); // always warn (Line breaking error) - } - } - reachable("return"); - return this; - }).exps = true; - - (function (x) { - x.exps = true; - x.lbp = 25; - }(prefix("yield", function () { - var prev = state.tokens.prev; - if (state.option.inESNext(true) && !funct["(generator)"]) { - error("E046", state.tokens.curr, "yield"); - } else if (!state.option.inESNext()) { - warning("W104", state.tokens.curr, "yield"); - } - funct["(generator)"] = "yielded"; - if (this.line === state.tokens.next.line || !state.option.inMoz(true)) { - if (state.tokens.next.id === "(regexp)") - warning("W092"); - - if (state.tokens.next.id !== ";" && !state.tokens.next.reach && state.tokens.next.nud) { - nobreaknonadjacent(state.tokens.curr, state.tokens.next); - this.first = expression(10); - - if (this.first.type === "(punctuator)" && this.first.value === "=" && !state.option.boss) { - warningAt("W093", this.first.line, this.first.character); - } - } - - if (state.option.inMoz(true) && state.tokens.next.id !== ")" && - (prev.lbp > 30 || (!prev.assign && !isEndOfExpr()) || prev.id === "yield")) { - error("E050", this); - } - } else if (!state.option.asi) { - nolinebreak(this); // always warn (Line breaking error) - } - return this; - }))); - - - stmt("throw", function () { - nolinebreak(this); - nonadjacent(state.tokens.curr, state.tokens.next); - this.first = expression(20); - reachable("throw"); - return this; - }).exps = true; - - stmt("import", function () { - if (!state.option.inESNext()) { - warning("W119", state.tokens.curr, "import"); - } - - if (state.tokens.next.identifier) { - this.name = identifier(); - addlabel(this.name, "unused", state.tokens.curr); - } else { - advance("{"); - for (;;) { - var importName; - if (state.tokens.next.type === "default") { - importName = "default"; - advance("default"); - } else { - importName = identifier(); - } - if (state.tokens.next.value === "as") { - advance("as"); - importName = identifier(); - } - addlabel(importName, "unused", state.tokens.curr); - - if (state.tokens.next.value === ",") { - advance(","); - } else if (state.tokens.next.value === "}") { - advance("}"); - break; - } else { - error("E024", state.tokens.next, state.tokens.next.value); - break; - } - } - } - - advance("from"); - advance("(string)"); - return this; - }).exps = true; - - stmt("export", function () { - if (!state.option.inESNext()) { - warning("W119", state.tokens.curr, "export"); - } - - if (state.tokens.next.type === "default") { - advance("default"); - if (state.tokens.next.id === "function" || state.tokens.next.id === "class") { - this.block = true; - } - this.exportee = expression(10); - - return this; - } - - if (state.tokens.next.value === "{") { - advance("{"); - for (;;) { - identifier(); - - if (state.tokens.next.value === ",") { - advance(","); - } else if (state.tokens.next.value === "}") { - advance("}"); - break; - } else { - error("E024", state.tokens.next, state.tokens.next.value); - break; - } - } - return this; - } - - if (state.tokens.next.id === "var") { - advance("var"); - state.syntax["var"].fud.call(state.syntax["var"].fud); - } else if (state.tokens.next.id === "let") { - advance("let"); - state.syntax["let"].fud.call(state.syntax["let"].fud); - } else if (state.tokens.next.id === "const") { - advance("const"); - state.syntax["const"].fud.call(state.syntax["const"].fud); - } else if (state.tokens.next.id === "function") { - this.block = true; - advance("function"); - state.syntax["function"].fud(); - } else if (state.tokens.next.id === "class") { - this.block = true; - advance("class"); - state.syntax["class"].fud(); - } else { - error("E024", state.tokens.next, state.tokens.next.value); - } - - return this; - }).exps = true; - - // Future Reserved Words - - FutureReservedWord("abstract"); - FutureReservedWord("boolean"); - FutureReservedWord("byte"); - FutureReservedWord("char"); - FutureReservedWord("class", { es5: true, nud: classdef }); - FutureReservedWord("double"); - FutureReservedWord("enum", { es5: true }); - FutureReservedWord("export", { es5: true }); - FutureReservedWord("extends", { es5: true }); - FutureReservedWord("final"); - FutureReservedWord("float"); - FutureReservedWord("goto"); - FutureReservedWord("implements", { es5: true, strictOnly: true }); - FutureReservedWord("import", { es5: true }); - FutureReservedWord("int"); - FutureReservedWord("interface", { es5: true, strictOnly: true }); - FutureReservedWord("long"); - FutureReservedWord("native"); - FutureReservedWord("package", { es5: true, strictOnly: true }); - FutureReservedWord("private", { es5: true, strictOnly: true }); - FutureReservedWord("protected", { es5: true, strictOnly: true }); - FutureReservedWord("public", { es5: true, strictOnly: true }); - FutureReservedWord("short"); - FutureReservedWord("static", { es5: true, strictOnly: true }); - FutureReservedWord("super", { es5: true }); - FutureReservedWord("synchronized"); - FutureReservedWord("throws"); - FutureReservedWord("transient"); - FutureReservedWord("volatile"); - - // this function is used to determine wether a squarebracket or a curlybracket - // expression is a comprehension array, destructuring assignment or a json value. - - var lookupBlockType = function () { - var pn, pn1; - var i = 0; - var bracketStack = 0; - var ret = {}; - if (_.contains(["[", "{"], state.tokens.curr.value)) - bracketStack += 1; - if (_.contains(["[", "{"], state.tokens.next.value)) - bracketStack += 1; - if (_.contains(["]", "}"], state.tokens.next.value)) - bracketStack -= 1; - do { - pn = peek(i); - pn1 = peek(i + 1); - i = i + 1; - if (_.contains(["[", "{"], pn.value)) { - bracketStack += 1; - } else if (_.contains(["]", "}"], pn.value)) { - bracketStack -= 1; - } - if (pn.identifier && pn.value === "for" && bracketStack === 1) { - ret.isCompArray = true; - ret.notJson = true; - break; - } - if (_.contains(["}", "]"], pn.value) && pn1.value === "=") { - ret.isDestAssign = true; - ret.notJson = true; - break; - } - if (pn.value === ";") { - ret.isBlock = true; - ret.notJson = true; - } - } while (bracketStack > 0 && pn.id !== "(end)" && i < 15); - return ret; - }; - - // Check whether this function has been reached for a destructuring assign with undeclared values - function destructuringAssignOrJsonValue() { - // lookup for the assignment (esnext only) - // if it has semicolons, it is a block, so go parse it as a block - // or it's not a block, but there are assignments, check for undeclared variables - - var block = lookupBlockType(); - if (block.notJson) { - if (!state.option.inESNext() && block.isDestAssign) { - warning("W104", state.tokens.curr, "destructuring assignment"); - } - statements(); - // otherwise parse json value - } else { - state.option.laxbreak = true; - state.jsonMode = true; - jsonValue(); - } - } - - // array comprehension parsing function - // parses and defines the three states of the list comprehension in order - // to avoid defining global variables, but keeping them to the list comprehension scope - // only. The order of the states are as follows: - // * "use" which will be the returned iterative part of the list comprehension - // * "define" which will define the variables local to the list comprehension - // * "filter" which will help filter out values - - var arrayComprehension = function () { - var CompArray = function () { - this.mode = "use"; - this.variables = []; - }; - var _carrays = []; - var _current; - function declare(v) { - var l = _current.variables.filter(function (elt) { - // if it has, change its undef state - if (elt.value === v) { - elt.undef = false; - return v; - } - }).length; - return l !== 0; - } - function use(v) { - var l = _current.variables.filter(function (elt) { - // and if it has been defined - if (elt.value === v && !elt.undef) { - if (elt.unused === true) { - elt.unused = false; - } - return v; - } - }).length; - // otherwise we warn about it - return (l === 0); - } - return {stack: function () { - _current = new CompArray(); - _carrays.push(_current); - }, - unstack: function () { - _current.variables.filter(function (v) { - if (v.unused) - warning("W098", v.token, v.value); - if (v.undef) - isundef(v.funct, "W117", v.token, v.value); - }); - _carrays.splice(_carrays[_carrays.length - 1], 1); - _current = _carrays[_carrays.length - 1]; - }, - setState: function (s) { - if (_.contains(["use", "define", "filter"], s)) - _current.mode = s; - }, - check: function (v) { - // When we are in "use" state of the list comp, we enqueue that var - if (_current && _current.mode === "use") { - _current.variables.push({funct: funct, - token: state.tokens.curr, - value: v, - undef: true, - unused: false}); - return true; - // When we are in "define" state of the list comp, - } else if (_current && _current.mode === "define") { - // check if the variable has been used previously - if (!declare(v)) { - _current.variables.push({funct: funct, - token: state.tokens.curr, - value: v, - undef: false, - unused: true}); - } - return true; - // When we are in "filter" state, - } else if (_current && _current.mode === "filter") { - // we check whether current variable has been declared - if (use(v)) { - // if not we warn about it - isundef(funct, "W117", state.tokens.curr, v); - } - return true; - } - return false; - } - }; - }; - - - // Parse JSON - - function jsonValue() { - - function jsonObject() { - var o = {}, t = state.tokens.next; - advance("{"); - if (state.tokens.next.id !== "}") { - for (;;) { - if (state.tokens.next.id === "(end)") { - error("E026", state.tokens.next, t.line); - } else if (state.tokens.next.id === "}") { - warning("W094", state.tokens.curr); - break; - } else if (state.tokens.next.id === ",") { - error("E028", state.tokens.next); - } else if (state.tokens.next.id !== "(string)") { - warning("W095", state.tokens.next, state.tokens.next.value); - } - if (o[state.tokens.next.value] === true) { - warning("W075", state.tokens.next, state.tokens.next.value); - } else if ((state.tokens.next.value === "__proto__" && - !state.option.proto) || (state.tokens.next.value === "__iterator__" && - !state.option.iterator)) { - warning("W096", state.tokens.next, state.tokens.next.value); - } else { - o[state.tokens.next.value] = true; - } - advance(); - advance(":"); - jsonValue(); - if (state.tokens.next.id !== ",") { - break; - } - advance(","); - } - } - advance("}"); - } - - function jsonArray() { - var t = state.tokens.next; - advance("["); - if (state.tokens.next.id !== "]") { - for (;;) { - if (state.tokens.next.id === "(end)") { - error("E027", state.tokens.next, t.line); - } else if (state.tokens.next.id === "]") { - warning("W094", state.tokens.curr); - break; - } else if (state.tokens.next.id === ",") { - error("E028", state.tokens.next); - } - jsonValue(); - if (state.tokens.next.id !== ",") { - break; - } - advance(","); - } - } - advance("]"); - } - - switch (state.tokens.next.id) { - case "{": - jsonObject(); - break; - case "[": - jsonArray(); - break; - case "true": - case "false": - case "null": - case "(number)": - case "(string)": - advance(); - break; - case "-": - advance("-"); - if (state.tokens.curr.character !== state.tokens.next.from) { - warning("W011", state.tokens.curr); - } - adjacent(state.tokens.curr, state.tokens.next); - advance("(number)"); - break; - default: - error("E003", state.tokens.next); - } - } - - var blockScope = function () { - var _current = {}; - var _variables = [_current]; - - function _checkBlockLabels() { - for (var t in _current) { - if (_current[t]["(type)"] === "unused") { - if (state.option.unused) { - var tkn = _current[t]["(token)"]; - var line = tkn.line; - var chr = tkn.character; - warningAt("W098", line, chr, t); - } - } - } - } - - return { - stack: function () { - _current = {}; - _variables.push(_current); - }, - - unstack: function () { - _checkBlockLabels(); - _variables.splice(_variables.length - 1, 1); - _current = _.last(_variables); - }, - - getlabel: function (l) { - for (var i = _variables.length - 1 ; i >= 0; --i) { - if (_.has(_variables[i], l)) { - return _variables[i]; - } - } - }, - - current: { - has: function (t) { - return _.has(_current, t); - }, - add: function (t, type, tok) { - _current[t] = { "(type)" : type, - "(token)": tok }; - } - } - }; - }; - - // The actual JSHINT function itself. - var itself = function (s, o, g) { - var i, k, x; - var optionKeys; - var newOptionObj = {}; - var newIgnoredObj = {}; - - state.reset(); - - if (o && o.scope) { - JSHINT.scope = o.scope; - } else { - JSHINT.errors = []; - JSHINT.undefs = []; - JSHINT.internals = []; - JSHINT.blacklist = {}; - JSHINT.scope = "(main)"; - } - - predefined = Object.create(null); - combine(predefined, vars.ecmaIdentifiers); - combine(predefined, vars.reservedVars); - - combine(predefined, g || {}); - - declared = Object.create(null); - exported = Object.create(null); - - function each(obj, cb) { - if (!obj) - return; - - if (!Array.isArray(obj) && typeof obj === "object") - obj = Object.keys(obj); - - obj.forEach(cb); - } - - if (o) { - each(o.predef || null, function (item) { - var slice, prop; - - if (item[0] === "-") { - slice = item.slice(1); - JSHINT.blacklist[slice] = slice; - } else { - prop = Object.getOwnPropertyDescriptor(o.predef, item); - predefined[item] = prop ? prop.value : false; - } - }); - - each(o.exported || null, function (item) { - exported[item] = true; - }); - - delete o.predef; - delete o.exported; - - optionKeys = Object.keys(o); - for (x = 0; x < optionKeys.length; x++) { - if (/^-W\d{3}$/g.test(optionKeys[x])) { - newIgnoredObj[optionKeys[x].slice(1)] = true; - } else { - newOptionObj[optionKeys[x]] = o[optionKeys[x]]; - - if (optionKeys[x] === "newcap" && o[optionKeys[x]] === false) - newOptionObj["(explicitNewcap)"] = true; - - if (optionKeys[x] === "indent") - newOptionObj["(explicitIndent)"] = o[optionKeys[x]] === false ? false : true; - } - } - } - - state.option = newOptionObj; - state.ignored = newIgnoredObj; - - state.option.indent = state.option.indent || 4; - state.option.maxerr = state.option.maxerr || 50; - - indent = 1; - global = Object.create(predefined); - scope = global; - funct = { - "(global)": true, - "(name)": "(global)", - "(scope)": scope, - "(breakage)": 0, - "(loopage)": 0, - "(tokens)": {}, - "(metrics)": createMetrics(state.tokens.next), - "(blockscope)": blockScope(), - "(comparray)": arrayComprehension() - }; - functions = [funct]; - urls = []; - stack = null; - member = {}; - membersOnly = null; - implied = {}; - inblock = false; - lookahead = []; - warnings = 0; - unuseds = []; - - if (!isString(s) && !Array.isArray(s)) { - errorAt("E004", 0); - return false; - } - - api = { - get isJSON() { - return state.jsonMode; - }, - - getOption: function (name) { - return state.option[name] || null; - }, - - getCache: function (name) { - return state.cache[name]; - }, - - setCache: function (name, value) { - state.cache[name] = value; - }, - - warn: function (code, data) { - warningAt.apply(null, [ code, data.line, data.char ].concat(data.data)); - }, - - on: function (names, listener) { - names.split(" ").forEach(function (name) { - emitter.on(name, listener); - }.bind(this)); - } - }; - - emitter.removeAllListeners(); - (extraModules || []).forEach(function (func) { - func(api); - }); - - state.tokens.prev = state.tokens.curr = state.tokens.next = state.syntax["(begin)"]; - - lex = new Lexer(s); - - lex.on("warning", function (ev) { - warningAt.apply(null, [ ev.code, ev.line, ev.character].concat(ev.data)); - }); - - lex.on("error", function (ev) { - errorAt.apply(null, [ ev.code, ev.line, ev.character ].concat(ev.data)); - }); - - lex.on("fatal", function (ev) { - quit("E041", ev.line, ev.from); - }); - - lex.on("Identifier", function (ev) { - emitter.emit("Identifier", ev); - }); - - lex.on("String", function (ev) { - emitter.emit("String", ev); - }); - - lex.on("Number", function (ev) { - emitter.emit("Number", ev); - }); - - lex.start(); - - // Check options - for (var name in o) { - if (_.has(o, name)) { - checkOption(name, state.tokens.curr); - } - } - - assume(); - - // combine the passed globals after we've assumed all our options - combine(predefined, g || {}); - - //reset values - comma.first = true; - - try { - advance(); - switch (state.tokens.next.id) { - case "{": - case "[": - destructuringAssignOrJsonValue(); - break; - default: - directives(); - - if (state.directive["use strict"]) { - if (!state.option.globalstrict && !state.option.node) { - warning("W097", state.tokens.prev); - } - } - - statements(); - } - advance((state.tokens.next && state.tokens.next.value !== ".") ? "(end)" : undefined); - funct["(blockscope)"].unstack(); - - var markDefined = function (name, context) { - do { - if (typeof context[name] === "string") { - // JSHINT marks unused variables as 'unused' and - // unused function declaration as 'unction'. This - // code changes such instances back 'var' and - // 'closure' so that the code in JSHINT.data() - // doesn't think they're unused. - - if (context[name] === "unused") - context[name] = "var"; - else if (context[name] === "unction") - context[name] = "closure"; - - return true; - } - - context = context["(context)"]; - } while (context); - - return false; - }; - - var clearImplied = function (name, line) { - if (!implied[name]) - return; - - var newImplied = []; - for (var i = 0; i < implied[name].length; i += 1) { - if (implied[name][i] !== line) - newImplied.push(implied[name][i]); - } - - if (newImplied.length === 0) - delete implied[name]; - else - implied[name] = newImplied; - }; - - var warnUnused = function (name, tkn, type, unused_opt) { - var line = tkn.line; - var chr = tkn.character; - - if (unused_opt === undefined) { - unused_opt = state.option.unused; - } - - if (unused_opt === true) { - unused_opt = "last-param"; - } - - var warnable_types = { - "vars": ["var"], - "last-param": ["var", "param"], - "strict": ["var", "param", "last-param"] - }; - - if (unused_opt) { - if (warnable_types[unused_opt] && warnable_types[unused_opt].indexOf(type) !== -1) { - warningAt("W098", line, chr, name); - } - } - - unuseds.push({ - name: name, - line: line, - character: chr - }); - }; - - var checkUnused = function (func, key) { - var type = func[key]; - var tkn = func["(tokens)"][key]; - - if (key.charAt(0) === "(") - return; - - if (type !== "unused" && type !== "unction") - return; - - // Params are checked separately from other variables. - if (func["(params)"] && func["(params)"].indexOf(key) !== -1) - return; - - // Variable is in global scope and defined as exported. - if (func["(global)"] && _.has(exported, key)) { - return; - } - - warnUnused(key, tkn, "var"); - }; - - // Check queued 'x is not defined' instances to see if they're still undefined. - for (i = 0; i < JSHINT.undefs.length; i += 1) { - k = JSHINT.undefs[i].slice(0); - - if (markDefined(k[2].value, k[0])) { - clearImplied(k[2].value, k[2].line); - } else if (state.option.undef) { - warning.apply(warning, k.slice(1)); - } - } - - functions.forEach(function (func) { - if (func["(unusedOption)"] === false) { - return; - } - - for (var key in func) { - if (_.has(func, key)) { - checkUnused(func, key); - } - } - - if (!func["(params)"]) - return; - - var params = func["(params)"].slice(); - var param = params.pop(); - var type, unused_opt; - - while (param) { - type = func[param]; - unused_opt = func["(unusedOption)"] || state.option.unused; - unused_opt = unused_opt === true ? "last-param" : unused_opt; - - // 'undefined' is a special case for (function (window, undefined) { ... })(); - // patterns. - - if (param === "undefined") - return; - - if (type === "unused" || type === "unction") { - warnUnused(param, func["(tokens)"][param], "param", func["(unusedOption)"]); - } else if (unused_opt === "last-param") { - return; - } - - param = params.pop(); - } - }); - - for (var key in declared) { - if (_.has(declared, key) && !_.has(global, key)) { - warnUnused(key, declared[key], "var"); - } - } - - } catch (err) { - if (err && err.name === "JSHintError") { - var nt = state.tokens.next || {}; - JSHINT.errors.push({ - scope : "(main)", - raw : err.raw, - code : err.code, - reason : err.message, - line : err.line || nt.line, - character : err.character || nt.from - }, null); - } else { - throw err; - } - } - - // Loop over the listed "internals", and check them as well. - - if (JSHINT.scope === "(main)") { - o = o || {}; - - for (i = 0; i < JSHINT.internals.length; i += 1) { - k = JSHINT.internals[i]; - o.scope = k.elem; - itself(k.value, o, g); - } - } - - return JSHINT.errors.length === 0; - }; - - // Modules. - itself.addModule = function (func) { - extraModules.push(func); - }; - - itself.addModule(style.register); - - // Data summary. - itself.data = function () { - var data = { - functions: [], - options: state.option - }; - var implieds = []; - var members = []; - var fu, f, i, j, n, globals; - - if (itself.errors.length) { - data.errors = itself.errors; - } - - if (state.jsonMode) { - data.json = true; - } - - for (n in implied) { - if (_.has(implied, n)) { - implieds.push({ - name: n, - line: implied[n] - }); - } - } - - if (implieds.length > 0) { - data.implieds = implieds; - } - - if (urls.length > 0) { - data.urls = urls; - } - - globals = Object.keys(scope); - if (globals.length > 0) { - data.globals = globals; - } - - for (i = 1; i < functions.length; i += 1) { - f = functions[i]; - fu = {}; - - for (j = 0; j < functionicity.length; j += 1) { - fu[functionicity[j]] = []; - } - - for (j = 0; j < functionicity.length; j += 1) { - if (fu[functionicity[j]].length === 0) { - delete fu[functionicity[j]]; - } - } - - fu.name = f["(name)"]; - fu.param = f["(params)"]; - fu.line = f["(line)"]; - fu.character = f["(character)"]; - fu.last = f["(last)"]; - fu.lastcharacter = f["(lastcharacter)"]; - data.functions.push(fu); - } - - if (unuseds.length > 0) { - data.unused = unuseds; - } - - members = []; - for (n in member) { - if (typeof member[n] === "number") { - data.member = member; - break; - } - } - - return data; - }; - - itself.jshint = itself; - - return itself; + "use strict"; + + var anonname, // The guessed name for anonymous functions. + api, // Extension API + + // These are operators that should not be used with the ! operator. + bang = { + "<" : true, + "<=" : true, + "==" : true, + "===": true, + "!==": true, + "!=" : true, + ">" : true, + ">=" : true, + "+" : true, + "-" : true, + "*" : true, + "/" : true, + "%" : true + }, + + // These are the JSHint boolean options. + boolOptions = { + asi : true, // if automatic semicolon insertion should be tolerated + bitwise : true, // if bitwise operators should not be allowed + boss : true, // if advanced usage of assignments should be allowed + browser : true, // if the standard browser globals should be predefined + camelcase : true, // if identifiers should be required in camel case + couch : true, // if CouchDB globals should be predefined + curly : true, // if curly braces around all blocks should be required + debug : true, // if debugger statements should be allowed + devel : true, // if logging globals should be predefined (console, alert, etc.) + dojo : true, // if Dojo Toolkit globals should be predefined + eqeqeq : true, // if === should be required + eqnull : true, // if == null comparisons should be tolerated + notypeof : true, // if should report typos in typeof comparisons + es3 : true, // if ES3 syntax should be allowed + es5 : true, // if ES5 syntax should be allowed (is now set per default) + esnext : true, // if es.next specific syntax should be allowed + moz : true, // if mozilla specific syntax should be allowed + evil : true, // if eval should be allowed + expr : true, // if ExpressionStatement should be allowed as Programs + forin : true, // if for in statements must filter + funcscope : true, // if only function scope should be used for scope tests + globalstrict: true, // if global "use strict"; should be allowed (also enables 'strict') + immed : true, // if immediate invocations must be wrapped in parens + iterator : true, // if the `__iterator__` property should be allowed + jquery : true, // if jQuery globals should be predefined + lastsemic : true, // if semicolons may be ommitted for the trailing + // statements inside of a one-line blocks. + laxbreak : true, // if line breaks should not be checked + laxcomma : true, // if line breaks should not be checked around commas + loopfunc : true, // if functions should be allowed to be defined within + // loops + mootools : true, // if MooTools globals should be predefined + multistr : true, // allow multiline strings + freeze : true, // if modifying native object prototypes should be disallowed + newcap : true, // if constructor names must be capitalized + noarg : true, // if arguments.caller and arguments.callee should be + // disallowed + node : true, // if the Node.js environment globals should be + // predefined + noempty : true, // if empty blocks should be disallowed + nonbsp : true, // if non-breaking spaces should be disallowed + nonew : true, // if using `new` for side-effects should be disallowed + nonstandard : true, // if non-standard (but widely adopted) globals should + // be predefined + phantom : true, // if PhantomJS symbols should be allowed + plusplus : true, // if increment/decrement should not be allowed + proto : true, // if the `__proto__` property should be allowed + prototypejs : true, // if Prototype and Scriptaculous globals should be + // predefined + rhino : true, // if the Rhino environment globals should be predefined + shelljs : true, // if ShellJS globals should be predefined + typed : true, // if typed array globals should be predefined + undef : true, // if variables should be declared before used + scripturl : true, // if script-targeted URLs should be tolerated + strict : true, // require the "use strict"; pragma + sub : true, // if all forms of subscript notation are tolerated + supernew : true, // if `new function () { ... };` and `new Object;` + // should be tolerated + validthis : true, // if 'this' inside a non-constructor function is valid. + // This is a function scoped option only. + withstmt : true, // if with statements should be allowed + worker : true, // if Web Worker script symbols should be allowed + wsh : true, // if the Windows Scripting Host environment globals + // should be predefined + yui : true, // YUI variables should be predefined + mocha : true, // Mocha functions should be predefined + noyield : true, // allow generators without a yield + + // Obsolete options + onecase : true, // if one case switch statements should be allowed + regexp : true, // if the . should not be allowed in regexp literals + regexdash : true // if unescaped first/last dash (-) inside brackets + // should be tolerated + }, + + // These are the JSHint options that can take any value + // (we use this object to detect invalid options) + valOptions = { + maxlen : false, + indent : false, + maxerr : false, + predef : false, // predef is deprecated and being replaced by globals + globals : false, + quotmark : false, // 'single'|'double'|true + scope : false, + maxstatements: false, // {int} max statements per function + maxdepth : false, // {int} max nested block depth per function + maxparams : false, // {int} max params per function + maxcomplexity: false, // {int} max cyclomatic complexity per function + shadow : false, // if variable shadowing should be tolerated + // "inner" - check for variables defined in the same scope only + // "outer" - check for variables defined in outer scopes as well + // false - same as inner + // true - allow variable shadowing + unused : true, // warn if variables are unused. Available options: + // false - don't check for unused variables + // true - "vars" + check last function param + // "vars" - skip checking unused function params + // "strict" - "vars" + check all function params + latedef : false, // warn if the variable is used before its definition + // false - don't emit any warnings + // true - warn if any variable is used before its definition + // "nofunc" - warn for any variable but function declarations + ignore : false // start/end ignoring lines of code, bypassing the lexer + // start - start ignoring lines, including the current line + // end - stop ignoring lines, starting on the next line + // line - ignore warnings / errors for just a single line + // (this option does not bypass the lexer) + }, + + // These are JSHint boolean options which are shared with JSLint + // where the definition in JSHint is opposite JSLint + invertedOptions = { + bitwise : true, + forin : true, + newcap : true, + plusplus: true, + regexp : true, + undef : true, + + // Inverted and renamed, use JSHint name here + eqeqeq : true, + strict : true + }, + + // These are JSHint boolean options which are shared with JSLint + // where the name has been changed but the effect is unchanged + renamedOptions = { + eqeq : "eqeqeq", + windows: "wsh", + sloppy : "strict" + }, + + removedOptions = { + nomen: true, + onevar: true, + passfail: true, + white: true, + gcl: true, + smarttabs: true, + trailing: true + }, + + declared, // Globals that were declared using /*global ... */ syntax. + exported, // Variables that are used outside of the current file. + + functionicity = [ + "closure", "exception", "global", "label", + "outer", "unused", "var" + ], + + funct, // The current function + functions, // All of the functions + + global, // The global scope + implied, // Implied globals + inblock, + indent, + lookahead, + lex, + member, + membersOnly, + noreach, + predefined, // Global variables defined by option + + scope, // The current scope + stack, + unuseds, + urls, + + extraModules = [], + emitter = new events.EventEmitter(); + + function checkOption(name, t) { + name = name.trim(); + + if (/^[+-]W\d{3}$/g.test(name)) { + return true; + } + + if (valOptions[name] === undefined && boolOptions[name] === undefined) { + if (t.type !== "jslint" && !removedOptions[name]) { + error("E001", t, name); + return false; + } + } + + return true; + } + + function isString(obj) { + return Object.prototype.toString.call(obj) === "[object String]"; + } + + function isIdentifier(tkn, value) { + if (!tkn) + return false; + + if (!tkn.identifier || tkn.value !== value) + return false; + + return true; + } + + function isReserved(token) { + if (!token.reserved) { + return false; + } + var meta = token.meta; + + if (meta && meta.isFutureReservedWord && state.option.inES5()) { + // ES3 FutureReservedWord in an ES5 environment. + if (!meta.es5) { + return false; + } + + // Some ES5 FutureReservedWord identifiers are active only + // within a strict mode environment. + if (meta.strictOnly) { + if (!state.option.strict && !state.directive["use strict"]) { + return false; + } + } + + if (token.isProperty) { + return false; + } + } + + return true; + } + + function supplant(str, data) { + return str.replace(/\{([^{}]*)\}/g, function (a, b) { + var r = data[b]; + return typeof r === "string" || typeof r === "number" ? r : a; + }); + } + + function combine(dest, src) { + Object.keys(src).forEach(function (name) { + if (JSHINT.blacklist.hasOwnProperty(name)) return; + dest[name] = src[name]; + }); + } + + function assume() { + if (state.option.esnext) { + combine(predefined, vars.newEcmaIdentifiers); + } + + if (state.option.couch) { + combine(predefined, vars.couch); + } + + if (state.option.rhino) { + combine(predefined, vars.rhino); + } + + if (state.option.shelljs) { + combine(predefined, vars.shelljs); + combine(predefined, vars.node); + } + if (state.option.typed) { + combine(predefined, vars.typed); + } + + if (state.option.phantom) { + combine(predefined, vars.phantom); + } + + if (state.option.prototypejs) { + combine(predefined, vars.prototypejs); + } + + if (state.option.node) { + combine(predefined, vars.node); + combine(predefined, vars.typed); + } + + if (state.option.devel) { + combine(predefined, vars.devel); + } + + if (state.option.dojo) { + combine(predefined, vars.dojo); + } + + if (state.option.browser) { + combine(predefined, vars.browser); + combine(predefined, vars.typed); + } + + if (state.option.nonstandard) { + combine(predefined, vars.nonstandard); + } + + if (state.option.jquery) { + combine(predefined, vars.jquery); + } + + if (state.option.mootools) { + combine(predefined, vars.mootools); + } + + if (state.option.worker) { + combine(predefined, vars.worker); + } + + if (state.option.wsh) { + combine(predefined, vars.wsh); + } + + if (state.option.globalstrict && state.option.strict !== false) { + state.option.strict = true; + } + + if (state.option.yui) { + combine(predefined, vars.yui); + } + + if (state.option.mocha) { + combine(predefined, vars.mocha); + } + + // Let's assume that chronologically ES3 < ES5 < ES6/ESNext < Moz + + state.option.inMoz = function (strict) { + return state.option.moz; + }; + + state.option.inESNext = function (strict) { + return state.option.moz || state.option.esnext; + }; + + state.option.inES5 = function (/* strict */) { + return !state.option.es3; + }; + + state.option.inES3 = function (strict) { + if (strict) { + return !state.option.moz && !state.option.esnext && state.option.es3; + } + return state.option.es3; + }; + } + + // Produce an error warning. + function quit(code, line, chr) { + var percentage = Math.floor((line / state.lines.length) * 100); + var message = messages.errors[code].desc; + + throw { + name: "JSHintError", + line: line, + character: chr, + message: message + " (" + percentage + "% scanned).", + raw: message, + code: code + }; + } + + function isundef(scope, code, token, a) { + return JSHINT.undefs.push([scope, code, token, a]); + } + + function removeIgnoredMessages() { + var ignored = state.ignoredLines; + + if (_.isEmpty(ignored)) return; + JSHINT.errors = _.reject(JSHINT.errors, function (err) { return ignored[err.line] }); + } + + function warning(code, t, a, b, c, d) { + var ch, l, w, msg; + + if (/^W\d{3}$/.test(code)) { + if (state.ignored[code]) + return; + + msg = messages.warnings[code]; + } else if (/E\d{3}/.test(code)) { + msg = messages.errors[code]; + } else if (/I\d{3}/.test(code)) { + msg = messages.info[code]; + } + + t = t || state.tokens.next; + if (t.id === "(end)") { // `~ + t = state.tokens.curr; + } + + l = t.line || 0; + ch = t.from || 0; + + w = { + id: "(error)", + raw: msg.desc, + code: msg.code, + evidence: state.lines[l - 1] || "", + line: l, + character: ch, + scope: JSHINT.scope, + a: a, + b: b, + c: c, + d: d + }; + + w.reason = supplant(msg.desc, w); + JSHINT.errors.push(w); + + removeIgnoredMessages(); + + if (JSHINT.errors.length >= state.option.maxerr) + quit("E043", l, ch); + + return w; + } + + function warningAt(m, l, ch, a, b, c, d) { + return warning(m, { + line: l, + from: ch + }, a, b, c, d); + } + + function error(m, t, a, b, c, d) { + warning(m, t, a, b, c, d); + } + + function errorAt(m, l, ch, a, b, c, d) { + return error(m, { + line: l, + from: ch + }, a, b, c, d); + } + + // Tracking of "internal" scripts, like eval containing a static string + function addInternalSrc(elem, src) { + var i; + i = { + id: "(internal)", + elem: elem, + value: src + }; + JSHINT.internals.push(i); + return i; + } + + // name: string + // opts: { type: string, token: token, islet: bool } + function addlabel(name, opts) { + opts = opts || {}; + + var type = opts.type; + var token = opts.token; + var islet = opts.islet; + + // Define label in the current function in the current scope. + if (type === "exception") { + if (_.has(funct["(context)"], name)) { + if (funct[name] !== true && !state.option.node) { + warning("W002", state.tokens.next, name); + } + } + } + + if (_.has(funct, name) && !funct["(global)"]) { + if (funct[name] === true) { + if (state.option.latedef) { + if ((state.option.latedef === true && _.contains([funct[name], type], "unction")) || + !_.contains([funct[name], type], "unction")) { + warning("W003", state.tokens.next, name); + } + } + } else { + if ((!state.option.shadow || _.contains([ "inner", "outer" ], state.option.shadow)) && + type !== "exception" || funct["(blockscope)"].getlabel(name)) { + warning("W004", state.tokens.next, name); + } + } + } + + if (funct["(context)"] && _.has(funct["(context)"], name) && type !== "function") { + if (state.option.shadow === "outer") { + warning("W123", state.tokens.next, name); + } + } + + // if the identifier is from a let, adds it only to the current blockscope + if (islet) { + funct["(blockscope)"].current.add(name, type, state.tokens.curr); + } else { + funct["(blockscope)"].shadow(name); + funct[name] = type; + + if (token) { + funct["(tokens)"][name] = token; + } + + setprop(funct, name, { unused: opts.unused || false }); + + if (funct["(global)"]) { + global[name] = funct; + if (_.has(implied, name)) { + if (state.option.latedef) { + if ((state.option.latedef === true && _.contains([funct[name], type], "unction")) || + !_.contains([funct[name], type], "unction")) { + warning("W003", state.tokens.next, name); + } + } + + delete implied[name]; + } + } else { + scope[name] = funct; + } + } + } + + function doOption() { + var nt = state.tokens.next; + var body = nt.body.match(/(-\s+)?[^\s,:]+(?:\s*:\s*(-\s+)?[^\s,]+)?/g); + var predef = {}; + + if (nt.type === "globals") { + body.forEach(function (g) { + g = g.split(":"); + var key = (g[0] || "").trim(); + var val = (g[1] || "").trim(); + + if (key.charAt(0) === "-") { + key = key.slice(1); + val = false; + + JSHINT.blacklist[key] = key; + delete predefined[key]; + } else { + predef[key] = (val === "true"); + } + }); + + combine(predefined, predef); + + for (var key in predef) { + if (_.has(predef, key)) { + declared[key] = nt; + } + } + } + + if (nt.type === "exported") { + body.forEach(function (e) { + exported[e] = true; + }); + } + + if (nt.type === "members") { + membersOnly = membersOnly || {}; + + body.forEach(function (m) { + var ch1 = m.charAt(0); + var ch2 = m.charAt(m.length - 1); + + if (ch1 === ch2 && (ch1 === "\"" || ch1 === "'")) { + m = m + .substr(1, m.length - 2) + .replace("\\\"", "\""); + } + + membersOnly[m] = false; + }); + } + + var numvals = [ + "maxstatements", + "maxparams", + "maxdepth", + "maxcomplexity", + "maxerr", + "maxlen", + "indent" + ]; + + if (nt.type === "jshint" || nt.type === "jslint") { + body.forEach(function (g) { + g = g.split(":"); + var key = (g[0] || "").trim(); + var val = (g[1] || "").trim(); + + if (!checkOption(key, nt)) { + return; + } + + if (numvals.indexOf(key) >= 0) { + // GH988 - numeric options can be disabled by setting them to `false` + if (val !== "false") { + val = +val; + + if (typeof val !== "number" || !isFinite(val) || val <= 0 || Math.floor(val) !== val) { + error("E032", nt, g[1].trim()); + return; + } + + state.option[key] = val; + } else { + state.option[key] = key === "indent" ? 4 : false; + } + + return; + } + + if (key === "validthis") { + // `validthis` is valid only within a function scope. + + if (funct["(global)"]) + return void error("E009"); + + if (val !== "true" && val !== "false") + return void error("E002", nt); + + state.option.validthis = (val === "true"); + return; + } + + if (key === "quotmark") { + switch (val) { + case "true": + case "false": + state.option.quotmark = (val === "true"); + break; + case "double": + case "single": + state.option.quotmark = val; + break; + default: + error("E002", nt); + } + return; + } + + if (key === "shadow") { + switch (val) { + case "true": + state.option.shadow = true; + break; + case "outer": + state.option.shadow = "outer"; + break; + case "false": + case "inner": + state.option.shadow = "inner"; + break; + default: + error("E002", nt); + } + return; + } + + if (key === "unused") { + switch (val) { + case "true": + state.option.unused = true; + break; + case "false": + state.option.unused = false; + break; + case "vars": + case "strict": + state.option.unused = val; + break; + default: + error("E002", nt); + } + return; + } + + if (key === "latedef") { + switch (val) { + case "true": + state.option.latedef = true; + break; + case "false": + state.option.latedef = false; + break; + case "nofunc": + state.option.latedef = "nofunc"; + break; + default: + error("E002", nt); + } + return; + } + + if (key === "ignore") { + switch (val) { + case "start": + state.ignoreLinterErrors = true; + break; + case "end": + state.ignoreLinterErrors = false; + break; + case "line": + state.ignoredLines[nt.line] = true; + removeIgnoredMessages(); + break; + default: + error("E002", nt); + } + return; + } + + var match = /^([+-])(W\d{3})$/g.exec(key); + if (match) { + // ignore for -W..., unignore for +W... + state.ignored[match[2]] = (match[1] === "-"); + return; + } + + var tn; + if (val === "true" || val === "false") { + if (nt.type === "jslint") { + tn = renamedOptions[key] || key; + state.option[tn] = (val === "true"); + + if (invertedOptions[tn] !== undefined) { + state.option[tn] = !state.option[tn]; + } + } else { + state.option[key] = (val === "true"); + } + + if (key === "newcap") { + state.option["(explicitNewcap)"] = true; + } + return; + } + + error("E002", nt); + }); + + assume(); + } + } + + // We need a peek function. If it has an argument, it peeks that much farther + // ahead. It is used to distinguish + // for ( var i in ... + // from + // for ( var i = ... + + function peek(p) { + var i = p || 0, j = 0, t; + + while (j <= i) { + t = lookahead[j]; + if (!t) { + t = lookahead[j] = lex.token(); + } + j += 1; + } + return t; + } + + // Produce the next token. It looks for programming errors. + + function advance(id, t) { + switch (state.tokens.curr.id) { + case "(number)": + if (state.tokens.next.id === ".") { + warning("W005", state.tokens.curr); + } + break; + case "-": + if (state.tokens.next.id === "-" || state.tokens.next.id === "--") { + warning("W006"); + } + break; + case "+": + if (state.tokens.next.id === "+" || state.tokens.next.id === "++") { + warning("W007"); + } + break; + } + + if (state.tokens.curr.type === "(string)" || state.tokens.curr.identifier) { + anonname = state.tokens.curr.value; + } + + if (id && state.tokens.next.id !== id) { + if (t) { + if (state.tokens.next.id === "(end)") { + error("E019", t, t.id); + } else { + error("E020", state.tokens.next, id, t.id, t.line, state.tokens.next.value); + } + } else if (state.tokens.next.type !== "(identifier)" || state.tokens.next.value !== id) { + warning("W116", state.tokens.next, id, state.tokens.next.value); + } + } + + state.tokens.prev = state.tokens.curr; + state.tokens.curr = state.tokens.next; + for (;;) { + state.tokens.next = lookahead.shift() || lex.token(); + + if (!state.tokens.next) { // No more tokens left, give up + quit("E041", state.tokens.curr.line); + } + + if (state.tokens.next.id === "(end)" || state.tokens.next.id === "(error)") { + return; + } + + if (state.tokens.next.check) { + state.tokens.next.check(); + } + + if (state.tokens.next.isSpecial) { + doOption(); + } else { + if (state.tokens.next.id !== "(endline)") { + break; + } + } + } + } + + function isInfix(token) { + return token.infix || (!token.identifier && !!token.led); + } + + function isEndOfExpr() { + var curr = state.tokens.curr; + var next = state.tokens.next; + if (next.id === ";" || next.id === "}" || next.id === ":") { + return true; + } + if (isInfix(next) === isInfix(curr) || (curr.id === "yield" && state.option.inMoz(true))) { + return curr.line !== next.line; + } + return false; + } + + // This is the heart of JSHINT, the Pratt parser. In addition to parsing, it + // is looking for ad hoc lint patterns. We add .fud to Pratt's model, which is + // like .nud except that it is only used on the first token of a statement. + // Having .fud makes it much easier to define statement-oriented languages like + // JavaScript. I retained Pratt's nomenclature. + + // .nud Null denotation + // .fud First null denotation + // .led Left denotation + // lbp Left binding power + // rbp Right binding power + + // They are elements of the parsing method called Top Down Operator Precedence. + + function expression(rbp, initial) { + var left, isArray = false, isObject = false, isLetExpr = false; + + // if current expression is a let expression + if (!initial && state.tokens.next.value === "let" && peek(0).value === "(") { + if (!state.option.inMoz(true)) { + warning("W118", state.tokens.next, "let expressions"); + } + isLetExpr = true; + // create a new block scope we use only for the current expression + funct["(blockscope)"].stack(); + advance("let"); + advance("("); + state.syntax["let"].fud.call(state.syntax["let"].fud, false); + advance(")"); + } + + if (state.tokens.next.id === "(end)") + error("E006", state.tokens.curr); + + if (state.option.asi && + (state.tokens.curr.id === "[" || + state.tokens.curr.id === "(" || + state.tokens.curr.id === "/") && + state.tokens.prev.line < state.tokens.curr.line) + warning("W014", state.tokens.curr, state.tokens.curr.id); + + advance(); + + if (initial) { + anonname = "anonymous"; + funct["(verb)"] = state.tokens.curr.value; + } + + if (initial === true && state.tokens.curr.fud) { + left = state.tokens.curr.fud(); + } else { + if (state.tokens.curr.nud) { + left = state.tokens.curr.nud(); + } else { + error("E030", state.tokens.curr, state.tokens.curr.id); + } + + while (rbp < state.tokens.next.lbp && !isEndOfExpr()) { + isArray = state.tokens.curr.value === "Array"; + isObject = state.tokens.curr.value === "Object"; + + // #527, new Foo.Array(), Foo.Array(), new Foo.Object(), Foo.Object() + // Line breaks in IfStatement heads exist to satisfy the checkJSHint + // "Line too long." error. + if (left && (left.value || (left.first && left.first.value))) { + // If the left.value is not "new", or the left.first.value is a "." + // then safely assume that this is not "new Array()" and possibly + // not "new Object()"... + if (left.value !== "new" || + (left.first && left.first.value && left.first.value === ".")) { + isArray = false; + // ...In the case of Object, if the left.value and state.tokens.curr.value + // are not equal, then safely assume that this not "new Object()" + if (left.value !== state.tokens.curr.value) { + isObject = false; + } + } + } + + advance(); + + if (isArray && state.tokens.curr.id === "(" && state.tokens.next.id === ")") { + warning("W009", state.tokens.curr); + } + + if (isObject && state.tokens.curr.id === "(" && state.tokens.next.id === ")") { + warning("W010", state.tokens.curr); + } + + if (left && state.tokens.curr.led) { + left = state.tokens.curr.led(left); + } else { + error("E033", state.tokens.curr, state.tokens.curr.id); + } + } + } + if (isLetExpr) { + funct["(blockscope)"].unstack(); + } + return left; + } + + + // Functions for conformance of style. + + function nobreaknonadjacent(left, right) { + left = left || state.tokens.curr; + right = right || state.tokens.next; + if (!state.option.laxbreak && left.line !== right.line) { + warning("W014", right, right.value); + } + } + + function nolinebreak(t) { + t = t || state.tokens.curr; + if (t.line !== state.tokens.next.line) { + warning("E022", t, t.value); + } + } + + function nobreakcomma(left, right) { + if (left.line !== right.line) { + if (!state.option.laxcomma) { + if (comma.first) { + warning("I001"); + comma.first = false; + } + warning("W014", left, right.value); + } + } + } + + function comma(opts) { + opts = opts || {}; + + if (!opts.peek) { + nobreakcomma(state.tokens.curr, state.tokens.next); + advance(","); + } else { + nobreakcomma(state.tokens.prev, state.tokens.curr); + } + + if (state.tokens.next.identifier && !(opts.property && state.option.inES5())) { + // Keywords that cannot follow a comma operator. + switch (state.tokens.next.value) { + case "break": + case "case": + case "catch": + case "continue": + case "default": + case "do": + case "else": + case "finally": + case "for": + case "if": + case "in": + case "instanceof": + case "return": + case "switch": + case "throw": + case "try": + case "var": + case "let": + case "while": + case "with": + error("E024", state.tokens.next, state.tokens.next.value); + return false; + } + } + + if (state.tokens.next.type === "(punctuator)") { + switch (state.tokens.next.value) { + case "}": + case "]": + case ",": + if (opts.allowTrailing) { + return true; + } + + /* falls through */ + case ")": + error("E024", state.tokens.next, state.tokens.next.value); + return false; + } + } + return true; + } + + // Functional constructors for making the symbols that will be inherited by + // tokens. + + function symbol(s, p) { + var x = state.syntax[s]; + if (!x || typeof x !== "object") { + state.syntax[s] = x = { + id: s, + lbp: p, + value: s + }; + } + return x; + } + + function delim(s) { + return symbol(s, 0); + } + + function stmt(s, f) { + var x = delim(s); + x.identifier = x.reserved = true; + x.fud = f; + return x; + } + + function blockstmt(s, f) { + var x = stmt(s, f); + x.block = true; + return x; + } + + function reserveName(x) { + var c = x.id.charAt(0); + if ((c >= "a" && c <= "z") || (c >= "A" && c <= "Z")) { + x.identifier = x.reserved = true; + } + return x; + } + + function prefix(s, f) { + var x = symbol(s, 150); + reserveName(x); + + x.nud = (typeof f === "function") ? f : function () { + this.right = expression(150); + this.arity = "unary"; + + if (this.id === "++" || this.id === "--") { + if (state.option.plusplus) { + warning("W016", this, this.id); + } else if (this.right && (!this.right.identifier || isReserved(this.right)) && + this.right.id !== "." && this.right.id !== "[") { + warning("W017", this); + } + } + + return this; + }; + + return x; + } + + function type(s, f) { + var x = delim(s); + x.type = s; + x.nud = f; + return x; + } + + function reserve(name, func) { + var x = type(name, func); + x.identifier = true; + x.reserved = true; + return x; + } + + function FutureReservedWord(name, meta) { + var x = type(name, (meta && meta.nud) || function () { + return this; + }); + + meta = meta || {}; + meta.isFutureReservedWord = true; + + x.value = name; + x.identifier = true; + x.reserved = true; + x.meta = meta; + + return x; + } + + function reservevar(s, v) { + return reserve(s, function () { + if (typeof v === "function") { + v(this); + } + return this; + }); + } + + function infix(s, f, p, w) { + var x = symbol(s, p); + reserveName(x); + x.infix = true; + x.led = function (left) { + if (!w) { + nobreaknonadjacent(state.tokens.prev, state.tokens.curr); + } + if (s === "in" && left.id === "!") { + warning("W018", left, "!"); + } + if (typeof f === "function") { + return f(left, this); + } else { + this.left = left; + this.right = expression(p); + return this; + } + }; + return x; + } + + + function application(s) { + var x = symbol(s, 42); + + x.led = function (left) { + if (!state.option.inESNext()) { + warning("W104", state.tokens.curr, "arrow function syntax (=>)"); + } + + nobreaknonadjacent(state.tokens.prev, state.tokens.curr); + + this.left = left; + this.right = doFunction(undefined, undefined, false, left); + return this; + }; + return x; + } + + function relation(s, f) { + var x = symbol(s, 100); + + x.led = function (left) { + nobreaknonadjacent(state.tokens.prev, state.tokens.curr); + var right = expression(100); + + if (isIdentifier(left, "NaN") || isIdentifier(right, "NaN")) { + warning("W019", this); + } else if (f) { + f.apply(this, [left, right]); + } + + if (!left || !right) { + quit("E041", state.tokens.curr.line); + } + + if (left.id === "!") { + warning("W018", left, "!"); + } + + if (right.id === "!") { + warning("W018", right, "!"); + } + + this.left = left; + this.right = right; + return this; + }; + return x; + } + + function isPoorRelation(node) { + return node && + ((node.type === "(number)" && +node.value === 0) || + (node.type === "(string)" && node.value === "") || + (node.type === "null" && !state.option.eqnull) || + node.type === "true" || + node.type === "false" || + node.type === "undefined"); + } + + // Checks whether the 'typeof' operator is used with the correct + // value. For docs on 'typeof' see: + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof + + function isTypoTypeof(left, right) { + if (state.option.notypeof) + return false; + + if (!left || !right) + return false; + + var values = [ + "undefined", "object", "boolean", "number", + "string", "function", "xml", "object", "unknown" + ]; + + if (right.type === "(identifier)" && right.value === "typeof" && left.type === "(string)") + return !_.contains(values, left.value); + + return false; + } + + function findNativePrototype(left) { + var natives = [ + "Array", "ArrayBuffer", "Boolean", "Collator", "DataView", "Date", + "DateTimeFormat", "Error", "EvalError", "Float32Array", "Float64Array", + "Function", "Infinity", "Intl", "Int16Array", "Int32Array", "Int8Array", + "Iterator", "Number", "NumberFormat", "Object", "RangeError", + "ReferenceError", "RegExp", "StopIteration", "String", "SyntaxError", + "TypeError", "Uint16Array", "Uint32Array", "Uint8Array", "Uint8ClampedArray", + "URIError" + ]; + + function walkPrototype(obj) { + if (typeof obj !== "object") return; + return obj.right === "prototype" ? obj : walkPrototype(obj.left); + } + + function walkNative(obj) { + while (!obj.identifier && typeof obj.left === "object") + obj = obj.left; + + if (obj.identifier && natives.indexOf(obj.value) >= 0) + return obj.value; + } + + var prototype = walkPrototype(left); + if (prototype) return walkNative(prototype); + } + + function assignop(s, f, p) { + var x = infix(s, typeof f === "function" ? f : function (left, that) { + that.left = left; + + if (left) { + if (state.option.freeze) { + var nativeObject = findNativePrototype(left); + if (nativeObject) + warning("W121", left, nativeObject); + } + + if (predefined[left.value] === false && + scope[left.value]["(global)"] === true) { + warning("W020", left); + } else if (left["function"]) { + warning("W021", left, left.value); + } + + if (funct[left.value] === "const") { + error("E013", left, left.value); + } + + if (left.id === ".") { + if (!left.left) { + warning("E031", that); + } else if (left.left.value === "arguments" && !state.directive["use strict"]) { + warning("E031", that); + } + + that.right = expression(10); + return that; + } else if (left.id === "[") { + if (state.tokens.curr.left.first) { + state.tokens.curr.left.first.forEach(function (t) { + if (t && funct[t.value] === "const") { + error("E013", t, t.value); + } + }); + } else if (!left.left) { + warning("E031", that); + } else if (left.left.value === "arguments" && !state.directive["use strict"]) { + warning("E031", that); + } + that.right = expression(10); + return that; + } else if (left.identifier && !isReserved(left)) { + if (funct[left.value] === "exception") { + warning("W022", left); + } + that.right = expression(10); + return that; + } + + if (left === state.syntax["function"]) { + warning("W023", state.tokens.curr); + } + } + + error("E031", that); + }, p); + + x.exps = true; + x.assign = true; + return x; + } + + + function bitwise(s, f, p) { + var x = symbol(s, p); + reserveName(x); + x.led = (typeof f === "function") ? f : function (left) { + if (state.option.bitwise) { + warning("W016", this, this.id); + } + this.left = left; + this.right = expression(p); + return this; + }; + return x; + } + + + function bitwiseassignop(s) { + return assignop(s, function (left, that) { + if (state.option.bitwise) { + warning("W016", that, that.id); + } + + if (left) { + if (left.id === "." || left.id === "[" || + (left.identifier && !isReserved(left))) { + expression(10); + return that; + } + if (left === state.syntax["function"]) { + warning("W023", state.tokens.curr); + } + return that; + } + error("E031", that); + }, 20); + } + + + function suffix(s) { + var x = symbol(s, 150); + + x.led = function (left) { + if (state.option.plusplus) { + warning("W016", this, this.id); + } else if ((!left.identifier || isReserved(left)) && left.id !== "." && left.id !== "[") { + warning("W017", this); + } + + this.left = left; + return this; + }; + return x; + } + + // fnparam means that this identifier is being defined as a function + // argument (see identifier()) + // prop means that this identifier is that of an object property + + function optionalidentifier(fnparam, prop) { + if (!state.tokens.next.identifier) { + return; + } + + advance(); + + var curr = state.tokens.curr; + var val = state.tokens.curr.value; + + if (!isReserved(curr)) { + return val; + } + + if (prop) { + if (state.option.inES5()) { + return val; + } + } + + if (fnparam && val === "undefined") { + return val; + } + + warning("W024", state.tokens.curr, state.tokens.curr.id); + return val; + } + + // fnparam means that this identifier is being defined as a function + // argument + // prop means that this identifier is that of an object property + function identifier(fnparam, prop) { + var i = optionalidentifier(fnparam, prop); + if (i) { + return i; + } + if (state.tokens.curr.id === "function" && state.tokens.next.id === "(") { + warning("W025"); + } else { + error("E030", state.tokens.next, state.tokens.next.value); + } + } + + + function reachable(s) { + var i = 0, t; + if (state.tokens.next.id !== ";" || noreach) { + return; + } + for (;;) { + do { + t = peek(i); + i += 1; + } while (t.id != "(end)" && t.id === "(comment)"); + + if (t.reach) { + return; + } + if (t.id !== "(endline)") { + if (t.id === "function") { + if (state.option.latedef === true) { + warning("W026", t); + } + break; + } + + warning("W027", t, t.value, s); + break; + } + } + } + + + function statement() { + var values; + var i = indent, r, s = scope, t = state.tokens.next; + + if (t.id === ";") { + advance(";"); + return; + } + + // Is this a labelled statement? + var res = isReserved(t); + + // We're being more tolerant here: if someone uses + // a FutureReservedWord as a label, we warn but proceed + // anyway. + + if (res && t.meta && t.meta.isFutureReservedWord && peek().id === ":") { + warning("W024", t, t.id); + res = false; + } + + // detect a destructuring assignment + if (_.has(["[", "{"], t.value)) { + if (lookupBlockType().isDestAssign) { + if (!state.option.inESNext()) { + warning("W104", state.tokens.curr, "destructuring expression"); + } + values = destructuringExpression(); + values.forEach(function (tok) { + isundef(funct, "W117", tok.token, tok.id); + }); + advance("="); + destructuringExpressionMatch(values, expression(10, true)); + advance(";"); + return; + } + } + if (t.identifier && !res && peek().id === ":") { + advance(); + advance(":"); + scope = Object.create(s); + addlabel(t.value, { type: "label" }); + + if (!state.tokens.next.labelled && state.tokens.next.value !== "{") { + warning("W028", state.tokens.next, t.value, state.tokens.next.value); + } + + state.tokens.next.label = t.value; + t = state.tokens.next; + } + + // Is it a lonely block? + + if (t.id === "{") { + // Is it a switch case block? + // + // switch (foo) { + // case bar: { <= here. + // ... + // } + // } + var iscase = (funct["(verb)"] === "case" && state.tokens.curr.value === ":"); + block(true, true, false, false, iscase); + return; + } + + // Parse the statement. + + r = expression(0, true); + + if (r && (!r.identifier || r.value !== "function") && (r.type !== "(punctuator)")) { + if (!state.directive["use strict"] && + state.option.globalstrict && + state.option.strict) { + warning("E007"); + } + } + + // Look for the final semicolon. + + if (!t.block) { + if (!state.option.expr && (!r || !r.exps)) { + warning("W030", state.tokens.curr); + } else if (state.option.nonew && r && r.left && r.id === "(" && r.left.id === "new") { + warning("W031", t); + } + + if (state.tokens.next.id !== ";") { + if (!state.option.asi) { + // If this is the last statement in a block that ends on + // the same line *and* option lastsemic is on, ignore the warning. + // Otherwise, complain about missing semicolon. + if (!state.option.lastsemic || state.tokens.next.id !== "}" || + state.tokens.next.line !== state.tokens.curr.line) { + warningAt("W033", state.tokens.curr.line, state.tokens.curr.character); + } + } + } else { + advance(";"); + } + } + + // Restore the indentation. + + indent = i; + scope = s; + return r; + } + + + function statements(startLine) { + var a = [], p; + + while (!state.tokens.next.reach && state.tokens.next.id !== "(end)") { + if (state.tokens.next.id === ";") { + p = peek(); + + if (!p || (p.id !== "(" && p.id !== "[")) { + warning("W032"); + } + + advance(";"); + } else { + a.push(statement(startLine === state.tokens.next.line)); + } + } + return a; + } + + + /* + * read all directives + * recognizes a simple form of asi, but always + * warns, if it is used + */ + function directives() { + var i, p, pn; + + for (;;) { + if (state.tokens.next.id === "(string)") { + p = peek(0); + if (p.id === "(endline)") { + i = 1; + do { + pn = peek(i); + i = i + 1; + } while (pn.id === "(endline)"); + + if (pn.id !== ";") { + if (pn.id !== "(string)" && pn.id !== "(number)" && + pn.id !== "(regexp)" && pn.identifier !== true && + pn.id !== "}") { + break; + } + warning("W033", state.tokens.next); + } else { + p = pn; + } + } else if (p.id === "}") { + // Directive with no other statements, warn about missing semicolon + warning("W033", p); + } else if (p.id !== ";") { + break; + } + + advance(); + if (state.directive[state.tokens.curr.value]) { + warning("W034", state.tokens.curr, state.tokens.curr.value); + } + + if (state.tokens.curr.value === "use strict") { + if (!state.option["(explicitNewcap)"]) + state.option.newcap = true; + state.option.undef = true; + } + + // there's no directive negation, so always set to true + state.directive[state.tokens.curr.value] = true; + + if (p.id === ";") { + advance(";"); + } + continue; + } + break; + } + } + + + /* + * Parses a single block. A block is a sequence of statements wrapped in + * braces. + * + * ordinary - true for everything but function bodies and try blocks. + * stmt - true if block can be a single statement (e.g. in if/for/while). + * isfunc - true if block is a function body + * isfatarrow - true if its a body of a fat arrow function + * iscase - true if block is a switch case block + */ + function block(ordinary, stmt, isfunc, isfatarrow, iscase) { + var a, + b = inblock, + old_indent = indent, + m, + s = scope, + t, + line, + d; + + inblock = ordinary; + + if (!ordinary || !state.option.funcscope) + scope = Object.create(scope); + + t = state.tokens.next; + + var metrics = funct["(metrics)"]; + metrics.nestedBlockDepth += 1; + metrics.verifyMaxNestedBlockDepthPerFunction(); + + if (state.tokens.next.id === "{") { + advance("{"); + + // create a new block scope + funct["(blockscope)"].stack(); + + line = state.tokens.curr.line; + if (state.tokens.next.id !== "}") { + indent += state.option.indent; + while (!ordinary && state.tokens.next.from > indent) { + indent += state.option.indent; + } + + if (isfunc) { + m = {}; + for (d in state.directive) { + if (_.has(state.directive, d)) { + m[d] = state.directive[d]; + } + } + directives(); + + if (state.option.strict && funct["(context)"]["(global)"]) { + if (!m["use strict"] && !state.directive["use strict"]) { + warning("E007"); + } + } + } + + a = statements(line); + + metrics.statementCount += a.length; + + if (isfunc) { + state.directive = m; + } + + indent -= state.option.indent; + } + + advance("}", t); + + funct["(blockscope)"].unstack(); + + indent = old_indent; + } else if (!ordinary) { + if (isfunc) { + m = {}; + if (stmt && !isfatarrow && !state.option.inMoz(true)) { + error("W118", state.tokens.curr, "function closure expressions"); + } + + if (!stmt) { + for (d in state.directive) { + if (_.has(state.directive, d)) { + m[d] = state.directive[d]; + } + } + } + expression(10); + + if (state.option.strict && funct["(context)"]["(global)"]) { + if (!m["use strict"] && !state.directive["use strict"]) { + warning("E007"); + } + } + } else { + error("E021", state.tokens.next, "{", state.tokens.next.value); + } + } else { + + // check to avoid let declaration not within a block + funct["(nolet)"] = true; + + if (!stmt || state.option.curly) { + warning("W116", state.tokens.next, "{", state.tokens.next.value); + } + + noreach = true; + indent += state.option.indent; + // test indentation only if statement is in new line + a = [statement()]; + indent -= state.option.indent; + noreach = false; + + delete funct["(nolet)"]; + } + + // Don't clear and let it propagate out if it is "break", "return" or similar in switch case + switch (funct["(verb)"]) { + case "break": + case "continue": + case "return": + case "throw": + if (iscase) { + break; + } + + /* falls through */ + default: + funct["(verb)"] = null; + } + + if (!ordinary || !state.option.funcscope) scope = s; + inblock = b; + if (ordinary && state.option.noempty && (!a || a.length === 0)) { + warning("W035"); + } + metrics.nestedBlockDepth -= 1; + return a; + } + + + function countMember(m) { + if (membersOnly && typeof membersOnly[m] !== "boolean") { + warning("W036", state.tokens.curr, m); + } + if (typeof member[m] === "number") { + member[m] += 1; + } else { + member[m] = 1; + } + } + + + function note_implied(tkn) { + var name = tkn.value; + var desc = Object.getOwnPropertyDescriptor(implied, name); + + if (!desc) + implied[name] = [tkn.line]; + else + desc.value.push(tkn.line); + } + + + // Build the syntax table by declaring the syntactic elements of the language. + + type("(number)", function () { + return this; + }); + + type("(string)", function () { + return this; + }); + + type("(template)", function () { + return this; + }); + + state.syntax["(identifier)"] = { + type: "(identifier)", + lbp: 0, + identifier: true, + + nud: function () { + var v = this.value; + var s = scope[v]; + var f; + var block; + + if (typeof s === "function") { + // Protection against accidental inheritance. + s = undefined; + } else if (!funct["(blockscope)"].current.has(v) && typeof s === "boolean") { + f = funct; + funct = functions[0]; + addlabel(v, { type: "var" }); + s = funct; + funct = f; + } + + block = funct["(blockscope)"].getlabel(v); + + // The name is in scope and defined in the current function. + if (funct === s || block) { + // Change 'unused' to 'var', and reject labels. + // the name is in a block scope. + switch (block ? block[v]["(type)"] : funct[v]) { + case "unused": + if (block) block[v]["(type)"] = "var"; + else funct[v] = "var"; + break; + case "unction": + if (block) block[v]["(type)"] = "function"; + else funct[v] = "function"; + this["function"] = true; + break; + case "const": + setprop(funct, v, { unused: false }); + break; + case "function": + this["function"] = true; + break; + case "label": + warning("W037", state.tokens.curr, v); + break; + } + } else if (funct["(global)"]) { + // The name is not defined in the function. If we are in the global + // scope, then we have an undefined variable. + // + // Operators typeof and delete do not raise runtime errors even if + // the base object of a reference is null so no need to display warning + // if we're inside of typeof or delete. + + if (typeof predefined[v] !== "boolean") { + // Attempting to subscript a null reference will throw an + // error, even within the typeof and delete operators + if (!(anonname === "typeof" || anonname === "delete") || + (state.tokens.next && (state.tokens.next.value === "." || + state.tokens.next.value === "["))) { + + // if we're in a list comprehension, variables are declared + // locally and used before being defined. So we check + // the presence of the given variable in the comp array + // before declaring it undefined. + + if (!funct["(comparray)"].check(v)) { + isundef(funct, "W117", state.tokens.curr, v); + } + } + } + + note_implied(state.tokens.curr); + } else { + // If the name is already defined in the current + // function, but not as outer, then there is a scope error. + + switch (funct[v]) { + case "closure": + case "function": + case "var": + case "unused": + warning("W038", state.tokens.curr, v); + break; + case "label": + warning("W037", state.tokens.curr, v); + break; + case "outer": + case "global": + break; + default: + // If the name is defined in an outer function, make an outer entry, + // and if it was unused, make it var. + if (s === true) { + funct[v] = true; + } else if (s === null) { + warning("W039", state.tokens.curr, v); + note_implied(state.tokens.curr); + } else if (typeof s !== "object") { + // Operators typeof and delete do not raise runtime errors even + // if the base object of a reference is null so no need to + // + // display warning if we're inside of typeof or delete. + // Attempting to subscript a null reference will throw an + // error, even within the typeof and delete operators + if (!(anonname === "typeof" || anonname === "delete") || + (state.tokens.next && + (state.tokens.next.value === "." || state.tokens.next.value === "["))) { + + isundef(funct, "W117", state.tokens.curr, v); + } + funct[v] = true; + note_implied(state.tokens.curr); + } else { + switch (s[v]) { + case "function": + case "unction": + this["function"] = true; + s[v] = "closure"; + funct[v] = s["(global)"] ? "global" : "outer"; + break; + case "var": + case "unused": + s[v] = "closure"; + funct[v] = s["(global)"] ? "global" : "outer"; + break; + case "const": + setprop(s, v, { unused: false }); + break; + case "closure": + funct[v] = s["(global)"] ? "global" : "outer"; + break; + case "label": + warning("W037", state.tokens.curr, v); + } + } + } + } + return this; + }, + + led: function () { + error("E033", state.tokens.next, state.tokens.next.value); + } + }; + + type("(regexp)", function () { + return this; + }); + + // ECMAScript parser + + delim("(endline)"); + delim("(begin)"); + delim("(end)").reach = true; + delim("(error)").reach = true; + delim("}").reach = true; + delim(")"); + delim("]"); + delim("\"").reach = true; + delim("'").reach = true; + delim(";"); + delim(":").reach = true; + delim("#"); + + reserve("else"); + reserve("case").reach = true; + reserve("catch"); + reserve("default").reach = true; + reserve("finally"); + reservevar("arguments", function (x) { + if (state.directive["use strict"] && funct["(global)"]) { + warning("E008", x); + } + }); + reservevar("eval"); + reservevar("false"); + reservevar("Infinity"); + reservevar("null"); + reservevar("this", function (x) { + if (state.directive["use strict"] && !state.option.validthis && ((funct["(statement)"] && + funct["(name)"].charAt(0) > "Z") || funct["(global)"])) { + warning("W040", x); + } + }); + reservevar("true"); + reservevar("undefined"); + + assignop("=", "assign", 20); + assignop("+=", "assignadd", 20); + assignop("-=", "assignsub", 20); + assignop("*=", "assignmult", 20); + assignop("/=", "assigndiv", 20).nud = function () { + error("E014"); + }; + assignop("%=", "assignmod", 20); + + bitwiseassignop("&=", "assignbitand", 20); + bitwiseassignop("|=", "assignbitor", 20); + bitwiseassignop("^=", "assignbitxor", 20); + bitwiseassignop("<<=", "assignshiftleft", 20); + bitwiseassignop(">>=", "assignshiftright", 20); + bitwiseassignop(">>>=", "assignshiftrightunsigned", 20); + infix(",", function (left, that) { + var expr; + that.exprs = [left]; + if (!comma({peek: true})) { + return that; + } + while (true) { + if (!(expr = expression(10))) { + break; + } + that.exprs.push(expr); + if (state.tokens.next.value !== "," || !comma()) { + break; + } + } + return that; + }, 10, true); + + infix("?", function (left, that) { + increaseComplexityCount(); + that.left = left; + that.right = expression(10); + advance(":"); + that["else"] = expression(10); + return that; + }, 30); + + var orPrecendence = 40; + infix("||", function (left, that) { + increaseComplexityCount(); + that.left = left; + that.right = expression(orPrecendence); + return that; + }, orPrecendence); + infix("&&", "and", 50); + bitwise("|", "bitor", 70); + bitwise("^", "bitxor", 80); + bitwise("&", "bitand", 90); + relation("==", function (left, right) { + var eqnull = state.option.eqnull && (left.value === "null" || right.value === "null"); + + switch (true) { + case !eqnull && state.option.eqeqeq: + this.from = this.character; + warning("W116", this, "===", "=="); + break; + case isPoorRelation(left): + warning("W041", this, "===", left.value); + break; + case isPoorRelation(right): + warning("W041", this, "===", right.value); + break; + case isTypoTypeof(right, left): + warning("W122", this, right.value); + break; + case isTypoTypeof(left, right): + warning("W122", this, left.value); + break; + } + + return this; + }); + relation("===", function (left, right) { + if (isTypoTypeof(right, left)) { + warning("W122", this, right.value); + } else if (isTypoTypeof(left, right)) { + warning("W122", this, left.value); + } + return this; + }); + relation("!=", function (left, right) { + var eqnull = state.option.eqnull && + (left.value === "null" || right.value === "null"); + + if (!eqnull && state.option.eqeqeq) { + this.from = this.character; + warning("W116", this, "!==", "!="); + } else if (isPoorRelation(left)) { + warning("W041", this, "!==", left.value); + } else if (isPoorRelation(right)) { + warning("W041", this, "!==", right.value); + } else if (isTypoTypeof(right, left)) { + warning("W122", this, right.value); + } else if (isTypoTypeof(left, right)) { + warning("W122", this, left.value); + } + return this; + }); + relation("!==", function (left, right) { + if (isTypoTypeof(right, left)) { + warning("W122", this, right.value); + } else if (isTypoTypeof(left, right)) { + warning("W122", this, left.value); + } + return this; + }); + relation("<"); + relation(">"); + relation("<="); + relation(">="); + bitwise("<<", "shiftleft", 120); + bitwise(">>", "shiftright", 120); + bitwise(">>>", "shiftrightunsigned", 120); + infix("in", "in", 120); + infix("instanceof", "instanceof", 120); + infix("+", function (left, that) { + var right = expression(130); + if (left && right && left.id === "(string)" && right.id === "(string)") { + left.value += right.value; + left.character = right.character; + if (!state.option.scripturl && reg.javascriptURL.test(left.value)) { + warning("W050", left); + } + return left; + } + that.left = left; + that.right = right; + return that; + }, 130); + prefix("+", "num"); + prefix("+++", function () { + warning("W007"); + this.right = expression(150); + this.arity = "unary"; + return this; + }); + infix("+++", function (left) { + warning("W007"); + this.left = left; + this.right = expression(130); + return this; + }, 130); + infix("-", "sub", 130); + prefix("-", "neg"); + prefix("---", function () { + warning("W006"); + this.right = expression(150); + this.arity = "unary"; + return this; + }); + infix("---", function (left) { + warning("W006"); + this.left = left; + this.right = expression(130); + return this; + }, 130); + infix("*", "mult", 140); + infix("/", "div", 140); + infix("%", "mod", 140); + + suffix("++", "postinc"); + prefix("++", "preinc"); + state.syntax["++"].exps = true; + + suffix("--", "postdec"); + prefix("--", "predec"); + state.syntax["--"].exps = true; + prefix("delete", function () { + var p = expression(10); + if (!p || (p.id !== "." && p.id !== "[")) { + warning("W051"); + } + this.first = p; + return this; + }).exps = true; + + prefix("~", function () { + if (state.option.bitwise) { + warning("W052", this, "~"); + } + expression(150); + return this; + }); + + prefix("...", function () { + if (!state.option.inESNext()) { + warning("W104", this, "spread/rest operator"); + } + if (!state.tokens.next.identifier) { + error("E030", state.tokens.next, state.tokens.next.value); + } + expression(150); + return this; + }); + + prefix("!", function () { + this.right = expression(150); + this.arity = "unary"; + + if (!this.right) { // '!' followed by nothing? Give up. + quit("E041", this.line || 0); + } + + if (bang[this.right.id] === true) { + warning("W018", this, "!"); + } + return this; + }); + + prefix("typeof", "typeof"); + prefix("new", function () { + var c = expression(155), i; + if (c && c.id !== "function") { + if (c.identifier) { + c["new"] = true; + switch (c.value) { + case "Number": + case "String": + case "Boolean": + case "Math": + case "JSON": + warning("W053", state.tokens.prev, c.value); + break; + case "Function": + if (!state.option.evil) { + warning("W054"); + } + break; + case "Date": + case "RegExp": + case "this": + break; + default: + if (c.id !== "function") { + i = c.value.substr(0, 1); + if (state.option.newcap && (i < "A" || i > "Z") && !_.has(global, c.value)) { + warning("W055", state.tokens.curr); + } + } + } + } else { + if (c.id !== "." && c.id !== "[" && c.id !== "(") { + warning("W056", state.tokens.curr); + } + } + } else { + if (!state.option.supernew) + warning("W057", this); + } + if (state.tokens.next.id !== "(" && !state.option.supernew) { + warning("W058", state.tokens.curr, state.tokens.curr.value); + } + this.first = c; + return this; + }); + state.syntax["new"].exps = true; + + prefix("void").exps = true; + + infix(".", function (left, that) { + var m = identifier(false, true); + + if (typeof m === "string") { + countMember(m); + } + + that.left = left; + that.right = m; + + if (m && m === "hasOwnProperty" && state.tokens.next.value === "=") { + warning("W001"); + } + + if (left && left.value === "arguments" && (m === "callee" || m === "caller")) { + if (state.option.noarg) + warning("W059", left, m); + else if (state.directive["use strict"]) + error("E008"); + } else if (!state.option.evil && left && left.value === "document" && + (m === "write" || m === "writeln")) { + warning("W060", left); + } + + if (!state.option.evil && (m === "eval" || m === "execScript")) { + warning("W061"); + } + + return that; + }, 160, true); + + infix("(", function (left, that) { + if (state.option.immed && left && !left.immed && left.id === "function") { + warning("W062"); + } + + var n = 0; + var p = []; + + if (left) { + if (left.type === "(identifier)") { + if (left.value.match(/^[A-Z]([A-Z0-9_$]*[a-z][A-Za-z0-9_$]*)?$/)) { + if ("Number String Boolean Date Object Error".indexOf(left.value) === -1) { + if (left.value === "Math") { + warning("W063", left); + } else if (state.option.newcap) { + warning("W064", left); + } + } + } + } + } + + if (state.tokens.next.id !== ")") { + for (;;) { + p[p.length] = expression(10); + n += 1; + if (state.tokens.next.id !== ",") { + break; + } + comma(); + } + } + + advance(")"); + + if (typeof left === "object") { + if (state.option.inES3() && left.value === "parseInt" && n === 1) { + warning("W065", state.tokens.curr); + } + if (!state.option.evil) { + if (left.value === "eval" || left.value === "Function" || + left.value === "execScript") { + warning("W061", left); + + if (p[0] && [0].id === "(string)") { + addInternalSrc(left, p[0].value); + } + } else if (p[0] && p[0].id === "(string)" && + (left.value === "setTimeout" || + left.value === "setInterval")) { + warning("W066", left); + addInternalSrc(left, p[0].value); + + // window.setTimeout/setInterval + } else if (p[0] && p[0].id === "(string)" && + left.value === "." && + left.left.value === "window" && + (left.right === "setTimeout" || + left.right === "setInterval")) { + warning("W066", left); + addInternalSrc(left, p[0].value); + } + } + if (!left.identifier && left.id !== "." && left.id !== "[" && + left.id !== "(" && left.id !== "&&" && left.id !== "||" && + left.id !== "?") { + warning("W067", left); + } + } + + that.left = left; + return that; + }, 155, true).exps = true; + + prefix("(", function () { + var bracket, brackets = []; + var pn, pn1, i = 0; + var ret; + var parens = 1; + + do { + pn = peek(i); + + if (pn.value === "(") { + parens += 1; + } else if (pn.value === ")") { + parens -= 1; + } + + i += 1; + pn1 = peek(i); + } while (!(parens === 0 && pn.value === ")") && + pn1.value !== "=>" && pn1.value !== ";" && pn1.type !== "(end)"); + + if (state.tokens.next.id === "function") { + state.tokens.next.immed = true; + } + + var exprs = []; + + if (state.tokens.next.id !== ")") { + for (;;) { + if (pn1.value === "=>" && _.contains(["{", "["], state.tokens.next.value)) { + bracket = state.tokens.next; + bracket.left = destructuringExpression(); + brackets.push(bracket); + for (var t in bracket.left) { + exprs.push(bracket.left[t].token); + } + } else { + exprs.push(expression(10)); + } + if (state.tokens.next.id !== ",") { + break; + } + comma(); + } + } + + advance(")", this); + if (state.option.immed && exprs[0] && exprs[0].id === "function") { + if (state.tokens.next.id !== "(" && + (state.tokens.next.id !== "." || (peek().value !== "call" && peek().value !== "apply"))) { + warning("W068", this); + } + } + + if (state.tokens.next.value === "=>") { + return exprs; + } + if (!exprs.length) { + return; + } + if (exprs.length > 1) { + ret = Object.create(state.syntax[","]); + ret.exprs = exprs; + } else { + ret = exprs[0]; + } + if (ret) { + ret.paren = true; + } + return ret; + }); + + application("=>"); + + infix("[", function (left, that) { + var e = expression(10), s; + if (e && e.type === "(string)") { + if (!state.option.evil && (e.value === "eval" || e.value === "execScript")) { + warning("W061", that); + } + + countMember(e.value); + if (!state.option.sub && reg.identifier.test(e.value)) { + s = state.syntax[e.value]; + if (!s || !isReserved(s)) { + warning("W069", state.tokens.prev, e.value); + } + } + } + advance("]", that); + + if (e && e.value === "hasOwnProperty" && state.tokens.next.value === "=") { + warning("W001"); + } + + that.left = left; + that.right = e; + return that; + }, 160, true); + + function comprehensiveArrayExpression() { + var res = {}; + res.exps = true; + funct["(comparray)"].stack(); + + // Handle reversed for expressions, used in spidermonkey + var reversed = false; + if (state.tokens.next.value !== "for") { + reversed = true; + if (!state.option.inMoz(true)) { + warning("W116", state.tokens.next, "for", state.tokens.next.value); + } + funct["(comparray)"].setState("use"); + res.right = expression(10); + } + + advance("for"); + if (state.tokens.next.value === "each") { + advance("each"); + if (!state.option.inMoz(true)) { + warning("W118", state.tokens.curr, "for each"); + } + } + advance("("); + funct["(comparray)"].setState("define"); + res.left = expression(130); + if (_.contains(["in", "of"], state.tokens.next.value)) { + advance(); + } else { + error("E045", state.tokens.curr); + } + funct["(comparray)"].setState("generate"); + expression(10); + + advance(")"); + if (state.tokens.next.value === "if") { + advance("if"); + advance("("); + funct["(comparray)"].setState("filter"); + res.filter = expression(10); + advance(")"); + } + + if (!reversed) { + funct["(comparray)"].setState("use"); + res.right = expression(10); + } + + advance("]"); + funct["(comparray)"].unstack(); + return res; + } + + prefix("[", function () { + var blocktype = lookupBlockType(true); + if (blocktype.isCompArray) { + if (!state.option.inESNext()) { + warning("W119", state.tokens.curr, "array comprehension"); + } + return comprehensiveArrayExpression(); + } else if (blocktype.isDestAssign && !state.option.inESNext()) { + warning("W104", state.tokens.curr, "destructuring assignment"); + } + var b = state.tokens.curr.line !== state.tokens.next.line; + this.first = []; + if (b) { + indent += state.option.indent; + if (state.tokens.next.from === indent + state.option.indent) { + indent += state.option.indent; + } + } + while (state.tokens.next.id !== "(end)") { + while (state.tokens.next.id === ",") { + if (!state.option.inES5()) + warning("W070"); + advance(","); + } + + if (state.tokens.next.id === "]") { + break; + } + + this.first.push(expression(10)); + if (state.tokens.next.id === ",") { + comma({ allowTrailing: true }); + if (state.tokens.next.id === "]" && !state.option.inES5(true)) { + warning("W070", state.tokens.curr); + break; + } + } else { + break; + } + } + if (b) { + indent -= state.option.indent; + } + advance("]", this); + return this; + }, 160); + + + function property_name() { + var id = optionalidentifier(false, true); + + if (!id) { + if (state.tokens.next.id === "(string)") { + id = state.tokens.next.value; + advance(); + } else if (state.tokens.next.id === "(number)") { + id = state.tokens.next.value.toString(); + advance(); + } + } + + if (id === "hasOwnProperty") { + warning("W001"); + } + + return id; + } + + function functionparams(parsed) { + var curr, next; + var params = []; + var ident; + var tokens = []; + var t; + var pastDefault = false; + + if (parsed) { + if (Array.isArray(parsed)) { + for (var i in parsed) { + curr = parsed[i]; + if (curr.value === "...") { + if (!state.option.inESNext()) { + warning("W104", curr, "spread/rest operator"); + } + continue; + } else if (curr.value !== ",") { + params.push(curr.value); + addlabel(curr.value, { type: "unused", token: curr }); + } + } + return params; + } else { + if (parsed.identifier === true) { + addlabel(parsed.value, { type: "unused", token: parsed }); + return [parsed]; + } + } + } + + next = state.tokens.next; + + advance("("); + + if (state.tokens.next.id === ")") { + advance(")"); + return; + } + + for (;;) { + if (_.contains(["{", "["], state.tokens.next.id)) { + tokens = destructuringExpression(); + for (t in tokens) { + t = tokens[t]; + if (t.id) { + params.push(t.id); + addlabel(t.id, { type: "unused", token: t.token }); + } + } + } else if (state.tokens.next.value === "...") { + if (!state.option.inESNext()) { + warning("W104", state.tokens.next, "spread/rest operator"); + } + advance("..."); + ident = identifier(true); + params.push(ident); + addlabel(ident, { type: "unused", token: state.tokens.curr }); + } else { + ident = identifier(true); + params.push(ident); + addlabel(ident, { type: "unused", token: state.tokens.curr }); + } + + // it is a syntax error to have a regular argument after a default argument + if (pastDefault) { + if (state.tokens.next.id !== "=") { + error("E051", state.tokens.current); + } + } + if (state.tokens.next.id === "=") { + if (!state.option.inESNext()) { + warning("W119", state.tokens.next, "default parameters"); + } + advance("="); + pastDefault = true; + expression(10); + } + if (state.tokens.next.id === ",") { + comma(); + } else { + advance(")", next); + return params; + } + } + } + + function setprop(funct, name, values) { + if (!funct["(properties)"][name]) { + funct["(properties)"][name] = { unused: false }; + } + + _.extend(funct["(properties)"][name], values); + } + + function getprop(funct, name, prop) { + if (!funct["(properties)"][name]) + return null; + + return funct["(properties)"][name][prop] || null; + } + + function functor(name, token, scope, overwrites) { + var funct = { + "(name)" : name, + "(breakage)" : 0, + "(loopage)" : 0, + "(scope)" : scope, + "(tokens)" : {}, + "(properties)": {}, + + "(catch)" : false, + "(global)" : false, + + "(line)" : null, + "(character)" : null, + "(metrics)" : null, + "(statement)" : null, + "(context)" : null, + "(blockscope)": null, + "(comparray)" : null, + "(generator)" : null, + "(params)" : null + }; + + if (token) { + _.extend(funct, { + "(line)" : token.line, + "(character)": token.character, + "(metrics)" : createMetrics(token) + }); + } + + _.extend(funct, overwrites); + + if (funct["(context)"]) { + funct["(blockscope)"] = funct["(context)"]["(blockscope)"]; + funct["(comparray)"] = funct["(context)"]["(comparray)"]; + } + + return funct; + } + + function doFunction(name, statement, generator, fatarrowparams) { + var f; + var oldOption = state.option; + var oldIgnored = state.ignored; + var oldScope = scope; + + state.option = Object.create(state.option); + state.ignored = Object.create(state.ignored); + scope = Object.create(scope); + + funct = functor(name || "\"" + anonname + "\"", state.tokens.next, scope, { + "(statement)": statement, + "(context)": funct, + "(generator)": generator ? true : null + }); + + f = funct; + state.tokens.curr.funct = funct; + + functions.push(funct); + + if (name) { + addlabel(name, { type: "function" }); + } + + funct["(params)"] = functionparams(fatarrowparams); + funct["(metrics)"].verifyMaxParametersPerFunction(funct["(params)"]); + + // So we parse fat-arrow functions after we encounter =>. So basically + // doFunction is called with the left side of => as its last argument. + // This means that the parser, at that point, had already added its + // arguments to the undefs array and here we undo that. + + JSHINT.undefs = _.filter(JSHINT.undefs, function (item) { + return !_.contains(_.union(fatarrowparams), item[2]); + }); + + block(false, true, true, fatarrowparams ? true : false); + + if (!state.option.noyield && generator && funct["(generator)"] !== "yielded") { + warning("W124", state.tokens.curr); + } + + funct["(metrics)"].verifyMaxStatementsPerFunction(); + funct["(metrics)"].verifyMaxComplexityPerFunction(); + funct["(unusedOption)"] = state.option.unused; + + scope = oldScope; + state.option = oldOption; + state.ignored = oldIgnored; + funct["(last)"] = state.tokens.curr.line; + funct["(lastcharacter)"] = state.tokens.curr.character; + + _.map(Object.keys(funct), function (key) { + if (key[0] === "(") return; + funct["(blockscope)"].unshadow(key); + }); + + funct = funct["(context)"]; + + return f; + } + + function createMetrics(functionStartToken) { + return { + statementCount: 0, + nestedBlockDepth: -1, + ComplexityCount: 1, + + verifyMaxStatementsPerFunction: function () { + if (state.option.maxstatements && + this.statementCount > state.option.maxstatements) { + warning("W071", functionStartToken, this.statementCount); + } + }, + + verifyMaxParametersPerFunction: function (params) { + params = params || []; + + if (state.option.maxparams && params.length > state.option.maxparams) { + warning("W072", functionStartToken, params.length); + } + }, + + verifyMaxNestedBlockDepthPerFunction: function () { + if (state.option.maxdepth && + this.nestedBlockDepth > 0 && + this.nestedBlockDepth === state.option.maxdepth + 1) { + warning("W073", null, this.nestedBlockDepth); + } + }, + + verifyMaxComplexityPerFunction: function () { + var max = state.option.maxcomplexity; + var cc = this.ComplexityCount; + if (max && cc > max) { + warning("W074", functionStartToken, cc); + } + } + }; + } + + function increaseComplexityCount() { + funct["(metrics)"].ComplexityCount += 1; + } + + // Parse assignments that were found instead of conditionals. + // For example: if (a = 1) { ... } + + function checkCondAssignment(expr) { + var id, paren; + if (expr) { + id = expr.id; + paren = expr.paren; + if (id === "," && (expr = expr.exprs[expr.exprs.length - 1])) { + id = expr.id; + paren = paren || expr.paren; + } + } + switch (id) { + case "=": + case "+=": + case "-=": + case "*=": + case "%=": + case "&=": + case "|=": + case "^=": + case "/=": + if (!paren && !state.option.boss) { + warning("W084"); + } + } + } + + + (function (x) { + x.nud = function (isclassdef) { + var b, f, i, p, t, g; + var props = {}; // All properties, including accessors + var tag = ""; + + function saveProperty(name, tkn) { + if (props[name] && _.has(props, name)) + warning("W075", state.tokens.next, i); + else + props[name] = {}; + + props[name].basic = true; + props[name].basictkn = tkn; + } + + function saveSetter(name, tkn) { + if (props[name] && _.has(props, name)) { + if (props[name].basic || props[name].setter) + warning("W075", state.tokens.next, i); + } else { + props[name] = {}; + } + + props[name].setter = true; + props[name].setterToken = tkn; + } + + function saveGetter(name) { + if (props[name] && _.has(props, name)) { + if (props[name].basic || props[name].getter) + warning("W075", state.tokens.next, i); + } else { + props[name] = {}; + } + + props[name].getter = true; + props[name].getterToken = state.tokens.curr; + } + + b = state.tokens.curr.line !== state.tokens.next.line; + if (b) { + indent += state.option.indent; + if (state.tokens.next.from === indent + state.option.indent) { + indent += state.option.indent; + } + } + + for (;;) { + if (state.tokens.next.id === "}") { + break; + } + + if (isclassdef && state.tokens.next.value === "static") { + advance("static"); + tag = "static "; + } + + if (state.tokens.next.value === "get" && peek().id !== ":") { + advance("get"); + + if (!state.option.inES5(!isclassdef)) { + error("E034"); + } + + i = property_name(); + + // ES6 allows for get() {...} and set() {...} method + // definition shorthand syntax, so we don't produce an error + // if the esnext option is enabled. + if (!i && !state.option.inESNext()) { + error("E035"); + } + + // It is a Syntax Error if PropName of MethodDefinition is + // "constructor" and SpecialMethod of MethodDefinition is true. + if (isclassdef && i === "constructor") { + error("E049", state.tokens.next, "class getter method", i); + } + + // We don't want to save this getter unless it's an actual getter + // and not an ES6 concise method + if (i) { + saveGetter(tag + i); + } + + t = state.tokens.next; + f = doFunction(); + p = f["(params)"]; + + // Don't warn about getter/setter pairs if this is an ES6 concise method + if (i && p) { + warning("W076", t, p[0], i); + } + } else if (state.tokens.next.value === "set" && peek().id !== ":") { + advance("set"); + + if (!state.option.inES5(!isclassdef)) { + error("E034"); + } + + i = property_name(); + + // ES6 allows for get() {...} and set() {...} method + // definition shorthand syntax, so we don't produce an error + // if the esnext option is enabled. + if (!i && !state.option.inESNext()) { + error("E035"); + } + + // It is a Syntax Error if PropName of MethodDefinition is + // "constructor" and SpecialMethod of MethodDefinition is true. + if (isclassdef && i === "constructor") { + error("E049", state.tokens.next, "class setter method", i); + } + + // We don't want to save this getter unless it's an actual getter + // and not an ES6 concise method + if (i) { + saveSetter(tag + i, state.tokens.next); + } + + t = state.tokens.next; + f = doFunction(); + p = f["(params)"]; + + // Don't warn about getter/setter pairs if this is an ES6 concise method + if (i && (!p || p.length !== 1)) { + warning("W077", t, i); + } + } else { + g = false; + if (state.tokens.next.value === "*" && state.tokens.next.type === "(punctuator)") { + if (!state.option.inESNext()) { + warning("W104", state.tokens.next, "generator functions"); + } + advance("*"); + g = true; + } + i = property_name(); + saveProperty(tag + i, state.tokens.next); + + if (typeof i !== "string") { + break; + } + + if (state.tokens.next.value === "(") { + if (!state.option.inESNext()) { + warning("W104", state.tokens.curr, "concise methods"); + } + doFunction(i, undefined, g); + } else if (!isclassdef) { + advance(":"); + expression(10); + } + } + // It is a Syntax Error if PropName of MethodDefinition is "prototype". + if (isclassdef && i === "prototype") { + error("E049", state.tokens.next, "class method", i); + } + + countMember(i); + if (isclassdef) { + tag = ""; + continue; + } + if (state.tokens.next.id === ",") { + comma({ allowTrailing: true, property: true }); + if (state.tokens.next.id === ",") { + warning("W070", state.tokens.curr); + } else if (state.tokens.next.id === "}" && !state.option.inES5(true)) { + warning("W070", state.tokens.curr); + } + } else { + break; + } + } + if (b) { + indent -= state.option.indent; + } + advance("}", this); + + // Check for lonely setters if in the ES5 mode. + if (state.option.inES5()) { + for (var name in props) { + if (_.has(props, name) && props[name].setter && !props[name].getter) { + warning("W078", props[name].setterToken); + } + } + } + return this; + }; + x.fud = function () { + error("E036", state.tokens.curr); + }; + }(delim("{"))); + + function destructuringExpression() { + var id, ids; + var identifiers = []; + if (!state.option.inESNext()) { + warning("W104", state.tokens.curr, "destructuring expression"); + } + var nextInnerDE = function () { + var ident; + if (_.contains(["[", "{"], state.tokens.next.value)) { + ids = destructuringExpression(); + for (var id in ids) { + id = ids[id]; + identifiers.push({ id: id.id, token: id.token }); + } + } else if (state.tokens.next.value === ",") { + identifiers.push({ id: null, token: state.tokens.curr }); + } else if (state.tokens.next.value === "(") { + advance("("); + nextInnerDE(); + advance(")"); + } else { + ident = identifier(); + if (ident) + identifiers.push({ id: ident, token: state.tokens.curr }); + } + }; + if (state.tokens.next.value === "[") { + advance("["); + nextInnerDE(); + while (state.tokens.next.value !== "]") { + advance(","); + nextInnerDE(); + } + advance("]"); + } else if (state.tokens.next.value === "{") { + advance("{"); + id = identifier(); + if (state.tokens.next.value === ":") { + advance(":"); + nextInnerDE(); + } else { + identifiers.push({ id: id, token: state.tokens.curr }); + } + while (state.tokens.next.value !== "}") { + advance(","); + id = identifier(); + if (state.tokens.next.value === ":") { + advance(":"); + nextInnerDE(); + } else { + identifiers.push({ id: id, token: state.tokens.curr }); + } + } + advance("}"); + } + return identifiers; + } + + function destructuringExpressionMatch(tokens, value) { + var first = value.first; + + if (!first) + return; + + _.zip(tokens, Array.isArray(first) ? first : [ first ]).forEach(function (val) { + var token = val[0]; + var value = val[1]; + + if (token && value) + token.first = value; + else if (token && token.first && !value) + warning("W080", token.first, token.first.value); + }); + } + + var conststatement = stmt("const", function (prefix) { + var tokens; + var value; + var lone; // State variable to know if it is a lone identifier, or a destructuring statement. + + if (!state.option.inESNext()) + warning("W104", state.tokens.curr, "const"); + + this.first = []; + for (;;) { + var names = []; + if (_.contains(["{", "["], state.tokens.next.value)) { + tokens = destructuringExpression(); + lone = false; + } else { + tokens = [ { id: identifier(), token: state.tokens.curr } ]; + lone = true; + } + for (var t in tokens) { + if (tokens.hasOwnProperty(t)) { + t = tokens[t]; + if (funct[t.id] === "const") { + warning("E011", null, t.id); + } + if (funct["(global)"] && predefined[t.id] === false) { + warning("W079", t.token, t.id); + } + if (t.id) { + addlabel(t.id, { token: t.token, type: "const", unused: true }); + names.push(t.token); + } + } + } + if (prefix) { + break; + } + + this.first = this.first.concat(names); + + if (state.tokens.next.id !== "=") { + warning("E012", state.tokens.curr, state.tokens.curr.value); + } + + if (state.tokens.next.id === "=") { + advance("="); + if (state.tokens.next.id === "undefined") { + warning("W080", state.tokens.prev, state.tokens.prev.value); + } + if (peek(0).id === "=" && state.tokens.next.identifier) { + warning("W120", state.tokens.next, state.tokens.next.value); + } + value = expression(10); + if (lone) { + tokens[0].first = value; + } else { + destructuringExpressionMatch(names, value); + } + } + + if (state.tokens.next.id !== ",") { + break; + } + comma(); + } + return this; + }); + + conststatement.exps = true; + var varstatement = stmt("var", function (prefix) { + // JavaScript does not have block scope. It only has function scope. So, + // declaring a variable in a block can have unexpected consequences. + var tokens, lone, value; + + this.first = []; + for (;;) { + var names = []; + if (_.contains(["{", "["], state.tokens.next.value)) { + tokens = destructuringExpression(); + lone = false; + } else { + tokens = [ { id: identifier(), token: state.tokens.curr } ]; + lone = true; + } + for (var t in tokens) { + if (tokens.hasOwnProperty(t)) { + t = tokens[t]; + if (state.option.inESNext() && funct[t.id] === "const") { + warning("E011", null, t.id); + } + if (funct["(global)"] && predefined[t.id] === false) { + warning("W079", t.token, t.id); + } + if (t.id) { + addlabel(t.id, { type: "unused", token: t.token }); + names.push(t.token); + } + } + } + if (prefix) { + break; + } + + this.first = this.first.concat(names); + + if (state.tokens.next.id === "=") { + advance("="); + if (state.tokens.next.id === "undefined") { + warning("W080", state.tokens.prev, state.tokens.prev.value); + } + if (peek(0).id === "=" && state.tokens.next.identifier) { + warning("W120", state.tokens.next, state.tokens.next.value); + } + value = expression(10); + if (lone) { + tokens[0].first = value; + } else { + destructuringExpressionMatch(names, value); + } + } + + if (state.tokens.next.id !== ",") { + break; + } + comma(); + } + return this; + }); + varstatement.exps = true; + + var letstatement = stmt("let", function (prefix) { + var tokens, lone, value, letblock; + + if (!state.option.inESNext()) { + warning("W104", state.tokens.curr, "let"); + } + + if (state.tokens.next.value === "(") { + if (!state.option.inMoz(true)) { + warning("W118", state.tokens.next, "let block"); + } + advance("("); + funct["(blockscope)"].stack(); + letblock = true; + } else if (funct["(nolet)"]) { + error("E048", state.tokens.curr); + } + + this.first = []; + for (;;) { + var names = []; + if (_.contains(["{", "["], state.tokens.next.value)) { + tokens = destructuringExpression(); + lone = false; + } else { + tokens = [ { id: identifier(), token: state.tokens.curr.value } ]; + lone = true; + } + for (var t in tokens) { + if (tokens.hasOwnProperty(t)) { + t = tokens[t]; + if (state.option.inESNext() && funct[t.id] === "const") { + warning("E011", null, t.id); + } + if (funct["(global)"] && predefined[t.id] === false) { + warning("W079", t.token, t.id); + } + if (t.id && !funct["(nolet)"]) { + addlabel(t.id, { type: "unused", token: t.token, islet: true }); + names.push(t.token); + } + } + } + if (prefix) { + break; + } + + this.first = this.first.concat(names); + + if (state.tokens.next.id === "=") { + advance("="); + if (state.tokens.next.id === "undefined") { + warning("W080", state.tokens.prev, state.tokens.prev.value); + } + if (peek(0).id === "=" && state.tokens.next.identifier) { + warning("W120", state.tokens.next, state.tokens.next.value); + } + value = expression(10); + if (lone) { + tokens[0].first = value; + } else { + destructuringExpressionMatch(names, value); + } + } + + if (state.tokens.next.id !== ",") { + break; + } + comma(); + } + if (letblock) { + advance(")"); + block(true, true); + this.block = true; + funct["(blockscope)"].unstack(); + } + + return this; + }); + letstatement.exps = true; + + blockstmt("class", function () { + return classdef.call(this, true); + }); + + function classdef(stmt) { + /*jshint validthis:true */ + if (!state.option.inESNext()) { + warning("W104", state.tokens.curr, "class"); + } + if (stmt) { + // BindingIdentifier + this.name = identifier(); + addlabel(this.name, { type: "unused", token: state.tokens.curr }); + } else if (state.tokens.next.identifier && state.tokens.next.value !== "extends") { + // BindingIdentifier(opt) + this.name = identifier(); + } + classtail(this); + return this; + } + + function classtail(c) { + var strictness = state.directive["use strict"]; + + // ClassHeritage(opt) + if (state.tokens.next.value === "extends") { + advance("extends"); + c.heritage = expression(10); + } + + // A ClassBody is always strict code. + state.directive["use strict"] = true; + advance("{"); + // ClassBody(opt) + c.body = state.syntax["{"].nud(true); + state.directive["use strict"] = strictness; + } + + blockstmt("function", function () { + var generator = false; + if (state.tokens.next.value === "*") { + advance("*"); + if (state.option.inESNext(true)) { + generator = true; + } else { + warning("W119", state.tokens.curr, "function*"); + } + } + if (inblock) { + warning("W082", state.tokens.curr); + + } + var i = identifier(); + if (funct[i] === "const") { + warning("E011", null, i); + } + addlabel(i, { type: "unction", token: state.tokens.curr }); + + doFunction(i, { statement: true }, generator); + if (state.tokens.next.id === "(" && state.tokens.next.line === state.tokens.curr.line) { + error("E039"); + } + return this; + }); + + prefix("function", function () { + var generator = false; + if (state.tokens.next.value === "*") { + if (!state.option.inESNext()) { + warning("W119", state.tokens.curr, "function*"); + } + advance("*"); + generator = true; + } + var i = optionalidentifier(); + doFunction(i, undefined, generator); + if (!state.option.loopfunc && funct["(loopage)"]) { + warning("W083"); + } + return this; + }); + + blockstmt("if", function () { + var t = state.tokens.next; + increaseComplexityCount(); + state.condition = true; + advance("("); + checkCondAssignment(expression(0)); + advance(")", t); + state.condition = false; + block(true, true); + if (state.tokens.next.id === "else") { + advance("else"); + if (state.tokens.next.id === "if" || state.tokens.next.id === "switch") { + statement(true); + } else { + block(true, true); + } + } + return this; + }); + + blockstmt("try", function () { + var b; + + function doCatch() { + var oldScope = scope; + var e; + + advance("catch"); + advance("("); + + scope = Object.create(oldScope); + + e = state.tokens.next.value; + if (state.tokens.next.type !== "(identifier)") { + e = null; + warning("E030", state.tokens.next, e); + } + + advance(); + + funct = functor("(catch)", state.tokens.next, scope, { + "(context)" : funct, + "(breakage)" : funct["(breakage)"], + "(loopage)" : funct["(loopage)"], + "(statement)": false, + "(catch)" : true + }); + + if (e) { + addlabel(e, { type: "exception" }); + } + + if (state.tokens.next.value === "if") { + if (!state.option.inMoz(true)) { + warning("W118", state.tokens.curr, "catch filter"); + } + advance("if"); + expression(0); + } + + advance(")"); + + state.tokens.curr.funct = funct; + functions.push(funct); + + block(false); + + scope = oldScope; + + funct["(last)"] = state.tokens.curr.line; + funct["(lastcharacter)"] = state.tokens.curr.character; + funct = funct["(context)"]; + } + + block(true); + + while (state.tokens.next.id === "catch") { + increaseComplexityCount(); + if (b && (!state.option.inMoz(true))) { + warning("W118", state.tokens.next, "multiple catch blocks"); + } + doCatch(); + b = true; + } + + if (state.tokens.next.id === "finally") { + advance("finally"); + block(true); + return; + } + + if (!b) { + error("E021", state.tokens.next, "catch", state.tokens.next.value); + } + + return this; + }); + + blockstmt("while", function () { + var t = state.tokens.next; + funct["(breakage)"] += 1; + funct["(loopage)"] += 1; + increaseComplexityCount(); + advance("("); + checkCondAssignment(expression(0)); + advance(")", t); + block(true, true); + funct["(breakage)"] -= 1; + funct["(loopage)"] -= 1; + return this; + }).labelled = true; + + blockstmt("with", function () { + var t = state.tokens.next; + if (state.directive["use strict"]) { + error("E010", state.tokens.curr); + } else if (!state.option.withstmt) { + warning("W085", state.tokens.curr); + } + + advance("("); + expression(0); + advance(")", t); + block(true, true); + + return this; + }); + + blockstmt("switch", function () { + var t = state.tokens.next; + var g = false; + var noindent = false; + + funct["(breakage)"] += 1; + advance("("); + checkCondAssignment(expression(0)); + advance(")", t); + t = state.tokens.next; + advance("{"); + + if (state.tokens.next.from === indent) + noindent = true; + + if (!noindent) + indent += state.option.indent; + + this.cases = []; + + for (;;) { + switch (state.tokens.next.id) { + case "case": + switch (funct["(verb)"]) { + case "yield": + case "break": + case "case": + case "continue": + case "return": + case "switch": + case "throw": + break; + default: + // You can tell JSHint that you don't use break intentionally by + // adding a comment /* falls through */ on a line just before + // the next `case`. + if (!reg.fallsThrough.test(state.lines[state.tokens.next.line - 2])) { + warning("W086", state.tokens.curr, "case"); + } + } + + advance("case"); + this.cases.push(expression(0)); + increaseComplexityCount(); + g = true; + advance(":"); + funct["(verb)"] = "case"; + break; + case "default": + switch (funct["(verb)"]) { + case "yield": + case "break": + case "continue": + case "return": + case "throw": + break; + default: + // Do not display a warning if 'default' is the first statement or if + // there is a special /* falls through */ comment. + if (this.cases.length) { + if (!reg.fallsThrough.test(state.lines[state.tokens.next.line - 2])) { + warning("W086", state.tokens.curr, "default"); + } + } + } + + advance("default"); + g = true; + advance(":"); + break; + case "}": + if (!noindent) + indent -= state.option.indent; + + advance("}", t); + funct["(breakage)"] -= 1; + funct["(verb)"] = undefined; + return; + case "(end)": + error("E023", state.tokens.next, "}"); + return; + default: + indent += state.option.indent; + if (g) { + switch (state.tokens.curr.id) { + case ",": + error("E040"); + return; + case ":": + g = false; + statements(); + break; + default: + error("E025", state.tokens.curr); + return; + } + } else { + if (state.tokens.curr.id === ":") { + advance(":"); + error("E024", state.tokens.curr, ":"); + statements(); + } else { + error("E021", state.tokens.next, "case", state.tokens.next.value); + return; + } + } + indent -= state.option.indent; + } + } + }).labelled = true; + + stmt("debugger", function () { + if (!state.option.debug) { + warning("W087", this); + } + return this; + }).exps = true; + + (function () { + var x = stmt("do", function () { + funct["(breakage)"] += 1; + funct["(loopage)"] += 1; + increaseComplexityCount(); + + this.first = block(true, true); + advance("while"); + var t = state.tokens.next; + advance("("); + checkCondAssignment(expression(0)); + advance(")", t); + funct["(breakage)"] -= 1; + funct["(loopage)"] -= 1; + return this; + }); + x.labelled = true; + x.exps = true; + }()); + + blockstmt("for", function () { + var s, t = state.tokens.next; + var letscope = false; + var foreachtok = null; + + if (t.value === "each") { + foreachtok = t; + advance("each"); + if (!state.option.inMoz(true)) { + warning("W118", state.tokens.curr, "for each"); + } + } + + funct["(breakage)"] += 1; + funct["(loopage)"] += 1; + increaseComplexityCount(); + advance("("); + + // what kind of for(…) statement it is? for(…of…)? for(…in…)? for(…;…;…)? + var nextop; // contains the token of the "in" or "of" operator + var i = 0; + var inof = ["in", "of"]; + do { + nextop = peek(i); + ++i; + } while (!_.contains(inof, nextop.value) && nextop.value !== ";" && + nextop.type !== "(end)"); + + // if we're in a for (… in|of …) statement + if (_.contains(inof, nextop.value)) { + if (!state.option.inESNext() && nextop.value === "of") { + error("W104", nextop, "for of"); + } + + if (state.tokens.next.id === "var") { + advance("var"); + state.syntax["var"].fud.call(state.syntax["var"].fud, true); + } else if (state.tokens.next.id === "let") { + advance("let"); + // create a new block scope + letscope = true; + funct["(blockscope)"].stack(); + state.syntax["let"].fud.call(state.syntax["let"].fud, true); + } else if (!state.tokens.next.identifier) { + error("E030", state.tokens.next, state.tokens.next.type); + advance(); + } else { + switch (funct[state.tokens.next.value]) { + case "unused": + funct[state.tokens.next.value] = "var"; + break; + case "var": + break; + default: + if (!funct["(blockscope)"].getlabel(state.tokens.next.value)) + warning("W088", state.tokens.next, state.tokens.next.value); + } + advance(); + } + advance(nextop.value); + expression(20); + advance(")", t); + s = block(true, true); + if (state.option.forin && s && (s.length > 1 || typeof s[0] !== "object" || + s[0].value !== "if")) { + warning("W089", this); + } + funct["(breakage)"] -= 1; + funct["(loopage)"] -= 1; + } else { + if (foreachtok) { + error("E045", foreachtok); + } + if (state.tokens.next.id !== ";") { + if (state.tokens.next.id === "var") { + advance("var"); + state.syntax["var"].fud.call(state.syntax["var"].fud); + } else if (state.tokens.next.id === "let") { + advance("let"); + // create a new block scope + letscope = true; + funct["(blockscope)"].stack(); + state.syntax["let"].fud.call(state.syntax["let"].fud); + } else { + for (;;) { + expression(0, "for"); + if (state.tokens.next.id !== ",") { + break; + } + comma(); + } + } + } + nolinebreak(state.tokens.curr); + advance(";"); + if (state.tokens.next.id !== ";") { + checkCondAssignment(expression(0)); + } + nolinebreak(state.tokens.curr); + advance(";"); + if (state.tokens.next.id === ";") { + error("E021", state.tokens.next, ")", ";"); + } + if (state.tokens.next.id !== ")") { + for (;;) { + expression(0, "for"); + if (state.tokens.next.id !== ",") { + break; + } + comma(); + } + } + advance(")", t); + block(true, true); + funct["(breakage)"] -= 1; + funct["(loopage)"] -= 1; + + } + // unstack loop blockscope + if (letscope) { + funct["(blockscope)"].unstack(); + } + return this; + }).labelled = true; + + + stmt("break", function () { + var v = state.tokens.next.value; + + if (funct["(breakage)"] === 0) + warning("W052", state.tokens.next, this.value); + + if (!state.option.asi) + nolinebreak(this); + + if (state.tokens.next.id !== ";" && !state.tokens.next.reach) { + if (state.tokens.curr.line === state.tokens.next.line) { + if (funct[v] !== "label") { + warning("W090", state.tokens.next, v); + } else if (scope[v] !== funct) { + warning("W091", state.tokens.next, v); + } + this.first = state.tokens.next; + advance(); + } + } + reachable("break"); + return this; + }).exps = true; + + + stmt("continue", function () { + var v = state.tokens.next.value; + + if (funct["(breakage)"] === 0) + warning("W052", state.tokens.next, this.value); + + if (!state.option.asi) + nolinebreak(this); + + if (state.tokens.next.id !== ";" && !state.tokens.next.reach) { + if (state.tokens.curr.line === state.tokens.next.line) { + if (funct[v] !== "label") { + warning("W090", state.tokens.next, v); + } else if (scope[v] !== funct) { + warning("W091", state.tokens.next, v); + } + this.first = state.tokens.next; + advance(); + } + } else if (!funct["(loopage)"]) { + warning("W052", state.tokens.next, this.value); + } + reachable("continue"); + return this; + }).exps = true; + + + stmt("return", function () { + if (this.line === state.tokens.next.line) { + if (state.tokens.next.id !== ";" && !state.tokens.next.reach) { + this.first = expression(0); + + if (this.first && + this.first.type === "(punctuator)" && this.first.value === "=" && + !this.first.paren && !state.option.boss) { + warningAt("W093", this.first.line, this.first.character); + } + } + } else { + if (state.tokens.next.type === "(punctuator)" && + ["[", "{", "+", "-"].indexOf(state.tokens.next.value) > -1) { + nolinebreak(this); // always warn (Line breaking error) + } + } + reachable("return"); + return this; + }).exps = true; + + (function (x) { + x.exps = true; + x.lbp = 25; + }(prefix("yield", function () { + var prev = state.tokens.prev; + if (state.option.inESNext(true) && !funct["(generator)"]) { + // If it's a yield within a catch clause inside a generator then that's ok + if (!("(catch)" === funct["(name)"] && funct["(context)"]["(generator)"])) { + error("E046", state.tokens.curr, "yield"); + } + } else if (!state.option.inESNext()) { + warning("W104", state.tokens.curr, "yield"); + } + funct["(generator)"] = "yielded"; + if (this.line === state.tokens.next.line || !state.option.inMoz(true)) { + if (state.tokens.next.id !== ";" && !state.tokens.next.reach && state.tokens.next.nud) { + nobreaknonadjacent(state.tokens.curr, state.tokens.next); + this.first = expression(10); + + if (this.first.type === "(punctuator)" && this.first.value === "=" && + !this.first.paren && !state.option.boss) { + warningAt("W093", this.first.line, this.first.character); + } + } + + if (state.option.inMoz(true) && state.tokens.next.id !== ")" && + (prev.lbp > 30 || (!prev.assign && !isEndOfExpr()) || prev.id === "yield")) { + error("E050", this); + } + } else if (!state.option.asi) { + nolinebreak(this); // always warn (Line breaking error) + } + return this; + }))); + + + stmt("throw", function () { + nolinebreak(this); + this.first = expression(20); + reachable("throw"); + return this; + }).exps = true; + + stmt("import", function () { + if (!state.option.inESNext()) { + warning("W119", state.tokens.curr, "import"); + } + + if (state.tokens.next.type === "(string)") { + advance("(string)"); + return this; + } + if (state.tokens.next.identifier) { + this.name = identifier(); + addlabel(this.name, { type: "unused", token: state.tokens.curr }); + } else { + advance("{"); + for (;;) { + if (state.tokens.next.value === "}") { + advance("}"); + break; + } + var importName; + if (state.tokens.next.type === "default") { + importName = "default"; + advance("default"); + } else { + importName = identifier(); + } + if (state.tokens.next.value === "as") { + advance("as"); + importName = identifier(); + } + addlabel(importName, { type: "unused", token: state.tokens.curr }); + + if (state.tokens.next.value === ",") { + advance(","); + } else if (state.tokens.next.value === "}") { + advance("}"); + break; + } else { + error("E024", state.tokens.next, state.tokens.next.value); + break; + } + } + } + + advance("from"); + advance("(string)"); + return this; + }).exps = true; + + stmt("export", function () { + if (!state.option.inESNext()) { + warning("W119", state.tokens.curr, "export"); + } + + if (state.tokens.next.type === "default") { + advance("default"); + if (state.tokens.next.id === "function" || state.tokens.next.id === "class") { + this.block = true; + } + this.exportee = expression(10); + + return this; + } + + if (state.tokens.next.value === "{") { + advance("{"); + for (;;) { + exported[identifier()] = true; + + if (state.tokens.next.value === ",") { + advance(","); + } else if (state.tokens.next.value === "}") { + advance("}"); + break; + } else { + error("E024", state.tokens.next, state.tokens.next.value); + break; + } + } + return this; + } + + if (state.tokens.next.id === "var") { + advance("var"); + exported[state.tokens.next.value] = true; + state.syntax["var"].fud.call(state.syntax["var"].fud); + } else if (state.tokens.next.id === "let") { + advance("let"); + exported[state.tokens.next.value] = true; + state.syntax["let"].fud.call(state.syntax["let"].fud); + } else if (state.tokens.next.id === "const") { + advance("const"); + exported[state.tokens.next.value] = true; + state.syntax["const"].fud.call(state.syntax["const"].fud); + } else if (state.tokens.next.id === "function") { + this.block = true; + advance("function"); + exported[state.tokens.next.value] = true; + state.syntax["function"].fud(); + } else if (state.tokens.next.id === "class") { + this.block = true; + advance("class"); + exported[state.tokens.next.value] = true; + state.syntax["class"].fud(); + } else { + error("E024", state.tokens.next, state.tokens.next.value); + } + + return this; + }).exps = true; + + // Future Reserved Words + + FutureReservedWord("abstract"); + FutureReservedWord("boolean"); + FutureReservedWord("byte"); + FutureReservedWord("char"); + FutureReservedWord("class", { es5: true, nud: classdef }); + FutureReservedWord("double"); + FutureReservedWord("enum", { es5: true }); + FutureReservedWord("export", { es5: true }); + FutureReservedWord("extends", { es5: true }); + FutureReservedWord("final"); + FutureReservedWord("float"); + FutureReservedWord("goto"); + FutureReservedWord("implements", { es5: true, strictOnly: true }); + FutureReservedWord("import", { es5: true }); + FutureReservedWord("int"); + FutureReservedWord("interface", { es5: true, strictOnly: true }); + FutureReservedWord("long"); + FutureReservedWord("native"); + FutureReservedWord("package", { es5: true, strictOnly: true }); + FutureReservedWord("private", { es5: true, strictOnly: true }); + FutureReservedWord("protected", { es5: true, strictOnly: true }); + FutureReservedWord("public", { es5: true, strictOnly: true }); + FutureReservedWord("short"); + FutureReservedWord("static", { es5: true, strictOnly: true }); + FutureReservedWord("super", { es5: true }); + FutureReservedWord("synchronized"); + FutureReservedWord("throws"); + FutureReservedWord("transient"); + FutureReservedWord("volatile"); + + // this function is used to determine wether a squarebracket or a curlybracket + // expression is a comprehension array, destructuring assignment or a json value. + + var lookupBlockType = function () { + var pn, pn1; + var i = -1; + var bracketStack = 0; + var ret = {}; + if (_.contains(["[", "{"], state.tokens.curr.value)) + bracketStack += 1; + do { + pn = (i === -1) ? state.tokens.next : peek(i); + pn1 = peek(i + 1); + i = i + 1; + if (_.contains(["[", "{"], pn.value)) { + bracketStack += 1; + } else if (_.contains(["]", "}"], pn.value)) { + bracketStack -= 1; + } + if (pn.identifier && pn.value === "for" && bracketStack === 1) { + ret.isCompArray = true; + ret.notJson = true; + break; + } + if (_.contains(["}", "]"], pn.value) && pn1.value === "=" && bracketStack === 0) { + ret.isDestAssign = true; + ret.notJson = true; + break; + } + if (pn.value === ";") { + ret.isBlock = true; + ret.notJson = true; + } + } while (bracketStack > 0 && pn.id !== "(end)" && i < 15); + return ret; + }; + + // Check whether this function has been reached for a destructuring assign with undeclared values + function destructuringAssignOrJsonValue() { + // lookup for the assignment (esnext only) + // if it has semicolons, it is a block, so go parse it as a block + // or it's not a block, but there are assignments, check for undeclared variables + + var block = lookupBlockType(); + if (block.notJson) { + if (!state.option.inESNext() && block.isDestAssign) { + warning("W104", state.tokens.curr, "destructuring assignment"); + } + statements(); + // otherwise parse json value + } else { + state.option.laxbreak = true; + state.jsonMode = true; + jsonValue(); + } + } + + // array comprehension parsing function + // parses and defines the three states of the list comprehension in order + // to avoid defining global variables, but keeping them to the list comprehension scope + // only. The order of the states are as follows: + // * "use" which will be the returned iterative part of the list comprehension + // * "define" which will define the variables local to the list comprehension + // * "filter" which will help filter out values + + var arrayComprehension = function () { + var CompArray = function () { + this.mode = "use"; + this.variables = []; + }; + var _carrays = []; + var _current; + function declare(v) { + var l = _current.variables.filter(function (elt) { + // if it has, change its undef state + if (elt.value === v) { + elt.undef = false; + return v; + } + }).length; + return l !== 0; + } + function use(v) { + var l = _current.variables.filter(function (elt) { + // and if it has been defined + if (elt.value === v && !elt.undef) { + if (elt.unused === true) { + elt.unused = false; + } + return v; + } + }).length; + // otherwise we warn about it + return (l === 0); + } + return {stack: function () { + _current = new CompArray(); + _carrays.push(_current); + }, + unstack: function () { + _current.variables.filter(function (v) { + if (v.unused) + warning("W098", v.token, v.value); + if (v.undef) + isundef(v.funct, "W117", v.token, v.value); + }); + _carrays.splice(-1, 1); + _current = _carrays[_carrays.length - 1]; + }, + setState: function (s) { + if (_.contains(["use", "define", "generate", "filter"], s)) + _current.mode = s; + }, + check: function (v) { + if (!_current) { + return; + } + // When we are in "use" state of the list comp, we enqueue that var + if (_current && _current.mode === "use") { + if (use(v)) { + _current.variables.push({ + funct: funct, + token: state.tokens.curr, + value: v, + undef: true, + unused: false + }); + } + return true; + // When we are in "define" state of the list comp, + } else if (_current && _current.mode === "define") { + // check if the variable has been used previously + if (!declare(v)) { + _current.variables.push({ + funct: funct, + token: state.tokens.curr, + value: v, + undef: false, + unused: true + }); + } + return true; + // When we are in the "generate" state of the list comp, + } else if (_current && _current.mode === "generate") { + isundef(funct, "W117", state.tokens.curr, v); + return true; + // When we are in "filter" state, + } else if (_current && _current.mode === "filter") { + // we check whether current variable has been declared + if (use(v)) { + // if not we warn about it + isundef(funct, "W117", state.tokens.curr, v); + } + return true; + } + return false; + } + }; + }; + + + // Parse JSON + + function jsonValue() { + function jsonObject() { + var o = {}, t = state.tokens.next; + advance("{"); + if (state.tokens.next.id !== "}") { + for (;;) { + if (state.tokens.next.id === "(end)") { + error("E026", state.tokens.next, t.line); + } else if (state.tokens.next.id === "}") { + warning("W094", state.tokens.curr); + break; + } else if (state.tokens.next.id === ",") { + error("E028", state.tokens.next); + } else if (state.tokens.next.id !== "(string)") { + warning("W095", state.tokens.next, state.tokens.next.value); + } + if (o[state.tokens.next.value] === true) { + warning("W075", state.tokens.next, state.tokens.next.value); + } else if ((state.tokens.next.value === "__proto__" && + !state.option.proto) || (state.tokens.next.value === "__iterator__" && + !state.option.iterator)) { + warning("W096", state.tokens.next, state.tokens.next.value); + } else { + o[state.tokens.next.value] = true; + } + advance(); + advance(":"); + jsonValue(); + if (state.tokens.next.id !== ",") { + break; + } + advance(","); + } + } + advance("}"); + } + + function jsonArray() { + var t = state.tokens.next; + advance("["); + if (state.tokens.next.id !== "]") { + for (;;) { + if (state.tokens.next.id === "(end)") { + error("E027", state.tokens.next, t.line); + } else if (state.tokens.next.id === "]") { + warning("W094", state.tokens.curr); + break; + } else if (state.tokens.next.id === ",") { + error("E028", state.tokens.next); + } + jsonValue(); + if (state.tokens.next.id !== ",") { + break; + } + advance(","); + } + } + advance("]"); + } + + switch (state.tokens.next.id) { + case "{": + jsonObject(); + break; + case "[": + jsonArray(); + break; + case "true": + case "false": + case "null": + case "(number)": + case "(string)": + advance(); + break; + case "-": + advance("-"); + advance("(number)"); + break; + default: + error("E003", state.tokens.next); + } + } + + var blockScope = function () { + var _current = {}; + var _variables = [_current]; + + function _checkBlockLabels() { + for (var t in _current) { + if (_current[t]["(type)"] === "unused") { + if (state.option.unused) { + var tkn = _current[t]["(token)"]; + var line = tkn.line; + var chr = tkn.character; + warningAt("W098", line, chr, t); + } + } + } + } + + return { + stack: function () { + _current = {}; + _variables.push(_current); + }, + + unstack: function () { + _checkBlockLabels(); + _variables.splice(_variables.length - 1, 1); + _current = _.last(_variables); + }, + + getlabel: function (l) { + for (var i = _variables.length - 1 ; i >= 0; --i) { + if (_.has(_variables[i], l) && !_variables[i][l]["(shadowed)"]) { + return _variables[i]; + } + } + }, + + shadow: function (name) { + for (var i = _variables.length - 1; i >= 0; i--) { + if (_.has(_variables[i], name)) { + _variables[i][name]["(shadowed)"] = true; + } + } + }, + + unshadow: function (name) { + for (var i = _variables.length - 1; i >= 0; i--) { + if (_.has(_variables[i], name)) { + _variables[i][name]["(shadowed)"] = false; + } + } + }, + + current: { + has: function (t) { + return _.has(_current, t); + }, + + add: function (t, type, tok) { + _current[t] = { "(type)" : type, "(token)": tok, "(shadowed)": false }; + } + } + }; + }; + + // The actual JSHINT function itself. + var itself = function (s, o, g) { + var i, k, x; + var optionKeys; + var newOptionObj = {}; + var newIgnoredObj = {}; + + o = _.clone(o); + state.reset(); + + if (o && o.scope) { + JSHINT.scope = o.scope; + } else { + JSHINT.errors = []; + JSHINT.undefs = []; + JSHINT.internals = []; + JSHINT.blacklist = {}; + JSHINT.scope = "(main)"; + } + + predefined = Object.create(null); + combine(predefined, vars.ecmaIdentifiers); + combine(predefined, vars.reservedVars); + + combine(predefined, g || {}); + + declared = Object.create(null); + exported = Object.create(null); + + function each(obj, cb) { + if (!obj) + return; + + if (!Array.isArray(obj) && typeof obj === "object") + obj = Object.keys(obj); + + obj.forEach(cb); + } + + if (o) { + each(o.predef || null, function (item) { + var slice, prop; + + if (item[0] === "-") { + slice = item.slice(1); + JSHINT.blacklist[slice] = slice; + } else { + prop = Object.getOwnPropertyDescriptor(o.predef, item); + predefined[item] = prop ? prop.value : false; + } + }); + + each(o.exported || null, function (item) { + exported[item] = true; + }); + + delete o.predef; + delete o.exported; + + optionKeys = Object.keys(o); + for (x = 0; x < optionKeys.length; x++) { + if (/^-W\d{3}$/g.test(optionKeys[x])) { + newIgnoredObj[optionKeys[x].slice(1)] = true; + } else { + newOptionObj[optionKeys[x]] = o[optionKeys[x]]; + + if (optionKeys[x] === "newcap" && o[optionKeys[x]] === false) + newOptionObj["(explicitNewcap)"] = true; + } + } + } + + state.option = newOptionObj; + state.ignored = newIgnoredObj; + + state.option.indent = state.option.indent || 4; + state.option.maxerr = state.option.maxerr || 50; + + indent = 1; + global = Object.create(predefined); + scope = global; + + funct = functor("(global)", null, scope, { + "(global)" : true, + "(blockscope)": blockScope(), + "(comparray)" : arrayComprehension(), + "(metrics)" : createMetrics(state.tokens.next) + }); + + functions = [funct]; + urls = []; + stack = null; + member = {}; + membersOnly = null; + implied = {}; + inblock = false; + lookahead = []; + unuseds = []; + + if (!isString(s) && !Array.isArray(s)) { + errorAt("E004", 0); + return false; + } + + api = { + get isJSON() { + return state.jsonMode; + }, + + getOption: function (name) { + return state.option[name] || null; + }, + + getCache: function (name) { + return state.cache[name]; + }, + + setCache: function (name, value) { + state.cache[name] = value; + }, + + warn: function (code, data) { + warningAt.apply(null, [ code, data.line, data.char ].concat(data.data)); + }, + + on: function (names, listener) { + names.split(" ").forEach(function (name) { + emitter.on(name, listener); + }.bind(this)); + } + }; + + emitter.removeAllListeners(); + (extraModules || []).forEach(function (func) { + func(api); + }); + + state.tokens.prev = state.tokens.curr = state.tokens.next = state.syntax["(begin)"]; + + lex = new Lexer(s); + + lex.on("warning", function (ev) { + warningAt.apply(null, [ ev.code, ev.line, ev.character].concat(ev.data)); + }); + + lex.on("error", function (ev) { + errorAt.apply(null, [ ev.code, ev.line, ev.character ].concat(ev.data)); + }); + + lex.on("fatal", function (ev) { + quit("E041", ev.line, ev.from); + }); + + lex.on("Identifier", function (ev) { + emitter.emit("Identifier", ev); + }); + + lex.on("String", function (ev) { + emitter.emit("String", ev); + }); + + lex.on("Number", function (ev) { + emitter.emit("Number", ev); + }); + + lex.start(); + + // Check options + for (var name in o) { + if (_.has(o, name)) { + checkOption(name, state.tokens.curr); + } + } + + assume(); + + // combine the passed globals after we've assumed all our options + combine(predefined, g || {}); + + //reset values + comma.first = true; + + try { + advance(); + switch (state.tokens.next.id) { + case "{": + case "[": + destructuringAssignOrJsonValue(); + break; + default: + directives(); + + if (state.directive["use strict"]) { + if (!state.option.globalstrict && !(state.option.node || state.option.phantom)) { + warning("W097", state.tokens.prev); + } + } + + statements(); + } + advance((state.tokens.next && state.tokens.next.value !== ".") ? "(end)" : undefined); + funct["(blockscope)"].unstack(); + + var markDefined = function (name, context) { + do { + if (typeof context[name] === "string") { + // JSHINT marks unused variables as 'unused' and + // unused function declaration as 'unction'. This + // code changes such instances back 'var' and + // 'closure' so that the code in JSHINT.data() + // doesn't think they're unused. + + if (context[name] === "unused") + context[name] = "var"; + else if (context[name] === "unction") + context[name] = "closure"; + + return true; + } + + context = context["(context)"]; + } while (context); + + return false; + }; + + var clearImplied = function (name, line) { + if (!implied[name]) + return; + + var newImplied = []; + for (var i = 0; i < implied[name].length; i += 1) { + if (implied[name][i] !== line) + newImplied.push(implied[name][i]); + } + + if (newImplied.length === 0) + delete implied[name]; + else + implied[name] = newImplied; + }; + + var warnUnused = function (name, tkn, type, unused_opt) { + var line = tkn.line; + var chr = tkn.character; + + if (unused_opt === undefined) { + unused_opt = state.option.unused; + } + + if (unused_opt === true) { + unused_opt = "last-param"; + } + + var warnable_types = { + "vars": ["var"], + "last-param": ["var", "param"], + "strict": ["var", "param", "last-param"] + }; + + if (unused_opt) { + if (warnable_types[unused_opt] && warnable_types[unused_opt].indexOf(type) !== -1) { + warningAt("W098", line, chr, name); + } + } + + unuseds.push({ + name: name, + line: line, + character: chr + }); + }; + + var checkUnused = function (func, key) { + var type = func[key]; + var tkn = func["(tokens)"][key]; + + if (key.charAt(0) === "(") + return; + + if (type !== "unused" && type !== "unction" && type !== "const") + return; + + // Params are checked separately from other variables. + if (func["(params)"] && func["(params)"].indexOf(key) !== -1) + return; + + // Variable is in global scope and defined as exported. + if (func["(global)"] && _.has(exported, key)) + return; + + // Is this constant unused? + if (type === "const" && !getprop(func, key, "unused")) + return; + + warnUnused(key, tkn, "var"); + }; + + // Check queued 'x is not defined' instances to see if they're still undefined. + for (i = 0; i < JSHINT.undefs.length; i += 1) { + k = JSHINT.undefs[i].slice(0); + + if (markDefined(k[2].value, k[0])) { + clearImplied(k[2].value, k[2].line); + } else if (state.option.undef) { + warning.apply(warning, k.slice(1)); + } + } + + functions.forEach(function (func) { + if (func["(unusedOption)"] === false) { + return; + } + + for (var key in func) { + if (_.has(func, key)) { + checkUnused(func, key); + } + } + + if (!func["(params)"]) + return; + + var params = func["(params)"].slice(); + var param = params.pop(); + var type, unused_opt; + + while (param) { + type = func[param]; + unused_opt = func["(unusedOption)"] || state.option.unused; + unused_opt = unused_opt === true ? "last-param" : unused_opt; + + // 'undefined' is a special case for (function (window, undefined) { ... })(); + // patterns. + + if (param === "undefined") + return; + + if (type === "unused" || type === "unction") { + warnUnused(param, func["(tokens)"][param], "param", func["(unusedOption)"]); + } else if (unused_opt === "last-param") { + return; + } + + param = params.pop(); + } + }); + + for (var key in declared) { + if (_.has(declared, key) && !_.has(global, key) && !_.has(exported, key)) { + warnUnused(key, declared[key], "var"); + } + } + + } catch (err) { + if (err && err.name === "JSHintError") { + var nt = state.tokens.next || {}; + JSHINT.errors.push({ + scope : "(main)", + raw : err.raw, + code : err.code, + reason : err.message, + line : err.line || nt.line, + character : err.character || nt.from + }, null); + } else { + throw err; + } + } + + // Loop over the listed "internals", and check them as well. + + if (JSHINT.scope === "(main)") { + o = o || {}; + + for (i = 0; i < JSHINT.internals.length; i += 1) { + k = JSHINT.internals[i]; + o.scope = k.elem; + itself(k.value, o, g); + } + } + + return JSHINT.errors.length === 0; + }; + + // Modules. + itself.addModule = function (func) { + extraModules.push(func); + }; + + itself.addModule(style.register); + + // Data summary. + itself.data = function () { + var data = { + functions: [], + options: state.option + }; + + var implieds = []; + var members = []; + var fu, f, i, j, n, globals; + + if (itself.errors.length) { + data.errors = itself.errors; + } + + if (state.jsonMode) { + data.json = true; + } + + for (n in implied) { + if (_.has(implied, n)) { + implieds.push({ + name: n, + line: implied[n] + }); + } + } + + if (implieds.length > 0) { + data.implieds = implieds; + } + + if (urls.length > 0) { + data.urls = urls; + } + + globals = Object.keys(scope); + if (globals.length > 0) { + data.globals = globals; + } + + for (i = 1; i < functions.length; i += 1) { + f = functions[i]; + fu = {}; + + for (j = 0; j < functionicity.length; j += 1) { + fu[functionicity[j]] = []; + } + + for (j = 0; j < functionicity.length; j += 1) { + if (fu[functionicity[j]].length === 0) { + delete fu[functionicity[j]]; + } + } + + fu.name = f["(name)"]; + fu.param = f["(params)"]; + fu.line = f["(line)"]; + fu.character = f["(character)"]; + fu.last = f["(last)"]; + fu.lastcharacter = f["(lastcharacter)"]; + + fu.metrics = { + complexity: f["(metrics)"].ComplexityCount, + parameters: (f["(params)"] || []).length, + statements: f["(metrics)"].statementCount + }; + + data.functions.push(fu); + } + + if (unuseds.length > 0) { + data.unused = unuseds; + } + + members = []; + for (n in member) { + if (typeof member[n] === "number") { + data.member = member; + break; + } + } + + return data; + }; + + itself.jshint = itself; + + return itself; }()); // Make JSHINT a Node module, if possible. if (typeof exports === "object" && exports) { - exports.JSHINT = JSHINT; + exports.JSHINT = JSHINT; } }, -{"../shared/messages.js":2,"../shared/vars.js":3,"./lex.js":5,"./reg.js":6,"./state.js":7,"./style.js":8,"console-browserify":9,"events":10,"underscore":1}], -5:[function(req,module,exports){ +{"./lex.js":4,"./messages.js":5,"./reg.js":6,"./state.js":7,"./style.js":8,"./vars.js":9,"events":10,"underscore":2}], +4:[function(_dereq_,module,exports){ /* * Lexical analysis and token construction. */ "use strict"; -var _ = req("underscore"); -var events = req("events"); -var reg = req("./reg.js"); -var state = req("./state.js").state; +var _ = _dereq_("underscore"); +var events = _dereq_("events"); +var reg = _dereq_("./reg.js"); +var state = _dereq_("./state.js").state; + +var unicodeData = _dereq_("../data/ascii-identifier-data.js"); +var asciiIdentifierStartTable = unicodeData.asciiIdentifierStartTable; +var asciiIdentifierPartTable = unicodeData.asciiIdentifierPartTable; // Some of these token types are from JavaScript Parser API // while others are specific to JSHint parser. // JS Parser API: https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API var Token = { - Identifier: 1, - Punctuator: 2, - NumericLiteral: 3, - StringLiteral: 4, - Comment: 5, - Keyword: 6, - NullLiteral: 7, - BooleanLiteral: 8, - RegExp: 9 + Identifier: 1, + Punctuator: 2, + NumericLiteral: 3, + StringLiteral: 4, + Comment: 5, + Keyword: 6, + NullLiteral: 7, + BooleanLiteral: 8, + RegExp: 9, + TemplateLiteral: 10 }; -// This is auto generated from the unicode tables. -// The tables are at: -// http://www.fileformat.info/info/unicode/category/Lu/list.htm -// http://www.fileformat.info/info/unicode/category/Ll/list.htm -// http://www.fileformat.info/info/unicode/category/Lt/list.htm -// http://www.fileformat.info/info/unicode/category/Lm/list.htm -// http://www.fileformat.info/info/unicode/category/Lo/list.htm -// http://www.fileformat.info/info/unicode/category/Nl/list.htm - -var unicodeLetterTable = [ - 170, 170, 181, 181, 186, 186, 192, 214, - 216, 246, 248, 705, 710, 721, 736, 740, 748, 748, 750, 750, - 880, 884, 886, 887, 890, 893, 902, 902, 904, 906, 908, 908, - 910, 929, 931, 1013, 1015, 1153, 1162, 1319, 1329, 1366, - 1369, 1369, 1377, 1415, 1488, 1514, 1520, 1522, 1568, 1610, - 1646, 1647, 1649, 1747, 1749, 1749, 1765, 1766, 1774, 1775, - 1786, 1788, 1791, 1791, 1808, 1808, 1810, 1839, 1869, 1957, - 1969, 1969, 1994, 2026, 2036, 2037, 2042, 2042, 2048, 2069, - 2074, 2074, 2084, 2084, 2088, 2088, 2112, 2136, 2308, 2361, - 2365, 2365, 2384, 2384, 2392, 2401, 2417, 2423, 2425, 2431, - 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482, - 2486, 2489, 2493, 2493, 2510, 2510, 2524, 2525, 2527, 2529, - 2544, 2545, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, - 2610, 2611, 2613, 2614, 2616, 2617, 2649, 2652, 2654, 2654, - 2674, 2676, 2693, 2701, 2703, 2705, 2707, 2728, 2730, 2736, - 2738, 2739, 2741, 2745, 2749, 2749, 2768, 2768, 2784, 2785, - 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, - 2869, 2873, 2877, 2877, 2908, 2909, 2911, 2913, 2929, 2929, - 2947, 2947, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, - 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 3001, - 3024, 3024, 3077, 3084, 3086, 3088, 3090, 3112, 3114, 3123, - 3125, 3129, 3133, 3133, 3160, 3161, 3168, 3169, 3205, 3212, - 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3261, 3261, - 3294, 3294, 3296, 3297, 3313, 3314, 3333, 3340, 3342, 3344, - 3346, 3386, 3389, 3389, 3406, 3406, 3424, 3425, 3450, 3455, - 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526, - 3585, 3632, 3634, 3635, 3648, 3654, 3713, 3714, 3716, 3716, - 3719, 3720, 3722, 3722, 3725, 3725, 3732, 3735, 3737, 3743, - 3745, 3747, 3749, 3749, 3751, 3751, 3754, 3755, 3757, 3760, - 3762, 3763, 3773, 3773, 3776, 3780, 3782, 3782, 3804, 3805, - 3840, 3840, 3904, 3911, 3913, 3948, 3976, 3980, 4096, 4138, - 4159, 4159, 4176, 4181, 4186, 4189, 4193, 4193, 4197, 4198, - 4206, 4208, 4213, 4225, 4238, 4238, 4256, 4293, 4304, 4346, - 4348, 4348, 4352, 4680, 4682, 4685, 4688, 4694, 4696, 4696, - 4698, 4701, 4704, 4744, 4746, 4749, 4752, 4784, 4786, 4789, - 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4822, 4824, 4880, - 4882, 4885, 4888, 4954, 4992, 5007, 5024, 5108, 5121, 5740, - 5743, 5759, 5761, 5786, 5792, 5866, 5870, 5872, 5888, 5900, - 5902, 5905, 5920, 5937, 5952, 5969, 5984, 5996, 5998, 6000, - 6016, 6067, 6103, 6103, 6108, 6108, 6176, 6263, 6272, 6312, - 6314, 6314, 6320, 6389, 6400, 6428, 6480, 6509, 6512, 6516, - 6528, 6571, 6593, 6599, 6656, 6678, 6688, 6740, 6823, 6823, - 6917, 6963, 6981, 6987, 7043, 7072, 7086, 7087, 7104, 7141, - 7168, 7203, 7245, 7247, 7258, 7293, 7401, 7404, 7406, 7409, - 7424, 7615, 7680, 7957, 7960, 7965, 7968, 8005, 8008, 8013, - 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061, - 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140, - 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188, - 8305, 8305, 8319, 8319, 8336, 8348, 8450, 8450, 8455, 8455, - 8458, 8467, 8469, 8469, 8473, 8477, 8484, 8484, 8486, 8486, - 8488, 8488, 8490, 8493, 8495, 8505, 8508, 8511, 8517, 8521, - 8526, 8526, 8544, 8584, 11264, 11310, 11312, 11358, - 11360, 11492, 11499, 11502, 11520, 11557, 11568, 11621, - 11631, 11631, 11648, 11670, 11680, 11686, 11688, 11694, - 11696, 11702, 11704, 11710, 11712, 11718, 11720, 11726, - 11728, 11734, 11736, 11742, 11823, 11823, 12293, 12295, - 12321, 12329, 12337, 12341, 12344, 12348, 12353, 12438, - 12445, 12447, 12449, 12538, 12540, 12543, 12549, 12589, - 12593, 12686, 12704, 12730, 12784, 12799, 13312, 13312, - 19893, 19893, 19968, 19968, 40907, 40907, 40960, 42124, - 42192, 42237, 42240, 42508, 42512, 42527, 42538, 42539, - 42560, 42606, 42623, 42647, 42656, 42735, 42775, 42783, - 42786, 42888, 42891, 42894, 42896, 42897, 42912, 42921, - 43002, 43009, 43011, 43013, 43015, 43018, 43020, 43042, - 43072, 43123, 43138, 43187, 43250, 43255, 43259, 43259, - 43274, 43301, 43312, 43334, 43360, 43388, 43396, 43442, - 43471, 43471, 43520, 43560, 43584, 43586, 43588, 43595, - 43616, 43638, 43642, 43642, 43648, 43695, 43697, 43697, - 43701, 43702, 43705, 43709, 43712, 43712, 43714, 43714, - 43739, 43741, 43777, 43782, 43785, 43790, 43793, 43798, - 43808, 43814, 43816, 43822, 43968, 44002, 44032, 44032, - 55203, 55203, 55216, 55238, 55243, 55291, 63744, 64045, - 64048, 64109, 64112, 64217, 64256, 64262, 64275, 64279, - 64285, 64285, 64287, 64296, 64298, 64310, 64312, 64316, - 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, - 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, - 65136, 65140, 65142, 65276, 65313, 65338, 65345, 65370, - 65382, 65470, 65474, 65479, 65482, 65487, 65490, 65495, - 65498, 65500, 65536, 65547, 65549, 65574, 65576, 65594, - 65596, 65597, 65599, 65613, 65616, 65629, 65664, 65786, - 65856, 65908, 66176, 66204, 66208, 66256, 66304, 66334, - 66352, 66378, 66432, 66461, 66464, 66499, 66504, 66511, - 66513, 66517, 66560, 66717, 67584, 67589, 67592, 67592, - 67594, 67637, 67639, 67640, 67644, 67644, 67647, 67669, - 67840, 67861, 67872, 67897, 68096, 68096, 68112, 68115, - 68117, 68119, 68121, 68147, 68192, 68220, 68352, 68405, - 68416, 68437, 68448, 68466, 68608, 68680, 69635, 69687, - 69763, 69807, 73728, 74606, 74752, 74850, 77824, 78894, - 92160, 92728, 110592, 110593, 119808, 119892, 119894, 119964, - 119966, 119967, 119970, 119970, 119973, 119974, 119977, 119980, - 119982, 119993, 119995, 119995, 119997, 120003, 120005, 120069, - 120071, 120074, 120077, 120084, 120086, 120092, 120094, 120121, - 120123, 120126, 120128, 120132, 120134, 120134, 120138, 120144, - 120146, 120485, 120488, 120512, 120514, 120538, 120540, 120570, - 120572, 120596, 120598, 120628, 120630, 120654, 120656, 120686, - 120688, 120712, 120714, 120744, 120746, 120770, 120772, 120779, - 131072, 131072, 173782, 173782, 173824, 173824, 177972, 177972, - 177984, 177984, 178205, 178205, 194560, 195101 -]; - -var identifierStartTable = []; - -for (var i = 0; i < 128; i++) { - identifierStartTable[i] = - i === 36 || // $ - i >= 65 && i <= 90 || // A-Z - i === 95 || // _ - i >= 97 && i <= 122; // a-z -} - -var identifierPartTable = []; - -for (var i = 0; i < 128; i++) { - identifierPartTable[i] = - identifierStartTable[i] || // $, _, A-Z, a-z - i >= 48 && i <= 57; // 0-9 -} - // Object that handles postponed lexing verifications that checks the parsed // environment state. function asyncTrigger() { - var _checks = []; + var _checks = []; - return { - push: function (fn) { - _checks.push(fn); - }, + return { + push: function (fn) { + _checks.push(fn); + }, - check: function () { - for (var check = 0; check < _checks.length; ++check) { - _checks[check](); - } + check: function () { + for (var check = 0; check < _checks.length; ++check) { + _checks[check](); + } - _checks.splice(0, _checks.length); - } - }; + _checks.splice(0, _checks.length); + } + }; } /* @@ -7070,1503 +6318,1808 @@ function asyncTrigger() { * JSLint format. */ function Lexer(source) { - var lines = source; + var lines = source; - if (typeof lines === "string") { - lines = lines - .replace(/\r\n/g, "\n") - .replace(/\r/g, "\n") - .split("\n"); - } + if (typeof lines === "string") { + lines = lines + .replace(/\r\n/g, "\n") + .replace(/\r/g, "\n") + .split("\n"); + } - // If the first line is a shebang (#!), make it a blank and move on. - // Shebangs are used by Node scripts. + // If the first line is a shebang (#!), make it a blank and move on. + // Shebangs are used by Node scripts. - if (lines[0] && lines[0].substr(0, 2) === "#!") { - lines[0] = ""; - } + if (lines[0] && lines[0].substr(0, 2) === "#!") { + if (lines[0].indexOf("node") !== -1) { + state.option.node = true; + } + lines[0] = ""; + } - this.emitter = new events.EventEmitter(); - this.source = source; - this.setLines(lines); - this.prereg = true; + this.emitter = new events.EventEmitter(); + this.source = source; + this.setLines(lines); + this.prereg = true; - this.line = 0; - this.char = 1; - this.from = 1; - this.input = ""; + this.line = 0; + this.char = 1; + this.from = 1; + this.input = ""; + this.inComment = false; - for (var i = 0; i < state.option.indent; i += 1) { - state.tab += " "; - } + for (var i = 0; i < state.option.indent; i += 1) { + state.tab += " "; + } } Lexer.prototype = { - _lines: [], - - getLines: function () { - this._lines = state.lines; - return this._lines; - }, - - setLines: function (val) { - this._lines = val; - state.lines = this._lines; - }, - - /* - * Return the next i character without actually moving the - * char pointer. - */ - peek: function (i) { - return this.input.charAt(i || 0); - }, - - /* - * Move the char pointer forward i times. - */ - skip: function (i) { - i = i || 1; - this.char += i; - this.input = this.input.slice(i); - }, - - /* - * Subscribe to a token event. The API for this method is similar - * Underscore.js i.e. you can subscribe to multiple events with - * one call: - * - * lex.on("Identifier Number", function (data) { - * // ... - * }); - */ - on: function (names, listener) { - names.split(" ").forEach(function (name) { - this.emitter.on(name, listener); - }.bind(this)); - }, - - /* - * Trigger a token event. All arguments will be passed to each - * listener. - */ - trigger: function () { - this.emitter.emit.apply(this.emitter, Array.prototype.slice.call(arguments)); - }, - - /* - * Postpone a token event. the checking condition is set as - * last parameter, and the trigger function is called in a - * stored callback. To be later called using the check() function - * by the parser. This avoids parser's peek() to give the lexer - * a false context. - */ - triggerAsync: function (type, args, checks, fn) { - checks.push(function () { - if (fn()) { - this.trigger(type, args); - } - }.bind(this)); - }, - - /* - * Extract a punctuator out of the next sequence of characters - * or return 'null' if its not possible. - * - * This method's implementation was heavily influenced by the - * scanPunctuator function in the Esprima parser's source code. - */ - scanPunctuator: function () { - var ch1 = this.peek(); - var ch2, ch3, ch4; - - switch (ch1) { - // Most common single-character punctuators - case ".": - if ((/^[0-9]$/).test(this.peek(1))) { - return null; - } - if (this.peek(1) === "." && this.peek(2) === ".") { - return { - type: Token.Punctuator, - value: "..." - }; - } - /* falls through */ - case "(": - case ")": - case ";": - case ",": - case "{": - case "}": - case "[": - case "]": - case ":": - case "~": - case "?": - return { - type: Token.Punctuator, - value: ch1 - }; - - // A pound sign (for Node shebangs) - case "#": - return { - type: Token.Punctuator, - value: ch1 - }; - - // We're at the end of input - case "": - return null; - } - - // Peek more characters - - ch2 = this.peek(1); - ch3 = this.peek(2); - ch4 = this.peek(3); - - // 4-character punctuator: >>>= - - if (ch1 === ">" && ch2 === ">" && ch3 === ">" && ch4 === "=") { - return { - type: Token.Punctuator, - value: ">>>=" - }; - } - - // 3-character punctuators: === !== >>> <<= >>= - - if (ch1 === "=" && ch2 === "=" && ch3 === "=") { - return { - type: Token.Punctuator, - value: "===" - }; - } - - if (ch1 === "!" && ch2 === "=" && ch3 === "=") { - return { - type: Token.Punctuator, - value: "!==" - }; - } - - if (ch1 === ">" && ch2 === ">" && ch3 === ">") { - return { - type: Token.Punctuator, - value: ">>>" - }; - } - - if (ch1 === "<" && ch2 === "<" && ch3 === "=") { - return { - type: Token.Punctuator, - value: "<<=" - }; - } - - if (ch1 === ">" && ch2 === ">" && ch3 === "=") { - return { - type: Token.Punctuator, - value: ">>=" - }; - } - - // Fat arrow punctuator - if (ch1 === "=" && ch2 === ">") { - return { - type: Token.Punctuator, - value: ch1 + ch2 - }; - } - - // 2-character punctuators: <= >= == != ++ -- << >> && || - // += -= *= %= &= |= ^= (but not /=, see below) - if (ch1 === ch2 && ("+-<>&|".indexOf(ch1) >= 0)) { - return { - type: Token.Punctuator, - value: ch1 + ch2 - }; - } - - if ("<>=!+-*%&|^".indexOf(ch1) >= 0) { - if (ch2 === "=") { - return { - type: Token.Punctuator, - value: ch1 + ch2 - }; - } - - return { - type: Token.Punctuator, - value: ch1 - }; - } - - // Special case: /=. We need to make sure that this is an - // operator and not a regular expression. - - if (ch1 === "/") { - if (ch2 === "=" && /\/=(?!(\S*\/[gim]?))/.test(this.input)) { - // /= is not a part of a regular expression, return it as a - // punctuator. - return { - type: Token.Punctuator, - value: "/=" - }; - } - - return { - type: Token.Punctuator, - value: "/" - }; - } - - return null; - }, - - /* - * Extract a comment out of the next sequence of characters and/or - * lines or return 'null' if its not possible. Since comments can - * span across multiple lines this method has to move the char - * pointer. - * - * In addition to normal JavaScript comments (// and /*) this method - * also recognizes JSHint- and JSLint-specific comments such as - * /*jshint, /*jslint, /*globals and so on. - */ - scanComments: function () { - var ch1 = this.peek(); - var ch2 = this.peek(1); - var rest = this.input.substr(2); - var startLine = this.line; - var startChar = this.char; - - // Create a comment token object and make sure it - // has all the data JSHint needs to work with special - // comments. - - function commentToken(label, body, opt) { - var special = ["jshint", "jslint", "members", "member", "globals", "global", "exported"]; - var isSpecial = false; - var value = label + body; - var commentType = "plain"; - opt = opt || {}; - - if (opt.isMultiline) { - value += "*/"; - } - - special.forEach(function (str) { - if (isSpecial) { - return; - } - - // Don't recognize any special comments other than jshint for single-line - // comments. This introduced many problems with legit comments. - if (label === "//" && str !== "jshint") { - return; - } - - if (body.substr(0, str.length) === str) { - isSpecial = true; - label = label + str; - body = body.substr(str.length); - } - - if (!isSpecial && body.charAt(0) === " " && body.substr(1, str.length) === str) { - isSpecial = true; - label = label + " " + str; - body = body.substr(str.length + 1); - } - - if (!isSpecial) { - return; - } - - switch (str) { - case "member": - commentType = "members"; - break; - case "global": - commentType = "globals"; - break; - default: - commentType = str; - } - }); - - return { - type: Token.Comment, - commentType: commentType, - value: value, - body: body, - isSpecial: isSpecial, - isMultiline: opt.isMultiline || false, - isMalformed: opt.isMalformed || false - }; - } - - // End of unbegun comment. Raise an error and skip that input. - if (ch1 === "*" && ch2 === "/") { - this.trigger("error", { - code: "E018", - line: startLine, - character: startChar - }); - - this.skip(2); - return null; - } - - // Comments must start either with // or /* - if (ch1 !== "/" || (ch2 !== "*" && ch2 !== "/")) { - return null; - } - - // One-line comment - if (ch2 === "/") { - this.skip(this.input.length); // Skip to the EOL. - return commentToken("//", rest); - } - - var body = ""; - - /* Multi-line comment */ - if (ch2 === "*") { - this.skip(2); - - while (this.peek() !== "*" || this.peek(1) !== "/") { - if (this.peek() === "") { // End of Line - body += "\n"; - - // If we hit EOF and our comment is still unclosed, - // trigger an error and end the comment implicitly. - if (!this.nextLine()) { - this.trigger("error", { - code: "E017", - line: startLine, - character: startChar - }); - - return commentToken("/*", body, { - isMultiline: true, - isMalformed: true - }); - } - } else { - body += this.peek(); - this.skip(); - } - } - - this.skip(2); - return commentToken("/*", body, { isMultiline: true }); - } - }, - - /* - * Extract a keyword out of the next sequence of characters or - * return 'null' if its not possible. - */ - scanKeyword: function () { - var result = /^[a-zA-Z_$][a-zA-Z0-9_$]*/.exec(this.input); - var keywords = [ - "if", "in", "do", "var", "for", "new", - "try", "let", "this", "else", "case", - "void", "with", "enum", "while", "break", - "catch", "throw", "const", "yield", "class", - "super", "return", "typeof", "delete", - "switch", "export", "import", "default", - "finally", "extends", "function", "continue", - "debugger", "instanceof" - ]; - - if (result && keywords.indexOf(result[0]) >= 0) { - return { - type: Token.Keyword, - value: result[0] - }; - } - - return null; - }, - - /* - * Extract a JavaScript identifier out of the next sequence of - * characters or return 'null' if its not possible. In addition, - * to Identifier this method can also produce BooleanLiteral - * (true/false) and NullLiteral (null). - */ - scanIdentifier: function () { - var id = ""; - var index = 0; - var type, char; - - // Detects any character in the Unicode categories "Uppercase - // letter (Lu)", "Lowercase letter (Ll)", "Titlecase letter - // (Lt)", "Modifier letter (Lm)", "Other letter (Lo)", or - // "Letter number (Nl)". - // - // Both approach and unicodeLetterTable were borrowed from - // Google's Traceur. - - function isUnicodeLetter(code) { - for (var i = 0; i < unicodeLetterTable.length;) { - if (code < unicodeLetterTable[i++]) { - return false; - } - - if (code <= unicodeLetterTable[i++]) { - return true; - } - } - - return false; - } - - function isHexDigit(str) { - return (/^[0-9a-fA-F]$/).test(str); - } - - var readUnicodeEscapeSequence = function () { - /*jshint validthis:true */ - index += 1; - - if (this.peek(index) !== "u") { - return null; - } - - var ch1 = this.peek(index + 1); - var ch2 = this.peek(index + 2); - var ch3 = this.peek(index + 3); - var ch4 = this.peek(index + 4); - var code; - - if (isHexDigit(ch1) && isHexDigit(ch2) && isHexDigit(ch3) && isHexDigit(ch4)) { - code = parseInt(ch1 + ch2 + ch3 + ch4, 16); - - if (isUnicodeLetter(code)) { - index += 5; - return "\\u" + ch1 + ch2 + ch3 + ch4; - } - - return null; - } - - return null; - }.bind(this); - - var getIdentifierStart = function () { - /*jshint validthis:true */ - var chr = this.peek(index); - var code = chr.charCodeAt(0); - - if (code === 92) { - return readUnicodeEscapeSequence(); - } - - if (code < 128) { - if (identifierStartTable[code]) { - index += 1; - return chr; - } - - return null; - } - - if (isUnicodeLetter(code)) { - index += 1; - return chr; - } - - return null; - }.bind(this); - - var getIdentifierPart = function () { - /*jshint validthis:true */ - var chr = this.peek(index); - var code = chr.charCodeAt(0); - - if (code === 92) { - return readUnicodeEscapeSequence(); - } - - if (code < 128) { - if (identifierPartTable[code]) { - index += 1; - return chr; - } - - return null; - } - - if (isUnicodeLetter(code)) { - index += 1; - return chr; - } - - return null; - }.bind(this); - - char = getIdentifierStart(); - if (char === null) { - return null; - } - - id = char; - for (;;) { - char = getIdentifierPart(); - - if (char === null) { - break; - } - - id += char; - } - - switch (id) { - case "true": - case "false": - type = Token.BooleanLiteral; - break; - case "null": - type = Token.NullLiteral; - break; - default: - type = Token.Identifier; - } - - return { - type: type, - value: id - }; - }, - - /* - * Extract a numeric literal out of the next sequence of - * characters or return 'null' if its not possible. This method - * supports all numeric literals described in section 7.8.3 - * of the EcmaScript 5 specification. - * - * This method's implementation was heavily influenced by the - * scanNumericLiteral function in the Esprima parser's source code. - */ - scanNumericLiteral: function () { - var index = 0; - var value = ""; - var length = this.input.length; - var char = this.peek(index); - var bad; - - function isDecimalDigit(str) { - return (/^[0-9]$/).test(str); - } - - function isOctalDigit(str) { - return (/^[0-7]$/).test(str); - } - - function isHexDigit(str) { - return (/^[0-9a-fA-F]$/).test(str); - } - - function isIdentifierStart(ch) { - return (ch === "$") || (ch === "_") || (ch === "\\") || - (ch >= "a" && ch <= "z") || (ch >= "A" && ch <= "Z"); - } - - // Numbers must start either with a decimal digit or a point. - - if (char !== "." && !isDecimalDigit(char)) { - return null; - } - - if (char !== ".") { - value = this.peek(index); - index += 1; - char = this.peek(index); - - if (value === "0") { - // Base-16 numbers. - if (char === "x" || char === "X") { - index += 1; - value += char; - - while (index < length) { - char = this.peek(index); - if (!isHexDigit(char)) { - break; - } - value += char; - index += 1; - } - - if (value.length <= 2) { // 0x - return { - type: Token.NumericLiteral, - value: value, - isMalformed: true - }; - } - - if (index < length) { - char = this.peek(index); - if (isIdentifierStart(char)) { - return null; - } - } - - return { - type: Token.NumericLiteral, - value: value, - base: 16, - isMalformed: false - }; - } - - // Base-8 numbers. - if (isOctalDigit(char)) { - index += 1; - value += char; - bad = false; - - while (index < length) { - char = this.peek(index); - - // Numbers like '019' (note the 9) are not valid octals - // but we still parse them and mark as malformed. - - if (isDecimalDigit(char)) { - bad = true; - } else if (!isOctalDigit(char)) { - break; - } - value += char; - index += 1; - } - - if (index < length) { - char = this.peek(index); - if (isIdentifierStart(char)) { - return null; - } - } - - return { - type: Token.NumericLiteral, - value: value, - base: 8, - isMalformed: false - }; - } - - // Decimal numbers that start with '0' such as '09' are illegal - // but we still parse them and return as malformed. - - if (isDecimalDigit(char)) { - index += 1; - value += char; - } - } - - while (index < length) { - char = this.peek(index); - if (!isDecimalDigit(char)) { - break; - } - value += char; - index += 1; - } - } - - // Decimal digits. - - if (char === ".") { - value += char; - index += 1; - - while (index < length) { - char = this.peek(index); - if (!isDecimalDigit(char)) { - break; - } - value += char; - index += 1; - } - } - - // Exponent part. - - if (char === "e" || char === "E") { - value += char; - index += 1; - char = this.peek(index); - - if (char === "+" || char === "-") { - value += this.peek(index); - index += 1; - } - - char = this.peek(index); - if (isDecimalDigit(char)) { - value += char; - index += 1; - - while (index < length) { - char = this.peek(index); - if (!isDecimalDigit(char)) { - break; - } - value += char; - index += 1; - } - } else { - return null; - } - } - - if (index < length) { - char = this.peek(index); - if (isIdentifierStart(char)) { - return null; - } - } - - return { - type: Token.NumericLiteral, - value: value, - base: 10, - isMalformed: !isFinite(value) - }; - }, - - /* - * Extract a string out of the next sequence of characters and/or - * lines or return 'null' if its not possible. Since strings can - * span across multiple lines this method has to move the char - * pointer. - * - * This method recognizes pseudo-multiline JavaScript strings: - * - * var str = "hello\ - * world"; - */ - scanStringLiteral: function (checks) { - /*jshint loopfunc:true */ - var quote = this.peek(); - - // String must start with a quote. - if (quote !== "\"" && quote !== "'") { - return null; - } - - // In JSON strings must always use double quotes. - this.triggerAsync("warning", { - code: "W108", - line: this.line, - character: this.char // +1? - }, checks, function () { return state.jsonMode && quote !== "\""; }); - - var value = ""; - var startLine = this.line; - var startChar = this.char; - var allowNewLine = false; - - this.skip(); - - outer: while (this.peek() !== quote) { - while (this.peek() === "") { // End Of Line - - // If an EOL is not preceded by a backslash, show a warning - // and proceed like it was a legit multi-line string where - // author simply forgot to escape the newline symbol. - // - // Another approach is to implicitly close a string on EOL - // but it generates too many false positives. - - if (!allowNewLine) { - this.trigger("warning", { - code: "W112", - line: this.line, - character: this.char - }); - } else { - allowNewLine = false; - - // Otherwise show a warning if multistr option was not set. - // For JSON, show warning no matter what. - - this.triggerAsync("warning", { - code: "W043", - line: this.line, - character: this.char - }, checks, function () { return !state.option.multistr; }); - - this.triggerAsync("warning", { - code: "W042", - line: this.line, - character: this.char - }, checks, function () { return state.jsonMode && state.option.multistr; }); - } - - // If we get an EOF inside of an unclosed string, show an - // error and implicitly close it at the EOF point. - - if (!this.nextLine()) { - this.trigger("error", { - code: "E029", - line: startLine, - character: startChar - }); - - return { - type: Token.StringLiteral, - value: value, - isUnclosed: true, - quote: quote - }; - } - - if (this.peek() == quote) - break outer; - } - - allowNewLine = false; - var char = this.peek(); - var jump = 1; // A length of a jump, after we're done - // parsing this character. - - if (char < " ") { - // Warn about a control character in a string. - this.trigger("warning", { - code: "W113", - line: this.line, - character: this.char, - data: [ "" ] - }); - } - - // Special treatment for some escaped characters. - - if (char === "\\") { - this.skip(); - char = this.peek(); - - switch (char) { - case "'": - this.triggerAsync("warning", { - code: "W114", - line: this.line, - character: this.char, - data: [ "\\'" ] - }, checks, function () {return state.jsonMode; }); - break; - case "b": - char = "\b"; - break; - case "f": - char = "\f"; - break; - case "n": - char = "\n"; - break; - case "r": - char = "\r"; - break; - case "t": - char = "\t"; - break; - case "0": - char = "\0"; - - // Octal literals fail in strict mode. - // Check if the number is between 00 and 07. - var n = parseInt(this.peek(1), 10); - this.triggerAsync("warning", { - code: "W115", - line: this.line, - character: this.char - }, checks, - function () { return n >= 0 && n <= 7 && state.directive["use strict"]; }); - break; - case "u": - char = String.fromCharCode(parseInt(this.input.substr(1, 4), 16)); - jump = 5; - break; - case "v": - this.triggerAsync("warning", { - code: "W114", - line: this.line, - character: this.char, - data: [ "\\v" ] - }, checks, function () { return state.jsonMode; }); - - char = "\v"; - break; - case "x": - var x = parseInt(this.input.substr(1, 2), 16); - - this.triggerAsync("warning", { - code: "W114", - line: this.line, - character: this.char, - data: [ "\\x-" ] - }, checks, function () { return state.jsonMode; }); - - char = String.fromCharCode(x); - jump = 3; - break; - case "\\": - case "\"": - case "/": - break; - case "": - allowNewLine = true; - char = ""; - break; - case "!": - if (value.slice(value.length - 2) === "<") { - break; - } - - /*falls through */ - default: - // Weird escaping. - this.trigger("warning", { - code: "W044", - line: this.line, - character: this.char - }); - } - } - - value += char; - this.skip(jump); - } - - this.skip(); - return { - type: Token.StringLiteral, - value: value, - isUnclosed: false, - quote: quote - }; - }, - - /* - * Extract a regular expression out of the next sequence of - * characters and/or lines or return 'null' if its not possible. - * - * This method is platform dependent: it accepts almost any - * regular expression values but then tries to compile and run - * them using system's RegExp object. This means that there are - * rare edge cases where one JavaScript engine complains about - * your regular expression while others don't. - */ - scanRegExp: function () { - var index = 0; - var length = this.input.length; - var char = this.peek(); - var value = char; - var body = ""; - var flags = []; - var malformed = false; - var isCharSet = false; - var terminated; - - var scanUnexpectedChars = function () { - // Unexpected control character - if (char < " ") { - malformed = true; - this.trigger("warning", { - code: "W048", - line: this.line, - character: this.char - }); - } - - // Unexpected escaped character - if (char === "<") { - malformed = true; - this.trigger("warning", { - code: "W049", - line: this.line, - character: this.char, - data: [ char ] - }); - } - }.bind(this); - - // Regular expressions must start with '/' - if (!this.prereg || char !== "/") { - return null; - } - - index += 1; - terminated = false; - - // Try to get everything in between slashes. A couple of - // cases aside (see scanUnexpectedChars) we don't really - // care whether the resulting expression is valid or not. - // We will check that later using the RegExp object. - - while (index < length) { - char = this.peek(index); - value += char; - body += char; - - if (isCharSet) { - if (char === "]") { - if (this.peek(index - 1) !== "\\" || this.peek(index - 2) === "\\") { - isCharSet = false; - } - } - - if (char === "\\") { - index += 1; - char = this.peek(index); - body += char; - value += char; - - scanUnexpectedChars(); - } - - index += 1; - continue; - } - - if (char === "\\") { - index += 1; - char = this.peek(index); - body += char; - value += char; - - scanUnexpectedChars(); - - if (char === "/") { - index += 1; - continue; - } - - if (char === "[") { - index += 1; - continue; - } - } - - if (char === "[") { - isCharSet = true; - index += 1; - continue; - } - - if (char === "/") { - body = body.substr(0, body.length - 1); - terminated = true; - index += 1; - break; - } - - index += 1; - } - - // A regular expression that was never closed is an - // error from which we cannot recover. - - if (!terminated) { - this.trigger("error", { - code: "E015", - line: this.line, - character: this.from - }); - - return void this.trigger("fatal", { - line: this.line, - from: this.from - }); - } - - // Parse flags (if any). - - while (index < length) { - char = this.peek(index); - if (!/[gim]/.test(char)) { - break; - } - flags.push(char); - value += char; - index += 1; - } - - // Check regular expression for correctness. - - try { - new RegExp(body, flags.join("")); - } catch (err) { - malformed = true; - this.trigger("error", { - code: "E016", - line: this.line, - character: this.char, - data: [ err.message ] // Platform dependent! - }); - } - - return { - type: Token.RegExp, - value: value, - flags: flags, - isMalformed: malformed - }; - }, - - /* - * Scan for any occurence of mixed tabs and spaces. If smarttabs option - * is on, ignore tabs followed by spaces. - * - * Tabs followed by one space followed by a block comment are allowed. - */ - scanMixedSpacesAndTabs: function () { - var at, match; - - if (state.option.smarttabs) { - // Negative look-behind for "//" - match = this.input.match(/(\/\/|^\s?\*)? \t/); - at = match && !match[1] ? 0 : -1; - } else { - at = this.input.search(/ \t|\t [^\*]/); - } - - return at; - }, - - /* - * Scan for characters that get silently deleted by one or more browsers. - */ - scanUnsafeChars: function () { - return this.input.search(reg.unsafeChars); - }, - - /* - * Produce the next raw token or return 'null' if no tokens can be matched. - * This method skips over all space characters. - */ - next: function (checks) { - this.from = this.char; - - // Move to the next non-space character. - var start; - if (/\s/.test(this.peek())) { - start = this.char; - - while (/\s/.test(this.peek())) { - this.from += 1; - this.skip(); - } - - if (this.peek() === "") { // EOL - if (!/^\s*$/.test(this.getLines()[this.line - 1]) && state.option.trailing) { - this.trigger("warning", { code: "W102", line: this.line, character: start }); - } - } - } - - // Methods that work with multi-line structures and move the - // character pointer. - - var match = this.scanComments() || - this.scanStringLiteral(checks); - - if (match) { - return match; - } - - // Methods that don't move the character pointer. - - match = - this.scanRegExp() || - this.scanPunctuator() || - this.scanKeyword() || - this.scanIdentifier() || - this.scanNumericLiteral(); - - if (match) { - this.skip(match.value.length); - return match; - } - - // No token could be matched, give up. - - return null; - }, - - /* - * Switch to the next line and reset all char pointers. Once - * switched, this method also checks for mixed spaces and tabs - * and other minor warnings. - */ - nextLine: function () { - var char; - - if (this.line >= this.getLines().length) { - return false; - } - - this.input = this.getLines()[this.line]; - this.line += 1; - this.char = 1; - this.from = 1; - - char = this.scanMixedSpacesAndTabs(); - if (char >= 0) { - this.trigger("warning", { code: "W099", line: this.line, character: char + 1 }); - } - - this.input = this.input.replace(/\t/g, state.tab); - char = this.scanUnsafeChars(); - - if (char >= 0) { - this.trigger("warning", { code: "W100", line: this.line, character: char }); - } - - // If there is a limit on line length, warn when lines get too - // long. - - if (state.option.maxlen && state.option.maxlen < this.input.length) { - this.trigger("warning", { code: "W101", line: this.line, character: this.input.length }); - } - - return true; - }, - - /* - * This is simply a synonym for nextLine() method with a friendlier - * public name. - */ - start: function () { - this.nextLine(); - }, - - /* - * Produce the next token. This function is called by advance() to get - * the next token. It retuns a token in a JSLint-compatible format. - */ - token: function () { - /*jshint loopfunc:true */ - var checks = asyncTrigger(); - var token; - - - function isReserved(token, isProperty) { - if (!token.reserved) { - return false; - } - var meta = token.meta; - - if (meta && meta.isFutureReservedWord && state.option.inES5()) { - // ES3 FutureReservedWord in an ES5 environment. - if (!meta.es5) { - return false; - } - - // Some ES5 FutureReservedWord identifiers are active only - // within a strict mode environment. - if (meta.strictOnly) { - if (!state.option.strict && !state.directive["use strict"]) { - return false; - } - } - - if (isProperty) { - return false; - } - } - - return true; - } - - // Produce a token object. - var create = function (type, value, isProperty) { - /*jshint validthis:true */ - var obj; - - if (type !== "(endline)" && type !== "(end)") { - this.prereg = false; - } - - if (type === "(punctuator)") { - switch (value) { - case ".": - case ")": - case "~": - case "#": - case "]": - this.prereg = false; - break; - default: - this.prereg = true; - } - - obj = Object.create(state.syntax[value] || state.syntax["(error)"]); - } - - if (type === "(identifier)") { - if (value === "return" || value === "case" || value === "typeof") { - this.prereg = true; - } - - if (_.has(state.syntax, value)) { - obj = Object.create(state.syntax[value] || state.syntax["(error)"]); - - // If this can't be a reserved keyword, reset the object. - if (!isReserved(obj, isProperty && type === "(identifier)")) { - obj = null; - } - } - } - - if (!obj) { - obj = Object.create(state.syntax[type]); - } - - obj.identifier = (type === "(identifier)"); - obj.type = obj.type || type; - obj.value = value; - obj.line = this.line; - obj.character = this.char; - obj.from = this.from; - - if (isProperty && obj.identifier) { - obj.isProperty = isProperty; - } - - obj.check = checks.check; - - return obj; - }.bind(this); - - for (;;) { - if (!this.input.length) { - return create(this.nextLine() ? "(endline)" : "(end)", ""); - } - - token = this.next(checks); - - if (!token) { - if (this.input.length) { - // Unexpected character. - this.trigger("error", { - code: "E024", - line: this.line, - character: this.char, - data: [ this.peek() ] - }); - - this.input = ""; - } - - continue; - } - - switch (token.type) { - case Token.StringLiteral: - this.triggerAsync("String", { - line: this.line, - char: this.char, - from: this.from, - value: token.value, - quote: token.quote - }, checks, function () { return true; }); - - return create("(string)", token.value); - case Token.Identifier: - this.trigger("Identifier", { - line: this.line, - char: this.char, - from: this.form, - name: token.value, - isProperty: state.tokens.curr.id === "." - }); - - /* falls through */ - case Token.Keyword: - case Token.NullLiteral: - case Token.BooleanLiteral: - return create("(identifier)", token.value, state.tokens.curr.id === "."); - - case Token.NumericLiteral: - if (token.isMalformed) { - this.trigger("warning", { - code: "W045", - line: this.line, - character: this.char, - data: [ token.value ] - }); - } - - this.triggerAsync("warning", { - code: "W114", - line: this.line, - character: this.char, - data: [ "0x-" ] - }, checks, function () { return token.base === 16 && state.jsonMode; }); - - this.triggerAsync("warning", { - code: "W115", - line: this.line, - character: this.char - }, checks, function () { - return state.directive["use strict"] && token.base === 8; - }); - - this.trigger("Number", { - line: this.line, - char: this.char, - from: this.from, - value: token.value, - base: token.base, - isMalformed: token.malformed - }); - - return create("(number)", token.value); - - case Token.RegExp: - return create("(regexp)", token.value); - - case Token.Comment: - state.tokens.curr.comment = true; - - if (token.isSpecial) { - return { - value: token.value, - body: token.body, - type: token.commentType, - isSpecial: token.isSpecial, - line: this.line, - character: this.char, - from: this.from - }; - } - - break; - - case "": - break; - - default: - return create("(punctuator)", token.value); - } - } - } + _lines: [], + + getLines: function () { + this._lines = state.lines; + return this._lines; + }, + + setLines: function (val) { + this._lines = val; + state.lines = this._lines; + }, + + /* + * Return the next i character without actually moving the + * char pointer. + */ + peek: function (i) { + return this.input.charAt(i || 0); + }, + + /* + * Move the char pointer forward i times. + */ + skip: function (i) { + i = i || 1; + this.char += i; + this.input = this.input.slice(i); + }, + + /* + * Subscribe to a token event. The API for this method is similar + * Underscore.js i.e. you can subscribe to multiple events with + * one call: + * + * lex.on("Identifier Number", function (data) { + * // ... + * }); + */ + on: function (names, listener) { + names.split(" ").forEach(function (name) { + this.emitter.on(name, listener); + }.bind(this)); + }, + + /* + * Trigger a token event. All arguments will be passed to each + * listener. + */ + trigger: function () { + this.emitter.emit.apply(this.emitter, Array.prototype.slice.call(arguments)); + }, + + /* + * Postpone a token event. the checking condition is set as + * last parameter, and the trigger function is called in a + * stored callback. To be later called using the check() function + * by the parser. This avoids parser's peek() to give the lexer + * a false context. + */ + triggerAsync: function (type, args, checks, fn) { + checks.push(function () { + if (fn()) { + this.trigger(type, args); + } + }.bind(this)); + }, + + /* + * Extract a punctuator out of the next sequence of characters + * or return 'null' if its not possible. + * + * This method's implementation was heavily influenced by the + * scanPunctuator function in the Esprima parser's source code. + */ + scanPunctuator: function () { + var ch1 = this.peek(); + var ch2, ch3, ch4; + + switch (ch1) { + // Most common single-character punctuators + case ".": + if ((/^[0-9]$/).test(this.peek(1))) { + return null; + } + if (this.peek(1) === "." && this.peek(2) === ".") { + return { + type: Token.Punctuator, + value: "..." + }; + } + /* falls through */ + case "(": + case ")": + case ";": + case ",": + case "{": + case "}": + case "[": + case "]": + case ":": + case "~": + case "?": + return { + type: Token.Punctuator, + value: ch1 + }; + + // A pound sign (for Node shebangs) + case "#": + return { + type: Token.Punctuator, + value: ch1 + }; + + // We're at the end of input + case "": + return null; + } + + // Peek more characters + + ch2 = this.peek(1); + ch3 = this.peek(2); + ch4 = this.peek(3); + + // 4-character punctuator: >>>= + + if (ch1 === ">" && ch2 === ">" && ch3 === ">" && ch4 === "=") { + return { + type: Token.Punctuator, + value: ">>>=" + }; + } + + // 3-character punctuators: === !== >>> <<= >>= + + if (ch1 === "=" && ch2 === "=" && ch3 === "=") { + return { + type: Token.Punctuator, + value: "===" + }; + } + + if (ch1 === "!" && ch2 === "=" && ch3 === "=") { + return { + type: Token.Punctuator, + value: "!==" + }; + } + + if (ch1 === ">" && ch2 === ">" && ch3 === ">") { + return { + type: Token.Punctuator, + value: ">>>" + }; + } + + if (ch1 === "<" && ch2 === "<" && ch3 === "=") { + return { + type: Token.Punctuator, + value: "<<=" + }; + } + + if (ch1 === ">" && ch2 === ">" && ch3 === "=") { + return { + type: Token.Punctuator, + value: ">>=" + }; + } + + // Fat arrow punctuator + if (ch1 === "=" && ch2 === ">") { + return { + type: Token.Punctuator, + value: ch1 + ch2 + }; + } + + // 2-character punctuators: <= >= == != ++ -- << >> && || + // += -= *= %= &= |= ^= (but not /=, see below) + if (ch1 === ch2 && ("+-<>&|".indexOf(ch1) >= 0)) { + return { + type: Token.Punctuator, + value: ch1 + ch2 + }; + } + + if ("<>=!+-*%&|^".indexOf(ch1) >= 0) { + if (ch2 === "=") { + return { + type: Token.Punctuator, + value: ch1 + ch2 + }; + } + + return { + type: Token.Punctuator, + value: ch1 + }; + } + + // Special case: /=. We need to make sure that this is an + // operator and not a regular expression. + + if (ch1 === "/") { + if (ch2 === "=" && /\/=(?!(\S*\/[gim]?))/.test(this.input)) { + // /= is not a part of a regular expression, return it as a + // punctuator. + return { + type: Token.Punctuator, + value: "/=" + }; + } + + return { + type: Token.Punctuator, + value: "/" + }; + } + + return null; + }, + + /* + * Extract a comment out of the next sequence of characters and/or + * lines or return 'null' if its not possible. Since comments can + * span across multiple lines this method has to move the char + * pointer. + * + * In addition to normal JavaScript comments (// and /*) this method + * also recognizes JSHint- and JSLint-specific comments such as + * /*jshint, /*jslint, /*globals and so on. + */ + scanComments: function () { + var ch1 = this.peek(); + var ch2 = this.peek(1); + var rest = this.input.substr(2); + var startLine = this.line; + var startChar = this.char; + + // Create a comment token object and make sure it + // has all the data JSHint needs to work with special + // comments. + + function commentToken(label, body, opt) { + var special = ["jshint", "jslint", "members", "member", "globals", "global", "exported"]; + var isSpecial = false; + var value = label + body; + var commentType = "plain"; + opt = opt || {}; + + if (opt.isMultiline) { + value += "*/"; + } + + special.forEach(function (str) { + if (isSpecial) { + return; + } + + // Don't recognize any special comments other than jshint for single-line + // comments. This introduced many problems with legit comments. + if (label === "//" && str !== "jshint") { + return; + } + + if (body.substr(0, str.length) === str) { + isSpecial = true; + label = label + str; + body = body.substr(str.length); + } + + if (!isSpecial && body.charAt(0) === " " && body.substr(1, str.length) === str) { + isSpecial = true; + label = label + " " + str; + body = body.substr(str.length + 1); + } + + if (!isSpecial) { + return; + } + + switch (str) { + case "member": + commentType = "members"; + break; + case "global": + commentType = "globals"; + break; + default: + commentType = str; + } + }); + + return { + type: Token.Comment, + commentType: commentType, + value: value, + body: body, + isSpecial: isSpecial, + isMultiline: opt.isMultiline || false, + isMalformed: opt.isMalformed || false + }; + } + + // End of unbegun comment. Raise an error and skip that input. + if (ch1 === "*" && ch2 === "/") { + this.trigger("error", { + code: "E018", + line: startLine, + character: startChar + }); + + this.skip(2); + return null; + } + + // Comments must start either with // or /* + if (ch1 !== "/" || (ch2 !== "*" && ch2 !== "/")) { + return null; + } + + // One-line comment + if (ch2 === "/") { + this.skip(this.input.length); // Skip to the EOL. + return commentToken("//", rest); + } + + var body = ""; + + /* Multi-line comment */ + if (ch2 === "*") { + this.inComment = true; + this.skip(2); + + while (this.peek() !== "*" || this.peek(1) !== "/") { + if (this.peek() === "") { // End of Line + body += "\n"; + + // If we hit EOF and our comment is still unclosed, + // trigger an error and end the comment implicitly. + if (!this.nextLine()) { + this.trigger("error", { + code: "E017", + line: startLine, + character: startChar + }); + + this.inComment = false; + return commentToken("/*", body, { + isMultiline: true, + isMalformed: true + }); + } + } else { + body += this.peek(); + this.skip(); + } + } + + this.skip(2); + this.inComment = false; + return commentToken("/*", body, { isMultiline: true }); + } + }, + + /* + * Extract a keyword out of the next sequence of characters or + * return 'null' if its not possible. + */ + scanKeyword: function () { + var result = /^[a-zA-Z_$][a-zA-Z0-9_$]*/.exec(this.input); + var keywords = [ + "if", "in", "do", "var", "for", "new", + "try", "let", "this", "else", "case", + "void", "with", "enum", "while", "break", + "catch", "throw", "const", "yield", "class", + "super", "return", "typeof", "delete", + "switch", "export", "import", "default", + "finally", "extends", "function", "continue", + "debugger", "instanceof" + ]; + + if (result && keywords.indexOf(result[0]) >= 0) { + return { + type: Token.Keyword, + value: result[0] + }; + } + + return null; + }, + + /* + * Extract a JavaScript identifier out of the next sequence of + * characters or return 'null' if its not possible. In addition, + * to Identifier this method can also produce BooleanLiteral + * (true/false) and NullLiteral (null). + */ + scanIdentifier: function () { + var id = ""; + var index = 0; + var type, char; + + function isNonAsciiIdentifierStart(code) { + return code > 256; + } + + function isNonAsciiIdentifierPart(code) { + return code > 256; + } + + function isHexDigit(str) { + return (/^[0-9a-fA-F]$/).test(str); + } + + var readUnicodeEscapeSequence = function () { + /*jshint validthis:true */ + index += 1; + + if (this.peek(index) !== "u") { + return null; + } + + var ch1 = this.peek(index + 1); + var ch2 = this.peek(index + 2); + var ch3 = this.peek(index + 3); + var ch4 = this.peek(index + 4); + var code; + + if (isHexDigit(ch1) && isHexDigit(ch2) && isHexDigit(ch3) && isHexDigit(ch4)) { + code = parseInt(ch1 + ch2 + ch3 + ch4, 16); + + if (asciiIdentifierPartTable[code] || isNonAsciiIdentifierPart(code)) { + index += 5; + return "\\u" + ch1 + ch2 + ch3 + ch4; + } + + return null; + } + + return null; + }.bind(this); + + var getIdentifierStart = function () { + /*jshint validthis:true */ + var chr = this.peek(index); + var code = chr.charCodeAt(0); + + if (code === 92) { + return readUnicodeEscapeSequence(); + } + + if (code < 128) { + if (asciiIdentifierStartTable[code]) { + index += 1; + return chr; + } + + return null; + } + + if (isNonAsciiIdentifierStart(code)) { + index += 1; + return chr; + } + + return null; + }.bind(this); + + var getIdentifierPart = function () { + /*jshint validthis:true */ + var chr = this.peek(index); + var code = chr.charCodeAt(0); + + if (code === 92) { + return readUnicodeEscapeSequence(); + } + + if (code < 128) { + if (asciiIdentifierPartTable[code]) { + index += 1; + return chr; + } + + return null; + } + + if (isNonAsciiIdentifierPart(code)) { + index += 1; + return chr; + } + + return null; + }.bind(this); + + char = getIdentifierStart(); + if (char === null) { + return null; + } + + id = char; + for (;;) { + char = getIdentifierPart(); + + if (char === null) { + break; + } + + id += char; + } + + switch (id) { + case "true": + case "false": + type = Token.BooleanLiteral; + break; + case "null": + type = Token.NullLiteral; + break; + default: + type = Token.Identifier; + } + + return { + type: type, + value: id + }; + }, + + /* + * Extract a numeric literal out of the next sequence of + * characters or return 'null' if its not possible. This method + * supports all numeric literals described in section 7.8.3 + * of the EcmaScript 5 specification. + * + * This method's implementation was heavily influenced by the + * scanNumericLiteral function in the Esprima parser's source code. + */ + scanNumericLiteral: function () { + var index = 0; + var value = ""; + var length = this.input.length; + var char = this.peek(index); + var bad; + + function isDecimalDigit(str) { + return (/^[0-9]$/).test(str); + } + + function isOctalDigit(str) { + return (/^[0-7]$/).test(str); + } + + function isHexDigit(str) { + return (/^[0-9a-fA-F]$/).test(str); + } + + function isIdentifierStart(ch) { + return (ch === "$") || (ch === "_") || (ch === "\\") || + (ch >= "a" && ch <= "z") || (ch >= "A" && ch <= "Z"); + } + + // Numbers must start either with a decimal digit or a point. + + if (char !== "." && !isDecimalDigit(char)) { + return null; + } + + if (char !== ".") { + value = this.peek(index); + index += 1; + char = this.peek(index); + + if (value === "0") { + // Base-16 numbers. + if (char === "x" || char === "X") { + index += 1; + value += char; + + while (index < length) { + char = this.peek(index); + if (!isHexDigit(char)) { + break; + } + value += char; + index += 1; + } + + if (value.length <= 2) { // 0x + return { + type: Token.NumericLiteral, + value: value, + isMalformed: true + }; + } + + if (index < length) { + char = this.peek(index); + if (isIdentifierStart(char)) { + return null; + } + } + + return { + type: Token.NumericLiteral, + value: value, + base: 16, + isMalformed: false + }; + } + + // Base-8 numbers. + if (isOctalDigit(char)) { + index += 1; + value += char; + bad = false; + + while (index < length) { + char = this.peek(index); + + // Numbers like '019' (note the 9) are not valid octals + // but we still parse them and mark as malformed. + + if (isDecimalDigit(char)) { + bad = true; + } else if (!isOctalDigit(char)) { + break; + } + value += char; + index += 1; + } + + if (index < length) { + char = this.peek(index); + if (isIdentifierStart(char)) { + return null; + } + } + + return { + type: Token.NumericLiteral, + value: value, + base: 8, + isMalformed: false + }; + } + + // Decimal numbers that start with '0' such as '09' are illegal + // but we still parse them and return as malformed. + + if (isDecimalDigit(char)) { + index += 1; + value += char; + } + } + + while (index < length) { + char = this.peek(index); + if (!isDecimalDigit(char)) { + break; + } + value += char; + index += 1; + } + } + + // Decimal digits. + + if (char === ".") { + value += char; + index += 1; + + while (index < length) { + char = this.peek(index); + if (!isDecimalDigit(char)) { + break; + } + value += char; + index += 1; + } + } + + // Exponent part. + + if (char === "e" || char === "E") { + value += char; + index += 1; + char = this.peek(index); + + if (char === "+" || char === "-") { + value += this.peek(index); + index += 1; + } + + char = this.peek(index); + if (isDecimalDigit(char)) { + value += char; + index += 1; + + while (index < length) { + char = this.peek(index); + if (!isDecimalDigit(char)) { + break; + } + value += char; + index += 1; + } + } else { + return null; + } + } + + if (index < length) { + char = this.peek(index); + if (isIdentifierStart(char)) { + return null; + } + } + + return { + type: Token.NumericLiteral, + value: value, + base: 10, + isMalformed: !isFinite(value) + }; + }, + + /* + * Extract a template literal out of the next sequence of characters + * and/or lines or return 'null' if its not possible. Since template + * literals can span across multiple lines, this method has to move + * the char pointer. + */ + scanTemplateLiteral: function () { + // String must start with a backtick. + if (!state.option.esnext || this.peek() !== "`") { + return null; + } + + var startLine = this.line; + var startChar = this.char; + var jump = 1; + var value = ""; + + // For now, do not perform any linting of the content of the template + // string. Just skip until the next backtick is found. + this.skip(); + + while (this.peek() !== "`") { + while (this.peek() === "") { + // End of line --- For template literals in ES6, no backslash is + // required to precede newlines. + if (!this.nextLine()) { + this.trigger("error", { + code: "E052", + line: startLine, + character: startChar + }); + + return { + type: Token.TemplateLiteral, + value: value, + isUnclosed: true + }; + } + value += "\n"; + } + + // TODO: do more interesting linting here, similar to string literal + // linting. + var char = this.peek(); + this.skip(jump); + value += char; + } + + this.skip(); + return { + type: Token.TemplateLiteral, + value: value, + isUnclosed: false + }; + }, + + /* + * Extract a string out of the next sequence of characters and/or + * lines or return 'null' if its not possible. Since strings can + * span across multiple lines this method has to move the char + * pointer. + * + * This method recognizes pseudo-multiline JavaScript strings: + * + * var str = "hello\ + * world"; + */ + scanStringLiteral: function (checks) { + /*jshint loopfunc:true */ + var quote = this.peek(); + + // String must start with a quote. + if (quote !== "\"" && quote !== "'") { + return null; + } + + // In JSON strings must always use double quotes. + this.triggerAsync("warning", { + code: "W108", + line: this.line, + character: this.char // +1? + }, checks, function () { return state.jsonMode && quote !== "\""; }); + + var value = ""; + var startLine = this.line; + var startChar = this.char; + var allowNewLine = false; + + this.skip(); + + outer: while (this.peek() !== quote) { + while (this.peek() === "") { // End Of Line + + // If an EOL is not preceded by a backslash, show a warning + // and proceed like it was a legit multi-line string where + // author simply forgot to escape the newline symbol. + // + // Another approach is to implicitly close a string on EOL + // but it generates too many false positives. + + if (!allowNewLine) { + this.trigger("warning", { + code: "W112", + line: this.line, + character: this.char + }); + } else { + allowNewLine = false; + + // Otherwise show a warning if multistr option was not set. + // For JSON, show warning no matter what. + + this.triggerAsync("warning", { + code: "W043", + line: this.line, + character: this.char + }, checks, function () { return !state.option.multistr; }); + + this.triggerAsync("warning", { + code: "W042", + line: this.line, + character: this.char + }, checks, function () { return state.jsonMode && state.option.multistr; }); + } + + // If we get an EOF inside of an unclosed string, show an + // error and implicitly close it at the EOF point. + + if (!this.nextLine()) { + this.trigger("error", { + code: "E029", + line: startLine, + character: startChar + }); + + return { + type: Token.StringLiteral, + value: value, + isUnclosed: true, + quote: quote + }; + } + + if (this.peek() == quote) + break outer; + } + + allowNewLine = false; + var char = this.peek(); + var jump = 1; // A length of a jump, after we're done + // parsing this character. + + if (char < " ") { + // Warn about a control character in a string. + this.trigger("warning", { + code: "W113", + line: this.line, + character: this.char, + data: [ "" ] + }); + } + + // Special treatment for some escaped characters. + + if (char === "\\") { + this.skip(); + char = this.peek(); + + switch (char) { + case "'": + this.triggerAsync("warning", { + code: "W114", + line: this.line, + character: this.char, + data: [ "\\'" ] + }, checks, function () {return state.jsonMode; }); + break; + case "b": + char = "\\b"; + break; + case "f": + char = "\\f"; + break; + case "n": + char = "\\n"; + break; + case "r": + char = "\\r"; + break; + case "t": + char = "\\t"; + break; + case "0": + char = "\\0"; + + // Octal literals fail in strict mode. + // Check if the number is between 00 and 07. + var n = parseInt(this.peek(1), 10); + this.triggerAsync("warning", { + code: "W115", + line: this.line, + character: this.char + }, checks, + function () { return n >= 0 && n <= 7 && state.directive["use strict"]; }); + break; + case "u": + char = String.fromCharCode(parseInt(this.input.substr(1, 4), 16)); + jump = 5; + break; + case "v": + this.triggerAsync("warning", { + code: "W114", + line: this.line, + character: this.char, + data: [ "\\v" ] + }, checks, function () { return state.jsonMode; }); + + char = "\v"; + break; + case "x": + var x = parseInt(this.input.substr(1, 2), 16); + + this.triggerAsync("warning", { + code: "W114", + line: this.line, + character: this.char, + data: [ "\\x-" ] + }, checks, function () { return state.jsonMode; }); + + char = String.fromCharCode(x); + jump = 3; + break; + case "\\": + char = "\\\\"; + break; + case "\"": + char = "\\\""; + break; + case "/": + break; + case "": + allowNewLine = true; + char = ""; + break; + case "!": + if (value.slice(value.length - 2) === "<") { + break; + } + + /*falls through */ + default: + // Weird escaping. + this.trigger("warning", { + code: "W044", + line: this.line, + character: this.char + }); + } + } + + value += char; + this.skip(jump); + } + + this.skip(); + return { + type: Token.StringLiteral, + value: value, + isUnclosed: false, + quote: quote + }; + }, + + /* + * Extract a regular expression out of the next sequence of + * characters and/or lines or return 'null' if its not possible. + * + * This method is platform dependent: it accepts almost any + * regular expression values but then tries to compile and run + * them using system's RegExp object. This means that there are + * rare edge cases where one JavaScript engine complains about + * your regular expression while others don't. + */ + scanRegExp: function () { + var index = 0; + var length = this.input.length; + var char = this.peek(); + var value = char; + var body = ""; + var flags = []; + var malformed = false; + var isCharSet = false; + var terminated; + + var scanUnexpectedChars = function () { + // Unexpected control character + if (char < " ") { + malformed = true; + this.trigger("warning", { + code: "W048", + line: this.line, + character: this.char + }); + } + + // Unexpected escaped character + if (char === "<") { + malformed = true; + this.trigger("warning", { + code: "W049", + line: this.line, + character: this.char, + data: [ char ] + }); + } + }.bind(this); + + // Regular expressions must start with '/' + if (!this.prereg || char !== "/") { + return null; + } + + index += 1; + terminated = false; + + // Try to get everything in between slashes. A couple of + // cases aside (see scanUnexpectedChars) we don't really + // care whether the resulting expression is valid or not. + // We will check that later using the RegExp object. + + while (index < length) { + char = this.peek(index); + value += char; + body += char; + + if (isCharSet) { + if (char === "]") { + if (this.peek(index - 1) !== "\\" || this.peek(index - 2) === "\\") { + isCharSet = false; + } + } + + if (char === "\\") { + index += 1; + char = this.peek(index); + body += char; + value += char; + + scanUnexpectedChars(); + } + + index += 1; + continue; + } + + if (char === "\\") { + index += 1; + char = this.peek(index); + body += char; + value += char; + + scanUnexpectedChars(); + + if (char === "/") { + index += 1; + continue; + } + + if (char === "[") { + index += 1; + continue; + } + } + + if (char === "[") { + isCharSet = true; + index += 1; + continue; + } + + if (char === "/") { + body = body.substr(0, body.length - 1); + terminated = true; + index += 1; + break; + } + + index += 1; + } + + // A regular expression that was never closed is an + // error from which we cannot recover. + + if (!terminated) { + this.trigger("error", { + code: "E015", + line: this.line, + character: this.from + }); + + return void this.trigger("fatal", { + line: this.line, + from: this.from + }); + } + + // Parse flags (if any). + + while (index < length) { + char = this.peek(index); + if (!/[gim]/.test(char)) { + break; + } + flags.push(char); + value += char; + index += 1; + } + + // Check regular expression for correctness. + + try { + new RegExp(body, flags.join("")); + } catch (err) { + malformed = true; + this.trigger("error", { + code: "E016", + line: this.line, + character: this.char, + data: [ err.message ] // Platform dependent! + }); + } + + return { + type: Token.RegExp, + value: value, + flags: flags, + isMalformed: malformed + }; + }, + + /* + * Scan for any occurence of non-breaking spaces. Non-breaking spaces + * can be mistakenly typed on OS X with option-space. Non UTF-8 web + * pages with non-breaking pages produce syntax errors. + */ + scanNonBreakingSpaces: function () { + return state.option.nonbsp ? + this.input.search(/(\u00A0)/) : -1; + }, + + /* + * Scan for characters that get silently deleted by one or more browsers. + */ + scanUnsafeChars: function () { + return this.input.search(reg.unsafeChars); + }, + + /* + * Produce the next raw token or return 'null' if no tokens can be matched. + * This method skips over all space characters. + */ + next: function (checks) { + this.from = this.char; + + // Move to the next non-space character. + var start; + if (/\s/.test(this.peek())) { + start = this.char; + + while (/\s/.test(this.peek())) { + this.from += 1; + this.skip(); + } + } + + // Methods that work with multi-line structures and move the + // character pointer. + + var match = this.scanComments() || + this.scanStringLiteral(checks) || + this.scanTemplateLiteral(); + + if (match) { + return match; + } + + // Methods that don't move the character pointer. + + match = + this.scanRegExp() || + this.scanPunctuator() || + this.scanKeyword() || + this.scanIdentifier() || + this.scanNumericLiteral(); + + if (match) { + this.skip(match.value.length); + return match; + } + + // No token could be matched, give up. + + return null; + }, + + /* + * Switch to the next line and reset all char pointers. Once + * switched, this method also checks for other minor warnings. + */ + nextLine: function () { + var char; + + if (this.line >= this.getLines().length) { + return false; + } + + this.input = this.getLines()[this.line]; + this.line += 1; + this.char = 1; + this.from = 1; + + var inputTrimmed = this.input.trim(); + + var startsWith = function () { + return _.some(arguments, function (prefix) { + return inputTrimmed.indexOf(prefix) === 0; + }); + }; + + var endsWith = function () { + return _.some(arguments, function (suffix) { + return inputTrimmed.indexOf(suffix, inputTrimmed.length - suffix.length) !== -1; + }); + }; + + // If we are ignoring linter errors, replace the input with empty string + // if it doesn't already at least start or end a multi-line comment + if (state.ignoreLinterErrors === true) { + if (!startsWith("/*", "//") && !endsWith("*/")) { + this.input = ""; + } + } + + char = this.scanNonBreakingSpaces(); + if (char >= 0) { + this.trigger("warning", { code: "W125", line: this.line, character: char + 1 }); + } + + this.input = this.input.replace(/\t/g, state.tab); + char = this.scanUnsafeChars(); + + if (char >= 0) { + this.trigger("warning", { code: "W100", line: this.line, character: char }); + } + + // If there is a limit on line length, warn when lines get too + // long. + + if (state.option.maxlen && state.option.maxlen < this.input.length) { + var inComment = this.inComment || + startsWith.call(inputTrimmed, "//") || + startsWith.call(inputTrimmed, "/*"); + + var shouldTriggerError = !inComment || !reg.maxlenException.test(inputTrimmed); + + if (shouldTriggerError) { + this.trigger("warning", { code: "W101", line: this.line, character: this.input.length }); + } + } + + return true; + }, + + /* + * This is simply a synonym for nextLine() method with a friendlier + * public name. + */ + start: function () { + this.nextLine(); + }, + + /* + * Produce the next token. This function is called by advance() to get + * the next token. It retuns a token in a JSLint-compatible format. + */ + token: function () { + /*jshint loopfunc:true */ + var checks = asyncTrigger(); + var token; + + + function isReserved(token, isProperty) { + if (!token.reserved) { + return false; + } + var meta = token.meta; + + if (meta && meta.isFutureReservedWord && state.option.inES5()) { + // ES3 FutureReservedWord in an ES5 environment. + if (!meta.es5) { + return false; + } + + // Some ES5 FutureReservedWord identifiers are active only + // within a strict mode environment. + if (meta.strictOnly) { + if (!state.option.strict && !state.directive["use strict"]) { + return false; + } + } + + if (isProperty) { + return false; + } + } + + return true; + } + + // Produce a token object. + var create = function (type, value, isProperty) { + /*jshint validthis:true */ + var obj; + + if (type !== "(endline)" && type !== "(end)") { + this.prereg = false; + } + + if (type === "(punctuator)") { + switch (value) { + case ".": + case ")": + case "~": + case "#": + case "]": + this.prereg = false; + break; + default: + this.prereg = true; + } + + obj = Object.create(state.syntax[value] || state.syntax["(error)"]); + } + + if (type === "(identifier)") { + if (value === "return" || value === "case" || value === "typeof") { + this.prereg = true; + } + + if (_.has(state.syntax, value)) { + obj = Object.create(state.syntax[value] || state.syntax["(error)"]); + + // If this can't be a reserved keyword, reset the object. + if (!isReserved(obj, isProperty && type === "(identifier)")) { + obj = null; + } + } + } + + if (!obj) { + obj = Object.create(state.syntax[type]); + } + + obj.identifier = (type === "(identifier)"); + obj.type = obj.type || type; + obj.value = value; + obj.line = this.line; + obj.character = this.char; + obj.from = this.from; + + if (isProperty && obj.identifier) { + obj.isProperty = isProperty; + } + + obj.check = checks.check; + + return obj; + }.bind(this); + + for (;;) { + if (!this.input.length) { + return create(this.nextLine() ? "(endline)" : "(end)", ""); + } + + token = this.next(checks); + + if (!token) { + if (this.input.length) { + // Unexpected character. + this.trigger("error", { + code: "E024", + line: this.line, + character: this.char, + data: [ this.peek() ] + }); + + this.input = ""; + } + + continue; + } + + switch (token.type) { + case Token.StringLiteral: + this.triggerAsync("String", { + line: this.line, + char: this.char, + from: this.from, + value: token.value, + quote: token.quote + }, checks, function () { return true; }); + + return create("(string)", token.value); + + case Token.TemplateLiteral: + this.trigger("Template", { + line: this.line, + char: this.char, + from: this.from, + value: token.value + }); + return create("(template)", token.value); + + case Token.Identifier: + this.trigger("Identifier", { + line: this.line, + char: this.char, + from: this.form, + name: token.value, + isProperty: state.tokens.curr.id === "." + }); + + /* falls through */ + case Token.Keyword: + case Token.NullLiteral: + case Token.BooleanLiteral: + return create("(identifier)", token.value, state.tokens.curr.id === "."); + + case Token.NumericLiteral: + if (token.isMalformed) { + this.trigger("warning", { + code: "W045", + line: this.line, + character: this.char, + data: [ token.value ] + }); + } + + this.triggerAsync("warning", { + code: "W114", + line: this.line, + character: this.char, + data: [ "0x-" ] + }, checks, function () { return token.base === 16 && state.jsonMode; }); + + this.triggerAsync("warning", { + code: "W115", + line: this.line, + character: this.char + }, checks, function () { + return state.directive["use strict"] && token.base === 8; + }); + + this.trigger("Number", { + line: this.line, + char: this.char, + from: this.from, + value: token.value, + base: token.base, + isMalformed: token.malformed + }); + + return create("(number)", token.value); + + case Token.RegExp: + return create("(regexp)", token.value); + + case Token.Comment: + state.tokens.curr.comment = true; + + if (token.isSpecial) { + return { + id: '(comment)', + value: token.value, + body: token.body, + type: token.commentType, + isSpecial: token.isSpecial, + line: this.line, + character: this.char, + from: this.from + }; + } + + break; + + case "": + break; + + default: + return create("(punctuator)", token.value); + } + } + } }; exports.Lexer = Lexer; }, -{"./reg.js":6,"./state.js":7,"events":10,"underscore":1}], -6:[function(req,module,exports){ +{"../data/ascii-identifier-data.js":1,"./reg.js":6,"./state.js":7,"events":10,"underscore":2}], +5:[function(_dereq_,module,exports){ +"use strict"; + +var _ = _dereq_("underscore"); + +var errors = { + // JSHint options + E001: "Bad option: '{a}'.", + E002: "Bad option value.", + + // JSHint input + E003: "Expected a JSON value.", + E004: "Input is neither a string nor an array of strings.", + E005: "Input is empty.", + E006: "Unexpected early end of program.", + + // Strict mode + E007: "Missing \"use strict\" statement.", + E008: "Strict violation.", + E009: "Option 'validthis' can't be used in a global scope.", + E010: "'with' is not allowed in strict mode.", + + // Constants + E011: "const '{a}' has already been declared.", + E012: "const '{a}' is initialized to 'undefined'.", + E013: "Attempting to override '{a}' which is a constant.", + + // Regular expressions + E014: "A regular expression literal can be confused with '/='.", + E015: "Unclosed regular expression.", + E016: "Invalid regular expression.", + + // Tokens + E017: "Unclosed comment.", + E018: "Unbegun comment.", + E019: "Unmatched '{a}'.", + E020: "Expected '{a}' to match '{b}' from line {c} and instead saw '{d}'.", + E021: "Expected '{a}' and instead saw '{b}'.", + E022: "Line breaking error '{a}'.", + E023: "Missing '{a}'.", + E024: "Unexpected '{a}'.", + E025: "Missing ':' on a case clause.", + E026: "Missing '}' to match '{' from line {a}.", + E027: "Missing ']' to match '[' from line {a}.", + E028: "Illegal comma.", + E029: "Unclosed string.", + + // Everything else + E030: "Expected an identifier and instead saw '{a}'.", + E031: "Bad assignment.", // FIXME: Rephrase + E032: "Expected a small integer or 'false' and instead saw '{a}'.", + E033: "Expected an operator and instead saw '{a}'.", + E034: "get/set are ES5 features.", + E035: "Missing property name.", + E036: "Expected to see a statement and instead saw a block.", + E037: null, + E038: null, + E039: "Function declarations are not invocable. Wrap the whole function invocation in parens.", + E040: "Each value should have its own case label.", + E041: "Unrecoverable syntax error.", + E042: "Stopping.", + E043: "Too many errors.", + E044: null, + E045: "Invalid for each loop.", + E046: "A yield statement shall be within a generator function (with syntax: `function*`)", + E047: null, // Vacant + E048: "Let declaration not directly within block.", + E049: "A {a} cannot be named '{b}'.", + E050: "Mozilla requires the yield expression to be parenthesized here.", + E051: "Regular parameters cannot come after default parameters.", + E052: "Unclosed template literal." +}; + +var warnings = { + W001: "'hasOwnProperty' is a really bad name.", + W002: "Value of '{a}' may be overwritten in IE 8 and earlier.", + W003: "'{a}' was used before it was defined.", + W004: "'{a}' is already defined.", + W005: "A dot following a number can be confused with a decimal point.", + W006: "Confusing minuses.", + W007: "Confusing plusses.", + W008: "A leading decimal point can be confused with a dot: '{a}'.", + W009: "The array literal notation [] is preferable.", + W010: "The object literal notation {} is preferable.", + W011: null, + W012: null, + W013: null, + W014: "Bad line breaking before '{a}'.", + W015: null, + W016: "Unexpected use of '{a}'.", + W017: "Bad operand.", + W018: "Confusing use of '{a}'.", + W019: "Use the isNaN function to compare with NaN.", + W020: "Read only.", + W021: "'{a}' is a function.", + W022: "Do not assign to the exception parameter.", + W023: "Expected an identifier in an assignment and instead saw a function invocation.", + W024: "Expected an identifier and instead saw '{a}' (a reserved word).", + W025: "Missing name in function declaration.", + W026: "Inner functions should be listed at the top of the outer function.", + W027: "Unreachable '{a}' after '{b}'.", + W028: "Label '{a}' on {b} statement.", + W030: "Expected an assignment or function call and instead saw an expression.", + W031: "Do not use 'new' for side effects.", + W032: "Unnecessary semicolon.", + W033: "Missing semicolon.", + W034: "Unnecessary directive \"{a}\".", + W035: "Empty block.", + W036: "Unexpected /*member '{a}'.", + W037: "'{a}' is a statement label.", + W038: "'{a}' used out of scope.", + W039: "'{a}' is not allowed.", + W040: "Possible strict violation.", + W041: "Use '{a}' to compare with '{b}'.", + W042: "Avoid EOL escaping.", + W043: "Bad escaping of EOL. Use option multistr if needed.", + W044: "Bad or unnecessary escaping.", + W045: "Bad number '{a}'.", + W046: "Don't use extra leading zeros '{a}'.", + W047: "A trailing decimal point can be confused with a dot: '{a}'.", + W048: "Unexpected control character in regular expression.", + W049: "Unexpected escaped character '{a}' in regular expression.", + W050: "JavaScript URL.", + W051: "Variables should not be deleted.", + W052: "Unexpected '{a}'.", + W053: "Do not use {a} as a constructor.", + W054: "The Function constructor is a form of eval.", + W055: "A constructor name should start with an uppercase letter.", + W056: "Bad constructor.", + W057: "Weird construction. Is 'new' necessary?", + W058: "Missing '()' invoking a constructor.", + W059: "Avoid arguments.{a}.", + W060: "document.write can be a form of eval.", + W061: "eval can be harmful.", + W062: "Wrap an immediate function invocation in parens " + + "to assist the reader in understanding that the expression " + + "is the result of a function, and not the function itself.", + W063: "Math is not a function.", + W064: "Missing 'new' prefix when invoking a constructor.", + W065: "Missing radix parameter.", + W066: "Implied eval. Consider passing a function instead of a string.", + W067: "Bad invocation.", + W068: "Wrapping non-IIFE function literals in parens is unnecessary.", + W069: "['{a}'] is better written in dot notation.", + W070: "Extra comma. (it breaks older versions of IE)", + W071: "This function has too many statements. ({a})", + W072: "This function has too many parameters. ({a})", + W073: "Blocks are nested too deeply. ({a})", + W074: "This function's cyclomatic complexity is too high. ({a})", + W075: "Duplicate key '{a}'.", + W076: "Unexpected parameter '{a}' in get {b} function.", + W077: "Expected a single parameter in set {a} function.", + W078: "Setter is defined without getter.", + W079: "Redefinition of '{a}'.", + W080: "It's not necessary to initialize '{a}' to 'undefined'.", + W081: null, + W082: "Function declarations should not be placed in blocks. " + + "Use a function expression or move the statement to the top of " + + "the outer function.", + W083: "Don't make functions within a loop.", + W084: "Assignment in conditional expression", + W085: "Don't use 'with'.", + W086: "Expected a 'break' statement before '{a}'.", + W087: "Forgotten 'debugger' statement?", + W088: "Creating global 'for' variable. Should be 'for (var {a} ...'.", + W089: "The body of a for in should be wrapped in an if statement to filter " + + "unwanted properties from the prototype.", + W090: "'{a}' is not a statement label.", + W091: "'{a}' is out of scope.", + W093: "Did you mean to return a conditional instead of an assignment?", + W094: "Unexpected comma.", + W095: "Expected a string and instead saw {a}.", + W096: "The '{a}' key may produce unexpected results.", + W097: "Use the function form of \"use strict\".", + W098: "'{a}' is defined but never used.", + W099: null, + W100: "This character may get silently deleted by one or more browsers.", + W101: "Line is too long.", + W102: null, + W103: "The '{a}' property is deprecated.", + W104: "'{a}' is available in ES6 (use esnext option) or Mozilla JS extensions (use moz).", + W105: "Unexpected {a} in '{b}'.", + W106: "Identifier '{a}' is not in camel case.", + W107: "Script URL.", + W108: "Strings must use doublequote.", + W109: "Strings must use singlequote.", + W110: "Mixed double and single quotes.", + W112: "Unclosed string.", + W113: "Control character in string: {a}.", + W114: "Avoid {a}.", + W115: "Octal literals are not allowed in strict mode.", + W116: "Expected '{a}' and instead saw '{b}'.", + W117: "'{a}' is not defined.", + W118: "'{a}' is only available in Mozilla JavaScript extensions (use moz option).", + W119: "'{a}' is only available in ES6 (use esnext option).", + W120: "You might be leaking a variable ({a}) here.", + W121: "Extending prototype of native object: '{a}'.", + W122: "Invalid typeof value '{a}'", + W123: "'{a}' is already defined in outer scope.", + W124: "A generator function shall contain a yield statement.", + W125: "This line contains non-breaking spaces: http://jshint.com/doc/options/#nonbsp" +}; + +var info = { + I001: "Comma warnings can be turned off with 'laxcomma'.", + I002: null, + I003: "ES5 option is now set per default" +}; + +exports.errors = {}; +exports.warnings = {}; +exports.info = {}; + +_.each(errors, function (desc, code) { + exports.errors[code] = { code: code, desc: desc }; +}); + +_.each(warnings, function (desc, code) { + exports.warnings[code] = { code: code, desc: desc }; +}); + +_.each(info, function (desc, code) { + exports.info[code] = { code: code, desc: desc }; +}); + +}, +{"underscore":2}], +6:[function(_dereq_,module,exports){ /* * Regular expressions. Some of these are stupidly long. */ @@ -8577,18 +8130,18 @@ exports.Lexer = Lexer; // Unsafe comment or string (ax) exports.unsafeString = - /@cc|<\/?|script|\]\s*\]|<\s*!|</i; + /@cc|<\/?|script|\]\s*\]|<\s*!|</i; // Unsafe characters that are silently deleted by one or more browsers (cx) exports.unsafeChars = - /[\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/; + /[\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/; // Characters in strings that need escaping (nx and nxg) exports.needEsc = - /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/; + /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/; exports.needEscGlobal = - /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; + /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; // Star slash (lx) exports.starSlash = /\*\//; @@ -8602,265 +8155,888 @@ exports.javascriptURL = /^(?:javascript|jscript|ecmascript|vbscript|mocha|livesc // Catches /* falls through */ comments (ft) exports.fallsThrough = /^\s*\/\*\s*falls?\sthrough\s*\*\/\s*$/; +// very conservative rule (eg: only one space between the start of the comment and the first character) +// to relax the maxlen option +exports.maxlenException = /^(?:(?:\/\/|\/\*|\*) ?)?[^ ]+$/; + }, {}], -7:[function(req,module,exports){ +7:[function(_dereq_,module,exports){ "use strict"; var state = { - syntax: {}, + syntax: {}, - reset: function () { - this.tokens = { - prev: null, - next: null, - curr: null - }; + reset: function () { + this.tokens = { + prev: null, + next: null, + curr: null + }; - this.option = {}; - this.ignored = {}; - this.directive = {}; - this.jsonMode = false; - this.jsonWarnings = []; - this.lines = []; - this.tab = ""; - this.cache = {}; // Node.JS doesn't have Map. Sniff. - } + this.option = {}; + this.ignored = {}; + this.directive = {}; + this.jsonMode = false; + this.jsonWarnings = []; + this.lines = []; + this.tab = ""; + this.cache = {}; // Node.JS doesn't have Map. Sniff. + this.ignoredLines = {}; + + // Blank out non-multi-line-commented lines when ignoring linter errors + this.ignoreLinterErrors = false; + } }; exports.state = state; }, {}], -8:[function(req,module,exports){ +8:[function(_dereq_,module,exports){ "use strict"; exports.register = function (linter) { - // Check for properties named __proto__. This special property was - // deprecated and then re-introduced for ES6. + // Check for properties named __proto__. This special property was + // deprecated and then re-introduced for ES6. - linter.on("Identifier", function style_scanProto(data) { - if (linter.getOption("proto")) { - return; - } + linter.on("Identifier", function style_scanProto(data) { + if (linter.getOption("proto")) { + return; + } - if (data.name === "__proto__") { - linter.warn("W103", { - line: data.line, - char: data.char, - data: [ data.name ] - }); - } - }); + if (data.name === "__proto__") { + linter.warn("W103", { + line: data.line, + char: data.char, + data: [ data.name ] + }); + } + }); - // Check for properties named __iterator__. This is a special property - // available only in browsers with JavaScript 1.7 implementation. + // Check for properties named __iterator__. This is a special property + // available only in browsers with JavaScript 1.7 implementation. - linter.on("Identifier", function style_scanIterator(data) { - if (linter.getOption("iterator")) { - return; - } + linter.on("Identifier", function style_scanIterator(data) { + if (linter.getOption("iterator")) { + return; + } - if (data.name === "__iterator__") { - linter.warn("W104", { - line: data.line, - char: data.char, - data: [ data.name ] - }); - } - }); + if (data.name === "__iterator__") { + linter.warn("W104", { + line: data.line, + char: data.char, + data: [ data.name ] + }); + } + }); - // Check for dangling underscores. + // Check that all identifiers are using camelCase notation. + // Exceptions: names like MY_VAR and _myVar. - linter.on("Identifier", function style_scanDangling(data) { - if (!linter.getOption("nomen")) { - return; - } + linter.on("Identifier", function style_scanCamelCase(data) { + if (!linter.getOption("camelcase")) { + return; + } - // Underscore.js - if (data.name === "_") { - return; - } + if (data.name.replace(/^_+|_+$/g, "").indexOf("_") > -1 && !data.name.match(/^[A-Z0-9_]*$/)) { + linter.warn("W106", { + line: data.line, + char: data.from, + data: [ data.name ] + }); + } + }); - // In Node, __dirname and __filename should be ignored. - if (linter.getOption("node")) { - if (/^(__dirname|__filename)$/.test(data.name) && !data.isProperty) { - return; - } - } + // Enforce consistency in style of quoting. - if (/^(_+.*|.*_+)$/.test(data.name)) { - linter.warn("W105", { - line: data.line, - char: data.from, - data: [ "dangling '_'", data.name ] - }); - } - }); + linter.on("String", function style_scanQuotes(data) { + var quotmark = linter.getOption("quotmark"); + var code; - // Check that all identifiers are using camelCase notation. - // Exceptions: names like MY_VAR and _myVar. + if (!quotmark) { + return; + } - linter.on("Identifier", function style_scanCamelCase(data) { - if (!linter.getOption("camelcase")) { - return; - } + // If quotmark is set to 'single' warn about all double-quotes. - if (data.name.replace(/^_+/, "").indexOf("_") > -1 && !data.name.match(/^[A-Z0-9_]*$/)) { - linter.warn("W106", { - line: data.line, - char: data.from, - data: [ data.name ] - }); - } - }); + if (quotmark === "single" && data.quote !== "'") { + code = "W109"; + } - // Enforce consistency in style of quoting. + // If quotmark is set to 'double' warn about all single-quotes. - linter.on("String", function style_scanQuotes(data) { - var quotmark = linter.getOption("quotmark"); - var code; + if (quotmark === "double" && data.quote !== "\"") { + code = "W108"; + } - if (!quotmark) { - return; - } + // If quotmark is set to true, remember the first quotation style + // and then warn about all others. - // If quotmark is set to 'single' warn about all double-quotes. + if (quotmark === true) { + if (!linter.getCache("quotmark")) { + linter.setCache("quotmark", data.quote); + } - if (quotmark === "single" && data.quote !== "'") { - code = "W109"; - } + if (linter.getCache("quotmark") !== data.quote) { + code = "W110"; + } + } - // If quotmark is set to 'double' warn about all single-quotes. + if (code) { + linter.warn(code, { + line: data.line, + char: data.char, + }); + } + }); - if (quotmark === "double" && data.quote !== "\"") { - code = "W108"; - } + linter.on("Number", function style_scanNumbers(data) { + if (data.value.charAt(0) === ".") { + // Warn about a leading decimal point. + linter.warn("W008", { + line: data.line, + char: data.char, + data: [ data.value ] + }); + } - // If quotmark is set to true, remember the first quotation style - // and then warn about all others. + if (data.value.substr(data.value.length - 1) === ".") { + // Warn about a trailing decimal point. + linter.warn("W047", { + line: data.line, + char: data.char, + data: [ data.value ] + }); + } - if (quotmark === true) { - if (!linter.getCache("quotmark")) { - linter.setCache("quotmark", data.quote); - } + if (/^00+/.test(data.value)) { + // Multiple leading zeroes. + linter.warn("W046", { + line: data.line, + char: data.char, + data: [ data.value ] + }); + } + }); - if (linter.getCache("quotmark") !== data.quote) { - code = "W110"; - } - } + // Warn about script URLs. - if (code) { - linter.warn(code, { - line: data.line, - char: data.char, - }); - } - }); + linter.on("String", function style_scanJavaScriptURLs(data) { + var re = /^(?:javascript|jscript|ecmascript|vbscript|mocha|livescript)\s*:/i; - linter.on("Number", function style_scanNumbers(data) { - if (data.value.charAt(0) === ".") { - // Warn about a leading decimal point. - linter.warn("W008", { - line: data.line, - char: data.char, - data: [ data.value ] - }); - } + if (linter.getOption("scripturl")) { + return; + } - if (data.value.substr(data.value.length - 1) === ".") { - // Warn about a trailing decimal point. - linter.warn("W047", { - line: data.line, - char: data.char, - data: [ data.value ] - }); - } - - if (/^00+/.test(data.value)) { - // Multiple leading zeroes. - linter.warn("W046", { - line: data.line, - char: data.char, - data: [ data.value ] - }); - } - }); - - // Warn about script URLs. - - linter.on("String", function style_scanJavaScriptURLs(data) { - var re = /^(?:javascript|jscript|ecmascript|vbscript|mocha|livescript)\s*:/i; - - if (linter.getOption("scripturl")) { - return; - } - - if (re.test(data.value)) { - linter.warn("W107", { - line: data.line, - char: data.char - }); - } - }); + if (re.test(data.value)) { + linter.warn("W107", { + line: data.line, + char: data.char + }); + } + }); }; -}, -{}], -9:[function(req,module,exports){ }, {}], -10:[function(req,module,exports){ -var process=req("__browserify_process");if (!process.EventEmitter) process.EventEmitter = function () {}; +9:[function(_dereq_,module,exports){ +// jshint -W001 -var EventEmitter = exports.EventEmitter = process.EventEmitter; -var isArray = typeof Array.isArray === 'function' - ? Array.isArray - : function (xs) { - return Object.prototype.toString.call(xs) === '[object Array]' - } -; -function indexOf (xs, x) { - if (xs.indexOf) return xs.indexOf(x); - for (var i = 0; i < xs.length; i++) { - if (x === xs[i]) return i; - } - return -1; -} +"use strict"; -// By default EventEmitters will print a warning if more than -// 10 listeners are added to it. This is a useful default which -// helps finding memory leaks. +// Identifiers provided by the ECMAScript standard. + +exports.reservedVars = { + arguments : false, + NaN : false +}; + +exports.ecmaIdentifiers = { + Array : false, + Boolean : false, + Date : false, + decodeURI : false, + decodeURIComponent : false, + encodeURI : false, + encodeURIComponent : false, + Error : false, + "eval" : false, + EvalError : false, + Function : false, + hasOwnProperty : false, + isFinite : false, + isNaN : false, + JSON : false, + Math : false, + Number : false, + Object : false, + parseInt : false, + parseFloat : false, + RangeError : false, + ReferenceError : false, + RegExp : false, + String : false, + SyntaxError : false, + TypeError : false, + URIError : false, +}; + +exports.newEcmaIdentifiers = { + Set : false, + Map : false, + WeakMap : false, + WeakSet : false, + Proxy : false, + Promise : false +}; + +// Global variables commonly provided by a web browser environment. + +exports.browser = { + Audio : false, + Blob : false, + addEventListener : false, + applicationCache : false, + atob : false, + blur : false, + btoa : false, + CanvasGradient : false, + CanvasPattern : false, + CanvasRenderingContext2D: false, + clearInterval : false, + clearTimeout : false, + close : false, + closed : false, + CustomEvent : false, + DOMParser : false, + defaultStatus : false, + document : false, + Element : false, + ElementTimeControl : false, + event : false, + FileReader : false, + FormData : false, + focus : false, + frames : false, + getComputedStyle : false, + HTMLElement : false, + HTMLAnchorElement : false, + HTMLBaseElement : false, + HTMLBlockquoteElement: false, + HTMLBodyElement : false, + HTMLBRElement : false, + HTMLButtonElement : false, + HTMLCanvasElement : false, + HTMLDirectoryElement : false, + HTMLDivElement : false, + HTMLDListElement : false, + HTMLFieldSetElement : false, + HTMLFontElement : false, + HTMLFormElement : false, + HTMLFrameElement : false, + HTMLFrameSetElement : false, + HTMLHeadElement : false, + HTMLHeadingElement : false, + HTMLHRElement : false, + HTMLHtmlElement : false, + HTMLIFrameElement : false, + HTMLImageElement : false, + HTMLInputElement : false, + HTMLIsIndexElement : false, + HTMLLabelElement : false, + HTMLLayerElement : false, + HTMLLegendElement : false, + HTMLLIElement : false, + HTMLLinkElement : false, + HTMLMapElement : false, + HTMLMenuElement : false, + HTMLMetaElement : false, + HTMLModElement : false, + HTMLObjectElement : false, + HTMLOListElement : false, + HTMLOptGroupElement : false, + HTMLOptionElement : false, + HTMLParagraphElement : false, + HTMLParamElement : false, + HTMLPreElement : false, + HTMLQuoteElement : false, + HTMLScriptElement : false, + HTMLSelectElement : false, + HTMLStyleElement : false, + HTMLTableCaptionElement: false, + HTMLTableCellElement : false, + HTMLTableColElement : false, + HTMLTableElement : false, + HTMLTableRowElement : false, + HTMLTableSectionElement: false, + HTMLTextAreaElement : false, + HTMLTitleElement : false, + HTMLUListElement : false, + HTMLVideoElement : false, + history : false, + Image : false, + length : false, + localStorage : false, + location : false, + matchMedia : false, + MessageChannel : false, + MessageEvent : false, + MessagePort : false, + MouseEvent : false, + moveBy : false, + moveTo : false, + MutationObserver : false, + name : false, + Node : false, + NodeFilter : false, + NodeList : false, + navigator : false, + onbeforeunload : true, + onblur : true, + onerror : true, + onfocus : true, + onload : true, + onresize : true, + onunload : true, + open : false, + openDatabase : false, + opener : false, + Option : false, + parent : false, + print : false, + removeEventListener : false, + resizeBy : false, + resizeTo : false, + screen : false, + scroll : false, + scrollBy : false, + scrollTo : false, + sessionStorage : false, + setInterval : false, + setTimeout : false, + SharedWorker : false, + status : false, + SVGAElement : false, + SVGAltGlyphDefElement: false, + SVGAltGlyphElement : false, + SVGAltGlyphItemElement: false, + SVGAngle : false, + SVGAnimateColorElement: false, + SVGAnimateElement : false, + SVGAnimateMotionElement: false, + SVGAnimateTransformElement: false, + SVGAnimatedAngle : false, + SVGAnimatedBoolean : false, + SVGAnimatedEnumeration: false, + SVGAnimatedInteger : false, + SVGAnimatedLength : false, + SVGAnimatedLengthList: false, + SVGAnimatedNumber : false, + SVGAnimatedNumberList: false, + SVGAnimatedPathData : false, + SVGAnimatedPoints : false, + SVGAnimatedPreserveAspectRatio: false, + SVGAnimatedRect : false, + SVGAnimatedString : false, + SVGAnimatedTransformList: false, + SVGAnimationElement : false, + SVGCSSRule : false, + SVGCircleElement : false, + SVGClipPathElement : false, + SVGColor : false, + SVGColorProfileElement: false, + SVGColorProfileRule : false, + SVGComponentTransferFunctionElement: false, + SVGCursorElement : false, + SVGDefsElement : false, + SVGDescElement : false, + SVGDocument : false, + SVGElement : false, + SVGElementInstance : false, + SVGElementInstanceList: false, + SVGEllipseElement : false, + SVGExternalResourcesRequired: false, + SVGFEBlendElement : false, + SVGFEColorMatrixElement: false, + SVGFEComponentTransferElement: false, + SVGFECompositeElement: false, + SVGFEConvolveMatrixElement: false, + SVGFEDiffuseLightingElement: false, + SVGFEDisplacementMapElement: false, + SVGFEDistantLightElement: false, + SVGFEFloodElement : false, + SVGFEFuncAElement : false, + SVGFEFuncBElement : false, + SVGFEFuncGElement : false, + SVGFEFuncRElement : false, + SVGFEGaussianBlurElement: false, + SVGFEImageElement : false, + SVGFEMergeElement : false, + SVGFEMergeNodeElement: false, + SVGFEMorphologyElement: false, + SVGFEOffsetElement : false, + SVGFEPointLightElement: false, + SVGFESpecularLightingElement: false, + SVGFESpotLightElement: false, + SVGFETileElement : false, + SVGFETurbulenceElement: false, + SVGFilterElement : false, + SVGFilterPrimitiveStandardAttributes: false, + SVGFitToViewBox : false, + SVGFontElement : false, + SVGFontFaceElement : false, + SVGFontFaceFormatElement: false, + SVGFontFaceNameElement: false, + SVGFontFaceSrcElement: false, + SVGFontFaceUriElement: false, + SVGForeignObjectElement: false, + SVGGElement : false, + SVGGlyphElement : false, + SVGGlyphRefElement : false, + SVGGradientElement : false, + SVGHKernElement : false, + SVGICCColor : false, + SVGImageElement : false, + SVGLangSpace : false, + SVGLength : false, + SVGLengthList : false, + SVGLineElement : false, + SVGLinearGradientElement: false, + SVGLocatable : false, + SVGMPathElement : false, + SVGMarkerElement : false, + SVGMaskElement : false, + SVGMatrix : false, + SVGMetadataElement : false, + SVGMissingGlyphElement: false, + SVGNumber : false, + SVGNumberList : false, + SVGPaint : false, + SVGPathElement : false, + SVGPathSeg : false, + SVGPathSegArcAbs : false, + SVGPathSegArcRel : false, + SVGPathSegClosePath : false, + SVGPathSegCurvetoCubicAbs: false, + SVGPathSegCurvetoCubicRel: false, + SVGPathSegCurvetoCubicSmoothAbs: false, + SVGPathSegCurvetoCubicSmoothRel: false, + SVGPathSegCurvetoQuadraticAbs: false, + SVGPathSegCurvetoQuadraticRel: false, + SVGPathSegCurvetoQuadraticSmoothAbs: false, + SVGPathSegCurvetoQuadraticSmoothRel: false, + SVGPathSegLinetoAbs : false, + SVGPathSegLinetoHorizontalAbs: false, + SVGPathSegLinetoHorizontalRel: false, + SVGPathSegLinetoRel : false, + SVGPathSegLinetoVerticalAbs: false, + SVGPathSegLinetoVerticalRel: false, + SVGPathSegList : false, + SVGPathSegMovetoAbs : false, + SVGPathSegMovetoRel : false, + SVGPatternElement : false, + SVGPoint : false, + SVGPointList : false, + SVGPolygonElement : false, + SVGPolylineElement : false, + SVGPreserveAspectRatio: false, + SVGRadialGradientElement: false, + SVGRect : false, + SVGRectElement : false, + SVGRenderingIntent : false, + SVGSVGElement : false, + SVGScriptElement : false, + SVGSetElement : false, + SVGStopElement : false, + SVGStringList : false, + SVGStylable : false, + SVGStyleElement : false, + SVGSwitchElement : false, + SVGSymbolElement : false, + SVGTRefElement : false, + SVGTSpanElement : false, + SVGTests : false, + SVGTextContentElement: false, + SVGTextElement : false, + SVGTextPathElement : false, + SVGTextPositioningElement: false, + SVGTitleElement : false, + SVGTransform : false, + SVGTransformList : false, + SVGTransformable : false, + SVGURIReference : false, + SVGUnitTypes : false, + SVGUseElement : false, + SVGVKernElement : false, + SVGViewElement : false, + SVGViewSpec : false, + SVGZoomAndPan : false, + TimeEvent : false, + top : false, + URL : false, + WebSocket : false, + window : false, + Worker : false, + XMLHttpRequest : false, + XMLSerializer : false, + XPathEvaluator : false, + XPathException : false, + XPathExpression : false, + XPathNamespace : false, + XPathNSResolver : false, + XPathResult : false +}; + +exports.devel = { + alert : false, + confirm: false, + console: false, + Debug : false, + opera : false, + prompt : false +}; + +exports.worker = { + importScripts: true, + postMessage : true, + self : true +}; + +// Widely adopted global names that are not part of ECMAScript standard +exports.nonstandard = { + escape : false, + unescape: false +}; + +// Globals provided by popular JavaScript environments. + +exports.couch = { + "require" : false, + respond : false, + getRow : false, + emit : false, + send : false, + start : false, + sum : false, + log : false, + exports : false, + module : false, + provides : false +}; + +exports.node = { + __filename : false, + __dirname : false, + GLOBAL : false, + global : false, + module : false, + require : false, + + // These globals are writeable because Node allows the following + // usage pattern: var Buffer = require("buffer").Buffer; + + Buffer : true, + console : true, + exports : true, + process : true, + setTimeout : true, + clearTimeout : true, + setInterval : true, + clearInterval : true, + setImmediate : true, // v0.9.1+ + clearImmediate: true // v0.9.1+ +}; + +exports.phantom = { + phantom : true, + require : true, + WebPage : true, + console : true, // in examples, but undocumented + exports : true // v1.7+ +}; + +exports.rhino = { + defineClass : false, + deserialize : false, + gc : false, + help : false, + importClass : false, + importPackage: false, + "java" : false, + load : false, + loadClass : false, + Packages : false, + print : false, + quit : false, + readFile : false, + readUrl : false, + runCommand : false, + seal : false, + serialize : false, + spawn : false, + sync : false, + toint32 : false, + version : false +}; + +exports.shelljs = { + target : false, + echo : false, + exit : false, + cd : false, + pwd : false, + ls : false, + find : false, + cp : false, + rm : false, + mv : false, + mkdir : false, + test : false, + cat : false, + sed : false, + grep : false, + which : false, + dirs : false, + pushd : false, + popd : false, + env : false, + exec : false, + chmod : false, + config : false, + error : false, + tempdir : false +}; + +exports.typed = { + ArrayBuffer : false, + ArrayBufferView : false, + DataView : false, + Float32Array : false, + Float64Array : false, + Int16Array : false, + Int32Array : false, + Int8Array : false, + Uint16Array : false, + Uint32Array : false, + Uint8Array : false, + Uint8ClampedArray : false +}; + +exports.wsh = { + ActiveXObject : true, + Enumerator : true, + GetObject : true, + ScriptEngine : true, + ScriptEngineBuildVersion : true, + ScriptEngineMajorVersion : true, + ScriptEngineMinorVersion : true, + VBArray : true, + WSH : true, + WScript : true, + XDomainRequest : true +}; + +// Globals provided by popular JavaScript libraries. + +exports.dojo = { + dojo : false, + dijit : false, + dojox : false, + define : false, + "require": false +}; + +exports.jquery = { + "$" : false, + jQuery : false +}; + +exports.mootools = { + "$" : false, + "$$" : false, + Asset : false, + Browser : false, + Chain : false, + Class : false, + Color : false, + Cookie : false, + Core : false, + Document : false, + DomReady : false, + DOMEvent : false, + DOMReady : false, + Drag : false, + Element : false, + Elements : false, + Event : false, + Events : false, + Fx : false, + Group : false, + Hash : false, + HtmlTable : false, + Iframe : false, + IframeShim : false, + InputValidator: false, + instanceOf : false, + Keyboard : false, + Locale : false, + Mask : false, + MooTools : false, + Native : false, + Options : false, + OverText : false, + Request : false, + Scroller : false, + Slick : false, + Slider : false, + Sortables : false, + Spinner : false, + Swiff : false, + Tips : false, + Type : false, + typeOf : false, + URI : false, + Window : false +}; + +exports.prototypejs = { + "$" : false, + "$$" : false, + "$A" : false, + "$F" : false, + "$H" : false, + "$R" : false, + "$break" : false, + "$continue" : false, + "$w" : false, + Abstract : false, + Ajax : false, + Class : false, + Enumerable : false, + Element : false, + Event : false, + Field : false, + Form : false, + Hash : false, + Insertion : false, + ObjectRange : false, + PeriodicalExecuter: false, + Position : false, + Prototype : false, + Selector : false, + Template : false, + Toggle : false, + Try : false, + Autocompleter : false, + Builder : false, + Control : false, + Draggable : false, + Draggables : false, + Droppables : false, + Effect : false, + Sortable : false, + SortableObserver : false, + Sound : false, + Scriptaculous : false +}; + +exports.yui = { + YUI : false, + Y : false, + YUI_config: false +}; + +exports.mocha = { + // BDD + describe : false, + it : false, + before : false, + after : false, + beforeEach : false, + afterEach : false, + // TDD + suite : false, + test : false, + setup : false, + teardown : false +}; + +}, +{}], +10:[function(_dereq_,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. // +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +function EventEmitter() { + this._events = this._events || {}; + this._maxListeners = this._maxListeners || undefined; +} +module.exports = EventEmitter; + +// Backwards-compat with node 0.10.x +EventEmitter.EventEmitter = EventEmitter; + +EventEmitter.prototype._events = undefined; +EventEmitter.prototype._maxListeners = undefined; + +// By default EventEmitters will print a warning if more than 10 listeners are +// added to it. This is a useful default which helps finding memory leaks. +EventEmitter.defaultMaxListeners = 10; + // Obviously not all Emitters should be limited to 10. This function allows // that to be increased. Set to zero for unlimited. -var defaultMaxListeners = 200; EventEmitter.prototype.setMaxListeners = function(n) { - if (!this._events) this._events = {}; - this._events.maxListeners = n; + if (!isNumber(n) || n < 0 || isNaN(n)) + throw TypeError('n must be a positive number'); + this._maxListeners = n; + return this; }; - EventEmitter.prototype.emit = function(type) { + var er, handler, len, args, i, listeners; + + if (!this._events) + this._events = {}; + // If there is no 'error' event listener then throw. if (type === 'error') { - if (!this._events || !this._events.error || - (isArray(this._events.error) && !this._events.error.length)) - { - if (arguments[1] instanceof Error) { - throw arguments[1]; // Unhandled 'error' event + if (!this._events.error || + (isObject(this._events.error) && !this._events.error.length)) { + er = arguments[1]; + if (er instanceof Error) { + throw er; // Unhandled 'error' event } else { - throw new Error("Uncaught, unspecified 'error' event."); + throw TypeError('Uncaught, unspecified "error" event.'); } return false; } } - if (!this._events) return false; - var handler = this._events[type]; - if (!handler) return false; + handler = this._events[type]; - if (typeof handler == 'function') { + if (isUndefined(handler)) + return false; + + if (isFunction(handler)) { switch (arguments.length) { // fast cases case 1: @@ -8874,67 +9050,70 @@ EventEmitter.prototype.emit = function(type) { break; // slower default: - var args = Array.prototype.slice.call(arguments, 1); + len = arguments.length; + args = new Array(len - 1); + for (i = 1; i < len; i++) + args[i - 1] = arguments[i]; handler.apply(this, args); } - return true; + } else if (isObject(handler)) { + len = arguments.length; + args = new Array(len - 1); + for (i = 1; i < len; i++) + args[i - 1] = arguments[i]; - } else if (isArray(handler)) { - var args = Array.prototype.slice.call(arguments, 1); - - var listeners = handler.slice(); - for (var i = 0, l = listeners.length; i < l; i++) { + listeners = handler.slice(); + len = listeners.length; + for (i = 0; i < len; i++) listeners[i].apply(this, args); - } - return true; - - } else { - return false; } + + return true; }; -// EventEmitter is defined in src/node_events.cc -// EventEmitter.prototype.emit() is also defined there. EventEmitter.prototype.addListener = function(type, listener) { - if ('function' !== typeof listener) { - throw new Error('addListener only takes instances of Function'); - } + var m; - if (!this._events) this._events = {}; + if (!isFunction(listener)) + throw TypeError('listener must be a function'); - // To avoid recursion in the case that type == "newListeners"! Before - // adding it to the listeners, first emit "newListeners". - this.emit('newListener', type, listener); + if (!this._events) + this._events = {}; - if (!this._events[type]) { + // To avoid recursion in the case that type === "newListener"! Before + // adding it to the listeners, first emit "newListener". + if (this._events.newListener) + this.emit('newListener', type, + isFunction(listener.listener) ? + listener.listener : listener); + + if (!this._events[type]) // Optimize the case of one listener. Don't need the extra array object. this._events[type] = listener; - } else if (isArray(this._events[type])) { - - // Check for listener leak - if (!this._events[type].warned) { - var m; - if (this._events.maxListeners !== undefined) { - m = this._events.maxListeners; - } else { - m = defaultMaxListeners; - } - - if (m && m > 0 && this._events[type].length > m) { - this._events[type].warned = true; - console.error('(node) warning: possible EventEmitter memory ' + - 'leak detected. %d listeners added. ' + - 'Use emitter.setMaxListeners() to increase limit.', - this._events[type].length); - console.trace(); - } - } - + else if (isObject(this._events[type])) // If we've already got an array, just append. this._events[type].push(listener); - } else { + else // Adding the second element, need to change to array. this._events[type] = [this._events[type], listener]; + + // Check for listener leak + if (isObject(this._events[type]) && !this._events[type].warned) { + var m; + if (!isUndefined(this._maxListeners)) { + m = this._maxListeners; + } else { + m = EventEmitter.defaultMaxListeners; + } + + if (m && m > 0 && this._events[type].length > m) { + this._events[type].warned = true; + console.error('(node) warning: possible EventEmitter memory ' + + 'leak detected. %d listeners added. ' + + 'Use emitter.setMaxListeners() to increase limit.', + this._events[type].length); + console.trace(); + } } return this; @@ -8943,134 +9122,152 @@ EventEmitter.prototype.addListener = function(type, listener) { EventEmitter.prototype.on = EventEmitter.prototype.addListener; EventEmitter.prototype.once = function(type, listener) { - var self = this; - self.on(type, function g() { - self.removeListener(type, g); - listener.apply(this, arguments); - }); + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + var fired = false; + + function g() { + this.removeListener(type, g); + + if (!fired) { + fired = true; + listener.apply(this, arguments); + } + } + + g.listener = listener; + this.on(type, g); return this; }; +// emits a 'removeListener' event iff the listener was removed EventEmitter.prototype.removeListener = function(type, listener) { - if ('function' !== typeof listener) { - throw new Error('removeListener only takes instances of Function'); - } + var list, position, length, i; - // does not use listeners(), so no side effect of creating _events[type] - if (!this._events || !this._events[type]) return this; + if (!isFunction(listener)) + throw TypeError('listener must be a function'); - var list = this._events[type]; + if (!this._events || !this._events[type]) + return this; - if (isArray(list)) { - var i = indexOf(list, listener); - if (i < 0) return this; - list.splice(i, 1); - if (list.length == 0) - delete this._events[type]; - } else if (this._events[type] === listener) { + list = this._events[type]; + length = list.length; + position = -1; + + if (list === listener || + (isFunction(list.listener) && list.listener === listener)) { delete this._events[type]; + if (this._events.removeListener) + this.emit('removeListener', type, listener); + + } else if (isObject(list)) { + for (i = length; i-- > 0;) { + if (list[i] === listener || + (list[i].listener && list[i].listener === listener)) { + position = i; + break; + } + } + + if (position < 0) + return this; + + if (list.length === 1) { + list.length = 0; + delete this._events[type]; + } else { + list.splice(position, 1); + } + + if (this._events.removeListener) + this.emit('removeListener', type, listener); } return this; }; EventEmitter.prototype.removeAllListeners = function(type) { + var key, listeners; + + if (!this._events) + return this; + + // not listening for removeListener, no need to emit + if (!this._events.removeListener) { + if (arguments.length === 0) + this._events = {}; + else if (this._events[type]) + delete this._events[type]; + return this; + } + + // emit removeListener for all listeners on all events if (arguments.length === 0) { + for (key in this._events) { + if (key === 'removeListener') continue; + this.removeAllListeners(key); + } + this.removeAllListeners('removeListener'); this._events = {}; return this; } - // does not use listeners(), so no side effect of creating _events[type] - if (type && this._events && this._events[type]) this._events[type] = null; + listeners = this._events[type]; + + if (isFunction(listeners)) { + this.removeListener(type, listeners); + } else { + // LIFO order + while (listeners.length) + this.removeListener(type, listeners[listeners.length - 1]); + } + delete this._events[type]; + return this; }; EventEmitter.prototype.listeners = function(type) { - if (!this._events) this._events = {}; - if (!this._events[type]) this._events[type] = []; - if (!isArray(this._events[type])) { - this._events[type] = [this._events[type]]; - } - return this._events[type]; + var ret; + if (!this._events || !this._events[type]) + ret = []; + else if (isFunction(this._events[type])) + ret = [this._events[type]]; + else + ret = this._events[type].slice(); + return ret; }; EventEmitter.listenerCount = function(emitter, type) { var ret; if (!emitter._events || !emitter._events[type]) ret = 0; - else if (typeof emitter._events[type] === 'function') + else if (isFunction(emitter._events[type])) ret = 1; else ret = emitter._events[type].length; return ret; }; -}, -{"__browserify_process":11}], -11:[function(req,module,exports){ -// shim for using process in browser - -var process = module.exports = {}; - -process.nextTick = (function () { - var canSetImmediate = typeof window !== 'undefined' - && window.setImmediate; - var canPost = typeof window !== 'undefined' - && window.postMessage && window.addEventListener - ; - - if (canSetImmediate) { - return function (f) { return window.setImmediate(f) }; - } - - if (canPost) { - var queue = []; - window.addEventListener('message', function (ev) { - if (ev.source === window && ev.data === 'process-tick') { - ev.stopPropagation(); - if (queue.length > 0) { - var fn = queue.shift(); - fn(); - } - } - }, true); - - return function nextTick(fn) { - queue.push(fn); - window.postMessage('process-tick', '*'); - }; - } - - return function nextTick(fn) { - setTimeout(fn, 0); - }; -})(); - -process.title = 'browser'; -process.browser = true; -process.env = {}; -process.argv = []; - -process.binding = function (name) { - throw new Error('process.binding is not supported'); +function isFunction(arg) { + return typeof arg === 'function'; } -// TODO(shtylman) -process.cwd = function () { return '/' }; -process.chdir = function (dir) { - throw new Error('process.chdir is not supported'); -}; +function isNumber(arg) { + return typeof arg === 'number'; +} + +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} + +function isUndefined(arg) { + return arg === void 0; +} }, -{}], -"jshint":[function(req,module,exports){ -module.exports=req('n4bKNg'); -}, -{}]},{},["n4bKNg"]) -; - -function req() {return require.apply(this, arguments)} -module.exports = req("jshint"); +{}]},{},[3]) +(3) }); \ No newline at end of file diff --git a/tool/update_deps.js b/tool/update_deps.js index a5adebb3..4ac9f4e6 100644 --- a/tool/update_deps.js +++ b/tool/update_deps.js @@ -12,7 +12,12 @@ var deps = { csslint: { path: "mode/css/csslint.js", url: "https://raw.github.com/stubbornella/csslint/master/release/csslint.js", - needsFixup: true + needsFixup: true, + browserify: { + npmModule: "csslint@latest", + path: "jshint/src/jshint.js", + exports: "jshint" + }, }, requirejs: { path: "../../demo/kitchen-sink/require.js", @@ -30,49 +35,34 @@ var deps = { ) } }, - jshint: { - path: "mode/javascript/jshint.js", - url: "http://jshint.com/get/jshint-2.1.9.js", - fetch: function(_, cb) { - //run("npm install jshint@latest", function() { - var base = Path.join(__dirname, "/node_modules/jshint/") - var path = Path.join(base, "/src/stable/jshint") - run('browserify ' + path + ' -i console-browserify -r jshint', function(err, src) { - src = replaceConsoleBrowserify(src); - var version = JSON.parse(fs.readFileSync(base + "package.json")).version - src = [ "// " + version, - "var JSHINT;", - "(function () {", - "require = null;", - src, - "JSHINT = require('jshint').JSHINT;", - "}());" - ].join("\n") - cb(err, src); - }) - //}); + html5: { + path: "mode/html/saxparser.js", + browserify: { + npmModule: "git+https://github.com/aredridel/html5.git#master", + path: "html5/lib/sax/SAXParser.js", + exports: "SAXParser" }, + fetch: browserify, + needsFixup: true, + postProcess: function(src) { + return src; + } + }, + jshint: { + path: "mode/javascript/jshint.js", + browserify: { + npmModule: "git+https://github.com/nightwing/jshint.git#master", + path: "jshint/src/jshint.js", + exports: "jshint" + }, + fetch: browserify, needsFixup: true, postProcess: function(src) { - src = src.replace(/(\],|\{)((?:\d+|"\w+"):\[)/g, "$1\n$2") - .replace(/^(\},)(\{[^{}\[\]]*?\}\])/gm, "$1\n$2") - src = src.replace( /"Expected a conditional expression and instead saw an assignment."/g, '"Assignment in conditional expression"' ); - - src = src.replace(/\brequire\(["']|\(require,|\(require\)/g, function(r){ - return r.replace("require", "req"); - }) - src = src.replace(/var defaultMaxListeners = 10;/, function(a) {return a.replace("10", "200")}); - - src = src.replace(/var JSHINT;\s*\(function[\s()]+\{\s*/, "") - .replace(/JSHINT = .*\n\s*\}\(\)\);\s*/, ""); - src += '\n' - + 'function req() {return require.apply(this, arguments)}\n' - + 'module.exports = req("jshint");\n'; return src; } }, @@ -238,23 +228,19 @@ function unquote(str) { }); } -function replaceConsoleBrowserify(str) { - var simpleConsole = function(req,module,exports){ - ["log", "info", "warn", "error", - "time","timeEnd", "trace", "dir", "assert" - ].forEach(function(x) {exports[x] = nop;}); - function nop() {} - } - var m = /"console-browserify":(\d+)/.exec(str); - name = m && m[1]; - if (name) { - str = str.replace( - "{1:[", - "{" + name + ":[" + simpleConsole + ",{}],\n1:[" - ) - } - return str; +function browserify(_, cb) { + var br = this.browserify; + var path = Path.join("node_modules", br.path) + run("npm install " + this.browserify.npmModule, function() { + run("browserify " + path + " -s " + br.exports, function(err, src) { + src = src.replace(/^.*return\s*\(function/, "module.exports = (function") + .replace(/\}\);\s*$/, ""); + src = src.replace(/(\],|\{)((?:\d+|"\w+"):\[)/g, "$1\n$2") + .replace(/^(\},)(\{[^{}\[\]]*?\}\])/gm, "$1\n$2") + cb(err, src); + }) + }) } - +getDep(deps.html5) getDep(deps.jshint) \ No newline at end of file