| 
						 | 
						- 'use strict';
 - 
 - const XHTMLEntities = require('./xhtml');
 - 
 - const hexNumber = /^[\da-fA-F]+$/;
 - const decimalNumber = /^\d+$/;
 - 
 - // The map to `acorn-jsx` tokens from `acorn` namespace objects.
 - const acornJsxMap = new WeakMap();
 - 
 - // Get the original tokens for the given `acorn` namespace object.
 - function getJsxTokens(acorn) {
 -   acorn = acorn.Parser.acorn || acorn;
 -   let acornJsx = acornJsxMap.get(acorn);
 -   if (!acornJsx) {
 -     const tt = acorn.tokTypes;
 -     const TokContext = acorn.TokContext;
 -     const TokenType = acorn.TokenType;
 -     const tc_oTag = new TokContext('<tag', false);
 -     const tc_cTag = new TokContext('</tag', false);
 -     const tc_expr = new TokContext('<tag>...</tag>', true, true);
 -     const tokContexts = {
 -       tc_oTag: tc_oTag,
 -       tc_cTag: tc_cTag,
 -       tc_expr: tc_expr
 -     };
 -     const tokTypes = {
 -       jsxName: new TokenType('jsxName'),
 -       jsxText: new TokenType('jsxText', {beforeExpr: true}),
 -       jsxTagStart: new TokenType('jsxTagStart', {startsExpr: true}),
 -       jsxTagEnd: new TokenType('jsxTagEnd')
 -     };
 - 
 -     tokTypes.jsxTagStart.updateContext = function() {
 -       this.context.push(tc_expr); // treat as beginning of JSX expression
 -       this.context.push(tc_oTag); // start opening tag context
 -       this.exprAllowed = false;
 -     };
 -     tokTypes.jsxTagEnd.updateContext = function(prevType) {
 -       let out = this.context.pop();
 -       if (out === tc_oTag && prevType === tt.slash || out === tc_cTag) {
 -         this.context.pop();
 -         this.exprAllowed = this.curContext() === tc_expr;
 -       } else {
 -         this.exprAllowed = true;
 -       }
 -     };
 - 
 -     acornJsx = { tokContexts: tokContexts, tokTypes: tokTypes };
 -     acornJsxMap.set(acorn, acornJsx);
 -   }
 - 
 -   return acornJsx;
 - }
 - 
 - // Transforms JSX element name to string.
 - 
 - function getQualifiedJSXName(object) {
 -   if (!object)
 -     return object;
 - 
 -   if (object.type === 'JSXIdentifier')
 -     return object.name;
 - 
 -   if (object.type === 'JSXNamespacedName')
 -     return object.namespace.name + ':' + object.name.name;
 - 
 -   if (object.type === 'JSXMemberExpression')
 -     return getQualifiedJSXName(object.object) + '.' +
 -     getQualifiedJSXName(object.property);
 - }
 - 
 - module.exports = function(options) {
 -   options = options || {};
 -   return function(Parser) {
 -     return plugin({
 -       allowNamespaces: options.allowNamespaces !== false,
 -       allowNamespacedObjects: !!options.allowNamespacedObjects
 -     }, Parser);
 -   };
 - };
 - 
 - // This is `tokTypes` of the peer dep.
 - // This can be different instances from the actual `tokTypes` this plugin uses.
 - Object.defineProperty(module.exports, "tokTypes", {
 -   get: function get_tokTypes() {
 -     return getJsxTokens(require("acorn")).tokTypes;
 -   },
 -   configurable: true,
 -   enumerable: true
 - });
 - 
 - function plugin(options, Parser) {
 -   const acorn = Parser.acorn || require("acorn");
 -   const acornJsx = getJsxTokens(acorn);
 -   const tt = acorn.tokTypes;
 -   const tok = acornJsx.tokTypes;
 -   const tokContexts = acorn.tokContexts;
 -   const tc_oTag = acornJsx.tokContexts.tc_oTag;
 -   const tc_cTag = acornJsx.tokContexts.tc_cTag;
 -   const tc_expr = acornJsx.tokContexts.tc_expr;
 -   const isNewLine = acorn.isNewLine;
 -   const isIdentifierStart = acorn.isIdentifierStart;
 -   const isIdentifierChar = acorn.isIdentifierChar;
 - 
 -   return class extends Parser {
 -     // Expose actual `tokTypes` and `tokContexts` to other plugins.
 -     static get acornJsx() {
 -       return acornJsx;
 -     }
 - 
 -     // Reads inline JSX contents token.
 -     jsx_readToken() {
 -       let out = '', chunkStart = this.pos;
 -       for (;;) {
 -         if (this.pos >= this.input.length)
 -           this.raise(this.start, 'Unterminated JSX contents');
 -         let ch = this.input.charCodeAt(this.pos);
 - 
 -         switch (ch) {
 -         case 60: // '<'
 -         case 123: // '{'
 -           if (this.pos === this.start) {
 -             if (ch === 60 && this.exprAllowed) {
 -               ++this.pos;
 -               return this.finishToken(tok.jsxTagStart);
 -             }
 -             return this.getTokenFromCode(ch);
 -           }
 -           out += this.input.slice(chunkStart, this.pos);
 -           return this.finishToken(tok.jsxText, out);
 - 
 -         case 38: // '&'
 -           out += this.input.slice(chunkStart, this.pos);
 -           out += this.jsx_readEntity();
 -           chunkStart = this.pos;
 -           break;
 - 
 -         case 62: // '>'
 -         case 125: // '}'
 -           this.raise(
 -             this.pos,
 -             "Unexpected token `" + this.input[this.pos] + "`. Did you mean `" +
 -               (ch === 62 ? ">" : "}") + "` or " + "`{\"" + this.input[this.pos] + "\"}" + "`?"
 -           );
 - 
 -         default:
 -           if (isNewLine(ch)) {
 -             out += this.input.slice(chunkStart, this.pos);
 -             out += this.jsx_readNewLine(true);
 -             chunkStart = this.pos;
 -           } else {
 -             ++this.pos;
 -           }
 -         }
 -       }
 -     }
 - 
 -     jsx_readNewLine(normalizeCRLF) {
 -       let ch = this.input.charCodeAt(this.pos);
 -       let out;
 -       ++this.pos;
 -       if (ch === 13 && this.input.charCodeAt(this.pos) === 10) {
 -         ++this.pos;
 -         out = normalizeCRLF ? '\n' : '\r\n';
 -       } else {
 -         out = String.fromCharCode(ch);
 -       }
 -       if (this.options.locations) {
 -         ++this.curLine;
 -         this.lineStart = this.pos;
 -       }
 - 
 -       return out;
 -     }
 - 
 -     jsx_readString(quote) {
 -       let out = '', chunkStart = ++this.pos;
 -       for (;;) {
 -         if (this.pos >= this.input.length)
 -           this.raise(this.start, 'Unterminated string constant');
 -         let ch = this.input.charCodeAt(this.pos);
 -         if (ch === quote) break;
 -         if (ch === 38) { // '&'
 -           out += this.input.slice(chunkStart, this.pos);
 -           out += this.jsx_readEntity();
 -           chunkStart = this.pos;
 -         } else if (isNewLine(ch)) {
 -           out += this.input.slice(chunkStart, this.pos);
 -           out += this.jsx_readNewLine(false);
 -           chunkStart = this.pos;
 -         } else {
 -           ++this.pos;
 -         }
 -       }
 -       out += this.input.slice(chunkStart, this.pos++);
 -       return this.finishToken(tt.string, out);
 -     }
 - 
 -     jsx_readEntity() {
 -       let str = '', count = 0, entity;
 -       let ch = this.input[this.pos];
 -       if (ch !== '&')
 -         this.raise(this.pos, 'Entity must start with an ampersand');
 -       let startPos = ++this.pos;
 -       while (this.pos < this.input.length && count++ < 10) {
 -         ch = this.input[this.pos++];
 -         if (ch === ';') {
 -           if (str[0] === '#') {
 -             if (str[1] === 'x') {
 -               str = str.substr(2);
 -               if (hexNumber.test(str))
 -                 entity = String.fromCharCode(parseInt(str, 16));
 -             } else {
 -               str = str.substr(1);
 -               if (decimalNumber.test(str))
 -                 entity = String.fromCharCode(parseInt(str, 10));
 -             }
 -           } else {
 -             entity = XHTMLEntities[str];
 -           }
 -           break;
 -         }
 -         str += ch;
 -       }
 -       if (!entity) {
 -         this.pos = startPos;
 -         return '&';
 -       }
 -       return entity;
 -     }
 - 
 -     // Read a JSX identifier (valid tag or attribute name).
 -     //
 -     // Optimized version since JSX identifiers can't contain
 -     // escape characters and so can be read as single slice.
 -     // Also assumes that first character was already checked
 -     // by isIdentifierStart in readToken.
 - 
 -     jsx_readWord() {
 -       let ch, start = this.pos;
 -       do {
 -         ch = this.input.charCodeAt(++this.pos);
 -       } while (isIdentifierChar(ch) || ch === 45); // '-'
 -       return this.finishToken(tok.jsxName, this.input.slice(start, this.pos));
 -     }
 - 
 -     // Parse next token as JSX identifier
 - 
 -     jsx_parseIdentifier() {
 -       let node = this.startNode();
 -       if (this.type === tok.jsxName)
 -         node.name = this.value;
 -       else if (this.type.keyword)
 -         node.name = this.type.keyword;
 -       else
 -         this.unexpected();
 -       this.next();
 -       return this.finishNode(node, 'JSXIdentifier');
 -     }
 - 
 -     // Parse namespaced identifier.
 - 
 -     jsx_parseNamespacedName() {
 -       let startPos = this.start, startLoc = this.startLoc;
 -       let name = this.jsx_parseIdentifier();
 -       if (!options.allowNamespaces || !this.eat(tt.colon)) return name;
 -       var node = this.startNodeAt(startPos, startLoc);
 -       node.namespace = name;
 -       node.name = this.jsx_parseIdentifier();
 -       return this.finishNode(node, 'JSXNamespacedName');
 -     }
 - 
 -     // Parses element name in any form - namespaced, member
 -     // or single identifier.
 - 
 -     jsx_parseElementName() {
 -       if (this.type === tok.jsxTagEnd) return '';
 -       let startPos = this.start, startLoc = this.startLoc;
 -       let node = this.jsx_parseNamespacedName();
 -       if (this.type === tt.dot && node.type === 'JSXNamespacedName' && !options.allowNamespacedObjects) {
 -         this.unexpected();
 -       }
 -       while (this.eat(tt.dot)) {
 -         let newNode = this.startNodeAt(startPos, startLoc);
 -         newNode.object = node;
 -         newNode.property = this.jsx_parseIdentifier();
 -         node = this.finishNode(newNode, 'JSXMemberExpression');
 -       }
 -       return node;
 -     }
 - 
 -     // Parses any type of JSX attribute value.
 - 
 -     jsx_parseAttributeValue() {
 -       switch (this.type) {
 -       case tt.braceL:
 -         let node = this.jsx_parseExpressionContainer();
 -         if (node.expression.type === 'JSXEmptyExpression')
 -           this.raise(node.start, 'JSX attributes must only be assigned a non-empty expression');
 -         return node;
 - 
 -       case tok.jsxTagStart:
 -       case tt.string:
 -         return this.parseExprAtom();
 - 
 -       default:
 -         this.raise(this.start, 'JSX value should be either an expression or a quoted JSX text');
 -       }
 -     }
 - 
 -     // JSXEmptyExpression is unique type since it doesn't actually parse anything,
 -     // and so it should start at the end of last read token (left brace) and finish
 -     // at the beginning of the next one (right brace).
 - 
 -     jsx_parseEmptyExpression() {
 -       let node = this.startNodeAt(this.lastTokEnd, this.lastTokEndLoc);
 -       return this.finishNodeAt(node, 'JSXEmptyExpression', this.start, this.startLoc);
 -     }
 - 
 -     // Parses JSX expression enclosed into curly brackets.
 - 
 -     jsx_parseExpressionContainer() {
 -       let node = this.startNode();
 -       this.next();
 -       node.expression = this.type === tt.braceR
 -         ? this.jsx_parseEmptyExpression()
 -         : this.parseExpression();
 -       this.expect(tt.braceR);
 -       return this.finishNode(node, 'JSXExpressionContainer');
 -     }
 - 
 -     // Parses following JSX attribute name-value pair.
 - 
 -     jsx_parseAttribute() {
 -       let node = this.startNode();
 -       if (this.eat(tt.braceL)) {
 -         this.expect(tt.ellipsis);
 -         node.argument = this.parseMaybeAssign();
 -         this.expect(tt.braceR);
 -         return this.finishNode(node, 'JSXSpreadAttribute');
 -       }
 -       node.name = this.jsx_parseNamespacedName();
 -       node.value = this.eat(tt.eq) ? this.jsx_parseAttributeValue() : null;
 -       return this.finishNode(node, 'JSXAttribute');
 -     }
 - 
 -     // Parses JSX opening tag starting after '<'.
 - 
 -     jsx_parseOpeningElementAt(startPos, startLoc) {
 -       let node = this.startNodeAt(startPos, startLoc);
 -       node.attributes = [];
 -       let nodeName = this.jsx_parseElementName();
 -       if (nodeName) node.name = nodeName;
 -       while (this.type !== tt.slash && this.type !== tok.jsxTagEnd)
 -         node.attributes.push(this.jsx_parseAttribute());
 -       node.selfClosing = this.eat(tt.slash);
 -       this.expect(tok.jsxTagEnd);
 -       return this.finishNode(node, nodeName ? 'JSXOpeningElement' : 'JSXOpeningFragment');
 -     }
 - 
 -     // Parses JSX closing tag starting after '</'.
 - 
 -     jsx_parseClosingElementAt(startPos, startLoc) {
 -       let node = this.startNodeAt(startPos, startLoc);
 -       let nodeName = this.jsx_parseElementName();
 -       if (nodeName) node.name = nodeName;
 -       this.expect(tok.jsxTagEnd);
 -       return this.finishNode(node, nodeName ? 'JSXClosingElement' : 'JSXClosingFragment');
 -     }
 - 
 -     // Parses entire JSX element, including it's opening tag
 -     // (starting after '<'), attributes, contents and closing tag.
 - 
 -     jsx_parseElementAt(startPos, startLoc) {
 -       let node = this.startNodeAt(startPos, startLoc);
 -       let children = [];
 -       let openingElement = this.jsx_parseOpeningElementAt(startPos, startLoc);
 -       let closingElement = null;
 - 
 -       if (!openingElement.selfClosing) {
 -         contents: for (;;) {
 -           switch (this.type) {
 -           case tok.jsxTagStart:
 -             startPos = this.start; startLoc = this.startLoc;
 -             this.next();
 -             if (this.eat(tt.slash)) {
 -               closingElement = this.jsx_parseClosingElementAt(startPos, startLoc);
 -               break contents;
 -             }
 -             children.push(this.jsx_parseElementAt(startPos, startLoc));
 -             break;
 - 
 -           case tok.jsxText:
 -             children.push(this.parseExprAtom());
 -             break;
 - 
 -           case tt.braceL:
 -             children.push(this.jsx_parseExpressionContainer());
 -             break;
 - 
 -           default:
 -             this.unexpected();
 -           }
 -         }
 -         if (getQualifiedJSXName(closingElement.name) !== getQualifiedJSXName(openingElement.name)) {
 -           this.raise(
 -             closingElement.start,
 -             'Expected corresponding JSX closing tag for <' + getQualifiedJSXName(openingElement.name) + '>');
 -         }
 -       }
 -       let fragmentOrElement = openingElement.name ? 'Element' : 'Fragment';
 - 
 -       node['opening' + fragmentOrElement] = openingElement;
 -       node['closing' + fragmentOrElement] = closingElement;
 -       node.children = children;
 -       if (this.type === tt.relational && this.value === "<") {
 -         this.raise(this.start, "Adjacent JSX elements must be wrapped in an enclosing tag");
 -       }
 -       return this.finishNode(node, 'JSX' + fragmentOrElement);
 -     }
 - 
 -     // Parse JSX text
 - 
 -     jsx_parseText() {
 -       let node = this.parseLiteral(this.value);
 -       node.type = "JSXText";
 -       return node;
 -     }
 - 
 -     // Parses entire JSX element from current position.
 - 
 -     jsx_parseElement() {
 -       let startPos = this.start, startLoc = this.startLoc;
 -       this.next();
 -       return this.jsx_parseElementAt(startPos, startLoc);
 -     }
 - 
 -     parseExprAtom(refShortHandDefaultPos) {
 -       if (this.type === tok.jsxText)
 -         return this.jsx_parseText();
 -       else if (this.type === tok.jsxTagStart)
 -         return this.jsx_parseElement();
 -       else
 -         return super.parseExprAtom(refShortHandDefaultPos);
 -     }
 - 
 -     readToken(code) {
 -       let context = this.curContext();
 - 
 -       if (context === tc_expr) return this.jsx_readToken();
 - 
 -       if (context === tc_oTag || context === tc_cTag) {
 -         if (isIdentifierStart(code)) return this.jsx_readWord();
 - 
 -         if (code == 62) {
 -           ++this.pos;
 -           return this.finishToken(tok.jsxTagEnd);
 -         }
 - 
 -         if ((code === 34 || code === 39) && context == tc_oTag)
 -           return this.jsx_readString(code);
 -       }
 - 
 -       if (code === 60 && this.exprAllowed && this.input.charCodeAt(this.pos + 1) !== 33) {
 -         ++this.pos;
 -         return this.finishToken(tok.jsxTagStart);
 -       }
 -       return super.readToken(code);
 -     }
 - 
 -     updateContext(prevType) {
 -       if (this.type == tt.braceL) {
 -         var curContext = this.curContext();
 -         if (curContext == tc_oTag) this.context.push(tokContexts.b_expr);
 -         else if (curContext == tc_expr) this.context.push(tokContexts.b_tmpl);
 -         else super.updateContext(prevType);
 -         this.exprAllowed = true;
 -       } else if (this.type === tt.slash && prevType === tok.jsxTagStart) {
 -         this.context.length -= 2; // do not consider JSX expr -> JSX open tag -> ... anymore
 -         this.context.push(tc_cTag); // reconsider as closing tag context
 -         this.exprAllowed = false;
 -       } else {
 -         return super.updateContext(prevType);
 -       }
 -     }
 -   };
 - }
 
 
  |